void* alloc(u32int size, heap* h) { u32int new_size = size + sizeof (header) + sizeof (footer); s32int iterator = find_smallest_hole(new_size, h); if (iterator == -1) // If we didn't find a suitable hole { print_msg("No enough memory space\n"); return NULL; } header *orig_hole_header = (header *) lookup_ordered_array(iterator, &h->index); u32int orig_hole_pos = (u32int) orig_hole_header; u32int orig_hole_size = orig_hole_header->size; // Here we work out if we should split the hole we found into two parts. // Is the original hole size - requested hole size less than the overhead for adding a new hole? if (orig_hole_size - new_size < sizeof (header) + sizeof (footer)) { // Then just increase the requested size to the size of the hole we found. size += orig_hole_size - new_size; new_size = orig_hole_size; } remove_ordered_array(iterator, &h->index); // we make sure all the header and footer attributes are correct, along with magic numbers header *block_header = (header *) orig_hole_pos; block_header->magic = HEAP_MAGIC; block_header->is_hole = 0; block_header->size = new_size; footer *block_footer = (footer *) (orig_hole_pos + sizeof (header) + size); block_footer->magic = HEAP_MAGIC; block_footer->head = block_header; // We may need to write a new hole after the allocated block. // We do this only if the new hole would have positive size... if (orig_hole_size - new_size > 0) { header *hole_header = (header *) (orig_hole_pos + sizeof (header) + size + sizeof (footer)); hole_header->magic = HEAP_MAGIC; hole_header->is_hole = 1; hole_header->size = orig_hole_size - new_size; footer *hole_footer = (footer *) ((u32int) hole_header + orig_hole_size - new_size - sizeof (footer)); if ((u32int) hole_footer < h->end_address) { hole_footer->magic = HEAP_MAGIC; hole_footer->head = hole_header; } // Put the new hole in the index; insert_ordered_array((u32int) hole_header, &h->index); } return (void *) ((u32int) block_header + sizeof (header)); }
void *alloc(u32 size, u8 page_align, heap_t *heap) { /* * Make sure we take the size of the header/footer * into account. */ u32 new_size = size + sizeof(header_t) + sizeof(footer_t); /* * Find the smallest hole that will fit */ s32 i = find_smallest_hole(new_size, page_align, heap); if (i == -1) { /* * If we didnt find a suitable hole */ u32 old_length = heap->end_address - heap->start_address; u32 old_end_address = heap->end_address; expand(old_length + new_size, heap); u32 new_length = heap->end_address - heap->start_address; /* * Find the endmost header. Not endmost in size, but in * location. */ u32 i = 0, idx = -1, value = 0x0; while (i < heap->index.size) { u32 tmp = (u32)lookup_ordered_array(i, &heap->index); if (tmp > value) { value = tmp; idx = i; } i++; } /* * If we didnt find any headers, we need to add one */ if (idx == -1) { header_t *header = (header_t *)old_end_address; header->magic = HEAP_MAGIC; header->size = new_length - old_length; header->is_hole = 1; footer_t *footer = (footer_t *)(old_end_address + header->size - sizeof(footer_t)); footer->magic = HEAP_MAGIC; footer->header = header; insert_ordered_array((void *)header, &heap->index); } else { /* * The last header needs adjusting */ header_t *header = lookup_ordered_array(idx, &heap->index); header->size += new_length - old_length; /* Rewrite the footer */ footer_t *footer = (footer_t *)((u32)header + header->size - sizeof(footer_t)); footer->header = header; footer->magic = HEAP_MAGIC; } /* * We now have enough space. Recurse call the function * again. */ return alloc(size, page_align, heap); } header_t *orig_hole_header = (header_t *)lookup_ordered_array(i, &heap->index); u32 orig_hole_pos = (u32)orig_hole_header; u32 orig_hole_size = orig_hole_header->size; if (orig_hole_size - new_size < sizeof(header_t) + sizeof(footer_t)) { size += orig_hole_size - new_size; new_size = orig_hole_size; } // If we need to page-align the data, do it now and make a new hole in front of our block. if (page_align && orig_hole_pos&0xFFFFF000) { u32 new_location = orig_hole_pos + 0x1000 /* page size */ - (orig_hole_pos&0xFFF) - sizeof(header_t); header_t *hole_header = (header_t *)orig_hole_pos; hole_header->size = 0x1000 /* page size */ - (orig_hole_pos&0xFFF) - sizeof(header_t); hole_header->magic = HEAP_MAGIC; hole_header->is_hole = 1; footer_t *hole_footer = (footer_t *) ( (u32)new_location - sizeof(footer_t) ); hole_footer->magic = HEAP_MAGIC; hole_footer->header = hole_header; orig_hole_pos = new_location; orig_hole_size = orig_hole_size - hole_header->size; } else { // Else we don't need this hole any more, delete it from the index. remove_ordered_array(i, &heap->index); } header_t *block_header = (header_t *)orig_hole_pos; block_header->magic = HEAP_MAGIC; block_header->is_hole = 0; block_header->size = new_size; footer_t *block_footer = (footer_t *)(orig_hole_pos + sizeof(header_t) + size); block_footer->magic = HEAP_MAGIC; block_footer->header = block_header; /* * We may need to write a new hole after the allocated block. * We do this only if the new hole would have a positive size */ if (orig_hole_size - new_size > 0) { header_t *hole_header = (header_t *)(orig_hole_pos + sizeof(header_t) + size + sizeof(footer_t)); hole_header->magic = HEAP_MAGIC; hole_header->is_hole = 1; hole_header->size = orig_hole_size - new_size; footer_t *hole_footer = (footer_t *)((u32)hole_header + orig_hole_size - new_size - sizeof(footer_t)); hole_footer->magic = HEAP_MAGIC; hole_footer->header = hole_header; if ((u32)hole_footer < heap->end_address) { hole_footer->magic = HEAP_MAGIC; hole_footer->header = hole_header; } /* * Put the new hole into the index. */ insert_ordered_array((void *)hole_header, &heap->index); } return (void *)((u32)block_header + sizeof(header_t)); }
void *alloc(uint32_t size, uint8_t page_align, heap_t *heap) { // Make sure we take the size of header/footer into account. uint32_t new_size = size + sizeof(header_t) + sizeof(footer_t); // Find the smallest hole that will fit. HeapArray_t::index_t iterator = find_smallest_hole(new_size, page_align, heap); if (iterator == -1) // If we didn't find a suitable hole { // Save some previous data. uint32_t old_length = heap->end_address - heap->start_address; uint32_t old_end_address = heap->end_address; // We need to allocate some more space. expand(old_length+new_size, heap); uint32_t new_length = heap->end_address-heap->start_address; // Find the endmost header. (Not endmost in size, but in location). iterator = 0; // Vars to hold the index of, and value of, the endmost header found so far. int32_t idx = -1; int32_t value = 0x0; while (iterator < heap->index->size()) { int32_t tmp = (int32_t)&(heap->index->lookup(iterator)); if (tmp > value) { value = tmp; idx = iterator; } iterator++; } // If we didn't find ANY headers, we need to add one. if (idx == -1) { header_t *header = (header_t *)old_end_address; header->magic = HEAP_MAGIC; header->size = new_length - old_length; header->is_hole = 1; footer_t *footer = (footer_t *) (old_end_address + header->size - sizeof(footer_t)); footer->magic = HEAP_MAGIC; footer->header = header; heap->index->insert(header); } else { // The last header needs adjusting. header_t *header = (header_t*)heap->index->lookup(idx); header->size += new_length - old_length; // Rewrite the footer. footer_t *footer = (footer_t *) ( (uint32_t)header + header->size - sizeof(footer_t) ); footer->header = header; footer->magic = HEAP_MAGIC; } // We now have enough space. Recurse, and call the function again. return alloc(size, page_align, heap); } header_t *orig_hole_header = (header_t *)heap->index->lookup(iterator); uint32_t orig_hole_pos = (uint32_t)orig_hole_header; uint32_t orig_hole_size = orig_hole_header->size; // Here we work out if we should split the hole we found into two parts. // Is the original hole size - requested hole size less than the overhead for adding a new hole? if (orig_hole_size-new_size < sizeof(header_t)+sizeof(footer_t)) { // Then just increase the requested size to the size of the hole we found. size += orig_hole_size-new_size; new_size = orig_hole_size; } // If we need to page-align the data, do it now and make a new hole in front of our block. if (page_align && orig_hole_pos&0xFFFFF000) { uint32_t new_location = orig_hole_pos + 0x1000 /* page size */ - (orig_hole_pos&0xFFF) - sizeof(header_t); header_t *hole_header = (header_t *)orig_hole_pos; hole_header->size = 0x1000 /* page size */ - (orig_hole_pos&0xFFF) - sizeof(header_t); hole_header->magic = HEAP_MAGIC; hole_header->is_hole = 1; footer_t *hole_footer = (footer_t *) ( (uint32_t)new_location - sizeof(footer_t) ); hole_footer->magic = HEAP_MAGIC; hole_footer->header = hole_header; orig_hole_pos = new_location; orig_hole_size = orig_hole_size - hole_header->size; } else { // Else we don't need this hole any more, delete it from the index. heap->index->remove(iterator); } // Overwrite the original header... header_t *block_header = (header_t *)orig_hole_pos; block_header->magic = HEAP_MAGIC; block_header->is_hole = 0; block_header->size = new_size; // ...And the footer footer_t *block_footer = (footer_t *) (orig_hole_pos + sizeof(header_t) + size); block_footer->magic = HEAP_MAGIC; block_footer->header = block_header; // We may need to write a new hole after the allocated block. // We do this only if the new hole would have positive size... if (orig_hole_size - new_size > 0) { header_t *hole_header = (header_t *) (orig_hole_pos + sizeof(header_t) + size + sizeof(footer_t)); hole_header->magic = HEAP_MAGIC; hole_header->is_hole = 1; hole_header->size = orig_hole_size - new_size; footer_t *hole_footer = (footer_t *) ( (uint32_t)hole_header + orig_hole_size - new_size - sizeof(footer_t) ); if ((uint32_t)hole_footer < heap->end_address) { hole_footer->magic = HEAP_MAGIC; hole_footer->header = hole_header; } // Put the new hole in the index; heap->index->insert(hole_header); } // ...And we're done! return (void *) ( (uint32_t)block_header+sizeof(header_t) ); }
static void *heap_malloc(UINT size, UCHAR page_align, heap *aheap) { UINT newsize = size + sizeof(mm_header) + sizeof(mm_footer); UINT hole_pos = find_smallest_hole(newsize, page_align, aheap), oldsize, oldpos, newpos, oldend; mm_header *header, *newheader; mm_footer *newfooter; if ((!size) || (!aheap)) return 0; if (hole_pos == MM_NO_HOLE) { oldsize = aheap->end - aheap->start; oldend = aheap->end; expand_heap(oldsize + newsize, aheap); newsize = aheap->end - aheap->start; UINT idx = MM_NO_HOLE; UINT value = 0; for (hole_pos = 0; hole_pos < aheap->entrycount; hole_pos++) { UINT tmp = (UINT) aheap->entries[hole_pos]; if (tmp > value) { value = tmp; idx = hole_pos; } } if (idx == MM_NO_HOLE) { header = (mm_header *)oldend; header->size = newsize - oldsize; header->flag = MM_FLAG_HOLE; newfooter = (mm_footer *) (oldend + header->size - sizeof(mm_footer)); header->magic = newfooter->magic = MM_MAGIC; newfooter->header = header; heap_add_entry(header, aheap); } else { header = aheap->entries[idx]; header->size += newsize - oldsize; newfooter = (mm_footer *) ((UINT)header + header->size - sizeof(mm_footer)); newfooter->header = header; newfooter->magic = MM_MAGIC; } return heap_malloc(size, page_align, aheap); } header = aheap->entries[hole_pos]; if (header->size - sizeof(mm_header) - sizeof(mm_footer) < newsize) { size += header->size - newsize; newsize = header->size; } oldpos = (UINT)header; oldsize = header->size; if (page_align && (oldpos & 0xFFFFF000)) { newpos = oldpos + FRAME_SIZE - (oldpos & 0xFFF) - sizeof(mm_header); newheader = (mm_header *) oldpos; newfooter = (mm_footer *) ((UINT)newpos - sizeof(mm_footer)); newheader->size = newpos - oldpos; newheader->flag = MM_FLAG_HOLE; newheader->magic = newfooter->magic = MM_MAGIC; newfooter->header = newheader; oldpos = newpos; oldsize = oldsize - newheader->size; } else { heap_del_entry(hole_pos, aheap); } header = (mm_header *) oldpos; newfooter = (mm_footer *) (oldpos + sizeof(mm_header) + size); header->flag = MM_FLAG_BLOCK; header->size = newsize; header->magic = newfooter->magic = MM_MAGIC; newfooter->header = header; if (oldsize - newsize > 0) { newheader = (mm_header *) (oldpos + newsize); newheader->magic = MM_MAGIC; newheader->flag = MM_FLAG_HOLE; newheader->size = oldsize - newsize; newfooter = (mm_footer *) ((UINT)newheader + newheader->size - sizeof(mm_footer)); if ((UINT)newfooter < aheap->end) { newfooter->magic = MM_MAGIC; newfooter->header = newheader; } heap_add_entry(newheader, aheap); } return (void *) ((UINT)header + sizeof(mm_header)); }
void* alloc(u32int size, u8int page_align, heap_t *heap) { u32int new_size = size + sizeof(header_t) + sizeof(footer_t); s32int iterator = find_smallest_hole(new_size, page_align, heap); // no suitable hole found if (iterator == -1) { u32int old_length = heap->end_address - heap->start_address; u32int old_end_address = heap->end_address; expand(old_length + new_size, heap); u32int new_length = heap->end_address - heap->start_address; iterator = 0; u32int idx = -1; u32int value = 0x0; while ((u32int)iterator < heap->index.size) { u32int tmp = (u32int)lookup_ordered_array(iterator, &heap->index); if (tmp > value) { value = tmp; idx = iterator; } iterator++; } if ((s32int)idx == -1) { header_t *header = (header_t *)old_end_address; header->magic = HEAP_MAGIC; header->size = new_length - old_length; header->is_hole = 1; footer_t *footer = (footer_t *)(old_end_address + header->size - sizeof(footer_t)); footer->magic = HEAP_MAGIC; footer->header = header; insert_ordered_array((void *)header, &heap->index); } else { header_t *header = lookup_ordered_array(idx, &heap->index); header->size += new_length - old_length; footer_t *footer = (footer_t *)((u32int)header + header->size - sizeof(footer_t)); footer->header = header; footer->magic = HEAP_MAGIC; } return alloc(size, page_align, heap); } header_t *orig_hole_header = (header_t *)lookup_ordered_array(iterator, &heap->index); u32int orig_hole_pos = (u32int)orig_hole_header; u32int orig_hole_size = orig_hole_header->size; if (orig_hole_size - new_size < sizeof(header_t) + sizeof(footer_t)) { size += orig_hole_size - new_size; new_size = orig_hole_size; } if (page_align && orig_hole_pos & ~0xfffff000) { u32int new_location = orig_hole_pos + 0x1000 - (orig_hole_pos & 0xfff) - sizeof(header_t); header_t *hole_header = (header_t *)orig_hole_pos; hole_header->size = 0x1000 - (orig_hole_pos & 0xfff) - sizeof(header_t); hole_header->magic = HEAP_MAGIC; hole_header->is_hole = 1; footer_t *hole_footer = (footer_t *)((u32int)new_location - sizeof(footer_t)); hole_footer->magic = HEAP_MAGIC; hole_footer->header = hole_header; orig_hole_pos = new_location; orig_hole_size -= hole_header->size; } else { remove_ordered_array(iterator, &heap->index); } header_t *block_header = (header_t *)orig_hole_pos; block_header->magic = HEAP_MAGIC; block_header->is_hole = 0; block_header->size = new_size; footer_t *block_footer = (footer_t *)(orig_hole_pos + sizeof(header_t) + size); block_footer->magic = HEAP_MAGIC; block_footer->header = block_header; if (orig_hole_size - new_size > 0) { header_t *hole_header = (header_t *)(orig_hole_pos + sizeof(header_t) + sizeof(footer_t) + size); hole_header->magic = HEAP_MAGIC; hole_header->is_hole = 1; hole_header->size = orig_hole_size - new_size; footer_t *hole_footer = (footer_t *)((u32int)hole_header + orig_hole_size - new_size - sizeof(footer_t)); if ((u32int)hole_footer < heap->end_address) { hole_footer->magic = HEAP_MAGIC; hole_footer->header = hole_header; } insert_ordered_array((void *)hole_header, &heap->index); } return (void *)((u32int)block_header + sizeof(header_t)); }
void* vmalloc(addr size, unsigned char page_align, struct vmem_heap* heap) { /* Make sure we take the size of the header / footer into account */ addr new_size = size + sizeof(struct vmem_header) + sizeof(struct vmem_footer); /* Find the smallest hole that will fit */ signed int iterator = find_smallest_hole(new_size, page_align, heap); if (iterator == -1) /* If we didn't find a suitable hole */ { /* Save some previous data */ addr old_length = heap->end_address - heap->start_address; addr old_end_address = heap->end_address; /* We need to allocate some more space */ expand(old_length + new_size, heap); addr new_length = heap->end_address - heap->start_address; /* Find the endmost header (not endmost in size, but in location) */ iterator = 0; /* Vars to hold the index of, and value of, the endmost header found so far */ addr idx = -1; addr value = 0x0; while (iterator < heap->index.size) { addr tmp = (addr)lookup_ordered_array(iterator, &heap->index); if (tmp > value) { value = tmp; idx = iterator; } iterator++; } /* If we didn't find any headers, we need to add one */ if (idx == -1) { struct vmem_header* header = (struct vmem_header*)old_end_address; header->magic = VMEM_MAGIC; header->size = new_length - old_length; header->is_hole = 1; struct vmem_footer* footer = (struct vmem_footer*)(old_end_address + header->size - sizeof(struct vmem_footer)); footer->magic = VMEM_MAGIC; footer->header = header; insert_ordered_array((void*)header, &heap->index); } else { /* The last header needs adjusting */ struct vmem_header* header = lookup_ordered_array(idx, &heap->index); header->size += new_length - old_length; /* Rewrite the footer */ struct vmem_footer* footer = (struct vmem_footer*)((addr)header + header->size - sizeof(struct vmem_footer)); footer->header = header; footer->magic = VMEM_MAGIC; } } struct vmem_header* orig_hole_header = (struct vmem_header*)lookup_ordered_array(iterator, &heap->index); addr orig_hole_pos = (addr)orig_hole_header; addr orig_hole_size = orig_hole_header->size; /* Here we work out if we should split the hole we found into two parts. * Is the original hole size - requested hole size less than the overhead for adding a new hole? */ if (orig_hole_size - new_size < sizeof(struct vmem_header) + sizeof(struct vmem_footer)) { /* Then just increase the requested size to the size of the hole we found */ size += orig_hole_size - new_size; new_size = orig_hole_size; } /* If we need to page-align the data, do it now and make a new hole in front of our block */ if (page_align && (orig_hole_pos & 0xFFFFF000)) { addr new_location = orig_hole_pos + 0x1000 /* page size */ - (orig_hole_pos & 0xFFF) - sizeof(struct vmem_header); struct vmem_header* hole_header = (struct vmem_header*)orig_hole_pos; hole_header->size = 0x1000 /* page size */ - (orig_hole_pos & 0xFFF) - sizeof(struct vmem_header); hole_header->magic = VMEM_MAGIC; hole_header->is_hole = 1; struct vmem_footer* hole_footer = (struct vmem_footer*)((addr)new_location - sizeof(struct vmem_footer)); hole_footer->magic = VMEM_MAGIC; hole_footer->header = hole_header; orig_hole_pos = new_location; orig_hole_size = orig_hole_size - hole_header->size; } else { /* Else we don't need this hole any more, delete it from the index */ remove_ordered_array(iterator, &heap->index); } /* Overwrite the original header... */ struct vmem_header* block_header = (struct vmem_header*)orig_hole_pos; block_header->magic = VMEM_MAGIC; block_header->is_hole = 0; block_header->size = new_size; /* ... and the footer */ struct vmem_footer* block_footer = (struct vmem_footer*)(orig_hole_pos + sizeof(struct vmem_header) + size); block_footer->magic = VMEM_MAGIC; block_footer->header = block_header; /* We may need to write a new hole after the allocated block. * We do this only if the new hole would have positive size */ if (orig_hole_size - new_size > 0) { struct vmem_header* hole_header = (struct vmem_header*)(orig_hole_pos + sizeof(struct vmem_header) + size + sizeof(struct vmem_footer)); hole_header->magic = VMEM_MAGIC; hole_header->is_hole = 1; hole_header->size = orig_hole_size - new_size; struct vmem_footer* hole_footer = (struct vmem_footer*)((addr)hole_header + orig_hole_size - new_size - sizeof(struct vmem_footer)); if ((addr)hole_footer < heap->end_address) { hole_footer->magic = VMEM_MAGIC; hole_footer->header = hole_header; } /* Put the new hole in the array */ insert_ordered_array((void*)hole_header, &heap->index); } /* ... and we're done! */ return (void*)((addr)block_header + sizeof(struct vmem_header)); }