view src/os/heap.c @ 160:3d891b634acb default tip

Fix to make make work
author Jonathan Pevarnek <pevarnj@gmail.com>
date Fri, 25 Nov 2011 23:27:09 -0500
parents 9ad854e6d994
children
line wrap: on
line source

#include <os/heap.h>
#include <memHead.h>
#include <os/storageKeys.h>
#include <os/memLayout.h>

static Header base;
static Header *allocp = NULL;

void heap_init(size_t memSize)
{
	allocp = &base;
	allocp->size = 0;
	allocp->next = (void*)HEAP_START;
	allocp->next->next = &base;
	allocp->next->size = (memSize - HEAP_START)/PAGESIZE;
}

//sets ammt to the amount of space that was allocated
void* allocHeap(size_t size, size_t *ammt)
{ 
	size_t nUnits = ((size + sizeof(Header)) + PAGESIZE - 1)/PAGESIZE;
	Header *prev = allocp;
	Header *cur, *temp;
	for(cur = prev->next;; prev = cur, cur = cur->next) {
		if(cur->size >= nUnits) {
			if(cur->size == nUnits) {
				prev->next = cur->next;
			} else {
				temp = cur + nUnits*PAGESIZE/sizeof(Header);
				temp->size = cur->size - nUnits;
				temp->next = cur->next;
				prev->next = temp;
				cur->size = nUnits;
			}
			*ammt = cur->size*PAGESIZE - sizeof(Header);
			allocp = prev;
			intptr_t ptr;
			for(ptr = (intptr_t)cur; (ptr - (intptr_t)cur) < nUnits*PAGESIZE; ptr += BLOCKSIZE) {
				setStorageKey(ptr, PROGSK, 1); //TODO only do this if being called by the program (how?)
			}
			return (void*)(cur + 1);
		} else if(cur == allocp) { //We went back to the start...
			return NULL;
		}
	}
}

void freeHeap(void *ptr)
{
	Header *toFree = (Header *)ptr - 1;
	intptr_t skLoc;
	for(skLoc = (intptr_t)toFree; (skLoc - (intptr_t)toFree) < toFree->size*PAGESIZE; skLoc += BLOCKSIZE) {
		setStorageKey(skLoc, 0, 1);
	}
	Header *scan;
	for(scan = allocp; !(toFree > scan && toFree < scan->next); scan = scan->next)
		if(scan->next <= scan && (toFree > scan || toFree < scan->next)) break;
	toFree->next = scan->next;
	scan->next = toFree;
	if(scan + scan->size == toFree) {
		scan->size += toFree->size;
		scan->next = toFree->next;
		toFree = scan;
	}
	if(toFree + (toFree->size*PAGESIZE)/sizeof(Header) == toFree->next) {
		toFree->size += toFree->next->size;
		toFree->next = toFree->next->next;
	}
}