diff --git a/src/galloc.๐Ÿ—ฟ b/src/galloc.๐Ÿ—ฟ index a5c26f5..4fd5a8f 100644 --- a/src/galloc.๐Ÿ—ฟ +++ b/src/galloc.๐Ÿ—ฟ @@ -1,24 +1,49 @@ -define header_size = 3; -define protection_size = 4; -define heap_size = 65536 +define PADDING_SIZE = 4; +define HEADER_SIZE = PADDING_SIZE * 2 + 5; -global heap[header_size] = 0; +define HEAP_SIZE = 65536; +global heap[HEADER_SIZE] = 0; ๐Ÿ—ฟHEADER REPRESENTATION -๐Ÿ—ฟ+-------------------------+-----------------------------+-----------------------------+---------+---------+---------+ -๐Ÿ—ฟ| index of the next block | index of the previous block | used (if the block is used) | padding | data | padding | -๐Ÿ—ฟ| 1 case | 1 case | 1 case | 4 cases | n cases | 4 cases | -๐Ÿ—ฟ+-------------------------+-----------------------------+-----------------------------+---------+---------+---------+ +๐Ÿ—ฟ+-------------+--------+--------+---------------------------+-------------------------------+---------+---------+---------+ +๐Ÿ—ฟ| initialised | used | size | pointer to the next block | pointer to the previous block | padding | data | padding | +๐Ÿ—ฟ| 1 case | 1 case | 1 case | 1 case | 1 case | 4 cases | n cases | 4 cases | +๐Ÿ—ฟ+-------------+--------+--------+---------------------------+-------------------------------+---------+---------+---------+ -๐Ÿ—ฟ padding is use to check invalid write +๐Ÿ—ฟ INITIALISED +๐Ÿ—ฟ a boolean to state if the block is initialised +๐Ÿ—ฟ USED +๐Ÿ—ฟ a boolean to state if the block is used -setup_header(pos, size, preview_pos) +๐Ÿ—ฟ SIZE +๐Ÿ—ฟ The size of the data + +๐Ÿ—ฟ POINTER +๐Ÿ—ฟ The address of block + +๐Ÿ—ฟ PADDING +๐Ÿ—ฟ Is used to check invalid write +๐Ÿ—ฟ If a case doesn't equal to 0 it is an invalid write + +define LOCATION_INITIALISED = 0; +define LOCATION_USED = 1; +define LOCATION_SIZE = 2; +define LOCATION_NEXT = 3; +define LOCATION_PREV = 4; +define LOCATION_DATA = 9; + +setup_header(ptr, used, size, next_block, prev_block) { local i; - - [ptr] = pos; - [ptr + 1] = 0; + + if (size + PADDING_SIZE * 2 + HEADER_SIZE) + return (1); + [ptr] = 1; ๐Ÿ—ฟ initialised + [ptr + 1] = used; ๐Ÿ—ฟ used + [ptr + 2] = size; ๐Ÿ—ฟ size + [ptr + 3] = next_block; ๐Ÿ—ฟ next block + [ptr + 4] = prev_block; ๐Ÿ—ฟ previous block i = header_size; loop { @@ -28,27 +53,53 @@ setup_header(pos, size, preview_pos) [ptr + i + size] = 0; i++; } + return (0); } find_next_space(size) { local current; - local next; - current = 0; + current = heap; loop { - if (current > header_size) + if ([current + LOCATION_USED] == 0 + & [current + LOCATION_SIZE] >= size) + return (current); + current = [current + LOCATION_NEXT]; + if ([current] == 0) return (0); - next_block = heap + current; - if ([next_block] == 0) ๐Ÿ—ฟcheck if the block is the last - | ([heap + current + 1] == 0) ๐Ÿ—ฟcheck if the block is not used - return (heap + current); - current = [heap + next_block]; } } -salloc (size) +divise_block(ptr, size) { - local p; + local old_next; + local next; + + if (size + HEADER_SIZE >= [ptr + LOCATION_SIZE]) + return (0); + old_next = [ptr + LOCATION_NEXT]; + next = [ptr + size + HEADER_SIZE]; + setup_header(next, 0, [ptr + LOCATION_SIZE] - HEADER_SIZE * 2, [ptr + LOCATION_SIZE] + HEADER_SIZE, old_next, ptr); + setup_header(ptr, 1, size, next, [ptr + LOCATION_PREV]); + return (0); +} + +salloc(size) +{ + local ptr; + + if ([heap] == 0) ๐Ÿ—ฟ if the heap is not initialised + setup_header(HEAP_SIZE - 2 * PADDING_SIZE - HEADER_SIZE, 0, 0, 0); ๐Ÿ—ฟ initialised all the heap + ptr = find_next_space(size); + if (ptr == 0) + return (0); + if ([ptr + LOCATION_SIZE] == size) + { + [ptr + LOCATION_USED] = 1; + return (ptr + LOCATION_DATA); + } + divise_block(ptr, size); + return (ptr); } diff --git a/tests/galloc.๐Ÿ—ฟ b/tests/galloc.๐Ÿ—ฟ new file mode 100644 index 0000000..fb9d6ee --- /dev/null +++ b/tests/galloc.๐Ÿ—ฟ @@ -0,0 +1,5 @@ +main() +{ + name = "galloc"; + test(galloc(1), heap + LOCATION_DATA, ""); +}