예제 #1
0
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));
}
예제 #2
0
파일: kheap.c 프로젝트: Magnus932/kernel
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));
}
예제 #3
0
파일: kheap.cpp 프로젝트: zerotri/Amarant
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) );
}
예제 #4
0
파일: mm.c 프로젝트: domoritz/nupkux
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));
}
예제 #5
0
파일: kheap.c 프로젝트: blessed/blessOS
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));
}
예제 #6
0
파일: vmem.c 프로젝트: TheBugEater/Kernel
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));
}