diff options
Diffstat (limited to 'src/kernel/mem.c')
-rw-r--r-- | src/kernel/mem.c | 115 |
1 files changed, 53 insertions, 62 deletions
diff --git a/src/kernel/mem.c b/src/kernel/mem.c index 99586d9..d9322a9 100644 --- a/src/kernel/mem.c +++ b/src/kernel/mem.c @@ -23,75 +23,66 @@ uint32_t last_byte = 0; uint32_t last_mask = 0x00000001; void *allocate_block(uint32_t size, uint16_t proc_n) { - struct mmap_entry *i = mmap_start; - while (i->whose || (i->length < size)) - if (i->next) - i = i->next; - else - return (void *)0; - if (i->length == size) { - i->whose = proc_n; - return (void *)i->base; - } - uint32_t remaining = i->length - size; - i->whose = proc_n; - i->length = size; - - uint32_t byte = last_byte; - uint32_t mask = last_mask; - do { - if (!(mask <<= 1)) { - mask = 0x00000001; - if (++byte == MMAP_SIZE) - byte = 0; + for (struct mmap_entry *find = mmap_start; find; find = find->after) + if (!find->whose) { + if (find->length == size) { + find->whose = proc_n; + return (void *)find->base; + } + else if (find->length > size) { + uint32_t byte = last_byte; + uint32_t mask = last_mask; + while (mmap_bitmap[byte] & mask) { + if ((byte == last_byte) && (mask == last_mask)) { + while (find = find->after) + if (find->length == size) { + find->whose = proc_n; + return (void *)find->base; + } + return (void *)0; + } + if (!(mask <<= 1)) { + mask = 0x00000001; + if (++byte == MMAP_SIZE) + byte = 0; + } + } + mmap_bitmap[last_byte = byte] |= last_mask = mask; + struct mmap_entry *new = mmap_bss + (byte << 5); + while (mask >>= 1) + ++new; + ((((new->after = find->after)->before = new)->before = find)->after = new)->base = find->base + size; + new->length = find->length - size; + find->length = size; + find->whose = proc_n; + new->whose = FREE; + return (void *)find->base; + } } - if ((byte == last_byte) && (mask == last_mask)) - return 0; - } while (mmap_bitmap[byte] & mask); - last_byte = byte; - last_mask = mask; - mmap_bitmap[byte] |= mask; - uint8_t bit = 0; - while (!(mask & 0x00000001)) { - ++bit; - mask >>= 1; - } - - struct mmap_entry *new = mmap_bss + (byte << 5) + bit; - new->base = i->base + size; - new->length = remaining; - new->whose = FREE; - new->next = i->next; - i->next = new; - return (void *)i->base; + return (void *)0; } void deallocate_block(void *start) { struct mmap_entry *find = mmap_start; while (find->base != (uint32_t)start) - if (find->next) - find = find->next; + if (find->after) + find = find->after; else return; find->whose = FREE; - - for (struct mmap_entry *find_after = mmap_start; find_after; find_after = find_after->next) - if (find_after->base == find->base + find->length) { - if (!find_after->whose) { - find->length += find_after->length; - find->next = find_after->next; - unmark_entry(find_after); - } - break; - } - - for (struct mmap_entry *find_before = mmap_start; find_before; find_before = find_before->next) - if (find->base == find_before->base + find_before->length) { - if (!find_before->whose) { - find_before->length += find->length; - find_before->next = find->next; - unmark_entry(find); - } - break; - } + while (find->before && !find->before->whose) { + find->before->length += find->length; + if (find->before->after = find->after) + find->after->before = find->before; + unmark_entry(find); + find = find->before; + } + if (!find->before) + mmap_start = find; + while (find->after && !find->after->whose) { + find->length += find->after->length; + unmark_entry(find->after); + if (find->after = find->after->after) + find->after->before = find; + } }
\ No newline at end of file |