Пример #1
0
static int myThread(A_UNUSED void *arg) {
	size_t i;
	usemdown(&usem);
	printf("Thread %d starts\n",gettid());
	fflush(stdout);
	usemup(&usem);
	for(i = 0; i < 10; i++)
		sleep(100);
	usemdown(&usem);
	printf("Thread %d is done\n",gettid());
	fflush(stdout);
	usemup(&usem);
	return 0;
}
Пример #2
0
void *realloc(void *addr,size_t size) {
	ulong *begin;
	sMemArea *area,*a,*prev;
	if(addr == NULL)
		return malloc(size);

	begin = (ulong*)addr - 3;
	area = (sMemArea*)begin[0];
	/* check guards */
	vassert(begin[0] != FREE_MAGIC,"Duplicate free?");
	assert(begin[2] == GUARD_MAGIC);
	assert(begin[begin[1] / sizeof(ulong) + 3] == GUARD_MAGIC);

	usemdown(&heapSem);

	/* align and we need 3 ulongs for the guards */
	size = ROUND_UP(size,sizeof(ulong)) + sizeof(ulong) * 4;

	/* ignore shrinks */
	if(size < area->size) {
		usemup(&heapSem);
		return addr;
	}

	a = usableList;
	prev = NULL;
	while(a != NULL) {
		/* found the area behind? */
		if((uintptr_t)a->address == (uintptr_t)area->address + area->size) {
			/* if the size of both is big enough we can use them */
			if(area->size + a->size >= size) {
				/* space left? */
				if(size < area->size + a->size) {
					/* so move the area forward */
					a->address = (void*)((uintptr_t)area->address + size);
					a->size = (area->size + a->size) - size;
				}
				/* otherwise we don't need a anymore */
				else {
					/* remove a from usable-list */
					if(prev == NULL)
						usableList = a->next;
					else
						prev->next = a->next;
					/* free a */
					a->next = freeList;
					freeList = a;
				}

				area->size = size;
				/* reset guards */
				begin[0] = (ulong)area;
				begin[1] = size - sizeof(ulong) * 4;
				begin[2] = GUARD_MAGIC;
				begin[size / sizeof(ulong) - 1] = GUARD_MAGIC;
				usemup(&heapSem);
				return begin + 3;
			}

			/* makes no sense to continue since we've found the area behind */
			break;
		}
		prev = a;
		a = a->next;
	}

	usemup(&heapSem);

	/* the areas are not big enough, so allocate a new one */
	a = malloc(size);
	if(a == NULL)
		return NULL;

	/* copy the old data and free it */
	memcpy(a,addr,area->size - sizeof(ulong) * 4);
	free(addr);
	return a;
}
Пример #3
0
void *malloc(size_t size) {
	ulong *begin;
	sMemArea *area,*prev,*narea;

	if(size == 0)
		return NULL;

	usemdown(&heapSem);

	/* align and we need 3 ulongs for the guards */
	size = ROUND_UP(size,sizeof(ulong)) + sizeof(ulong) * 4;

	/* find a suitable area */
	prev = NULL;
	area = usableList;
	while(area != NULL) {
		if(area->size >= size)
			break;
		prev = area;
		area = area->next;
	}

	/* no area found? */
	if(area == NULL) {
		if(!loadNewSpace(size)) {
			usemup(&heapSem);
			return NULL;
		}
		/* we can assume that it fits */
		area = usableList;
		/* remove from usable-list */
		usableList = area->next;
	}
	else {
		/* remove from usable-list */
		if(prev == NULL)
			usableList = area->next;
		else
			prev->next = area->next;
	}

	/* is there space left? */
	if(size < area->size) {
		if(freeList == NULL) {
			if(!loadNewAreas()) {
				/* TODO we may have changed something... */
				usemup(&heapSem);
				return NULL;
			}
		}

		/* split the area */
		narea = freeList;
		freeList = freeList->next;
		narea->address = (void*)((uintptr_t)area->address + size);
		narea->size = area->size - size;
		area->size = size;
		/* insert in usable-list */
		narea->next = usableList;
		usableList = narea;
	}

#if DEBUG_ALLOC_N_FREE
	if(DEBUG_ALLOC_N_FREE_PID == -1 || getpid() == DEBUG_ALLOC_N_FREE_PID) {
		size_t i = 0;
		uintptr_t *trace = getStackTrace();
		debugf("[A] %x %d ",(char*)area->address + 3,area->size);
		while(*trace && i++ < 10) {
			debugf("%x",*trace);
			if(trace[1])
				debugf(" ");
			trace++;
		}
		debugf("\n");
	}
#endif

	/* add guards */
	begin = (ulong*)area->address;
	begin[0] = (ulong)area;
	begin[1] = size - sizeof(ulong) * 4;
	begin[2] = GUARD_MAGIC;
	begin[size / sizeof(ulong) - 1] = GUARD_MAGIC;
	usemup(&heapSem);
	return begin + 3;
}
Пример #4
0
void free(void *addr) {
	ulong *begin;
	sMemArea *area,*a,*prev,*next,*nprev,*pprev,*tprev;

	/* addr may be null */
	if(addr == NULL)
		return;

	/* check guards */
	begin = (ulong*)addr - 3;
	area = (sMemArea*)begin[0];
	vassert(begin[0] != FREE_MAGIC,"Duplicate free of %p?",addr);
	assert(begin[2] == GUARD_MAGIC);
	assert(begin[begin[1] / sizeof(ulong) + 3] == GUARD_MAGIC);

	usemdown(&heapSem);

	/* mark as free */
	begin[0] = FREE_MAGIC;

	/* find the previous and next free areas */
	prev = NULL;
	next = NULL;
	tprev = NULL;
	pprev = NULL;
	nprev = NULL;
	a = usableList;
	while(a != NULL) {
		if((uintptr_t)a->address + a->size == (uintptr_t)begin) {
			prev = a;
			pprev = tprev;
		}
		if((uintptr_t)a->address == (uintptr_t)begin + area->size) {
			next = a;
			nprev = tprev;
		}
		/* do we have both? */
		if(prev && next)
			break;
		tprev = a;
		a = a->next;
	}

#if DEBUG_ALLOC_N_FREE
	if(DEBUG_ALLOC_N_FREE_PID == -1 || getpid() == DEBUG_ALLOC_N_FREE_PID) {
		size_t i = 0;
		uintptr_t *trace = getStackTrace();
		debugf("[F] %x %d ",addr,area->size);
		while(*trace && i++ < 10) {
			debugf("%x",*trace);
			if(trace[1])
				debugf(" ");
			trace++;
		}
		debugf("\n");
	}
#endif

	/* see what we have to merge */
	if(prev && next) {
		/* merge prev & area & next */
		area->size += prev->size + next->size;
		area->address = prev->address;
		/* remove prev and next from the list */
		if(nprev)
			nprev->next = next->next;
		else
			usableList = next->next;
		/* special-case if next is the previous of prev */
		if(pprev == next) {
			if(nprev)
				nprev->next = prev->next;
			else
				usableList = prev->next;
		}
		else {
			if(pprev)
				pprev->next = prev->next;
			else
				usableList = prev->next;
		}
		/* put area on the usable-list */
		area->next = usableList;
		usableList = area;
		/* put prev and next on the freelist */
		prev->next = next;
		next->next = freeList;
		freeList = prev;
	}
	else if(prev) {
		/* merge preg & area */
		prev->size += area->size;
		/* put area on the freelist */
		area->next = freeList;
		freeList = area;
	}
	else if(next) {
		/* merge area & next */
		next->address = area->address;
		next->size += area->size;
		/* put area on the freelist */
		area->next = freeList;
		freeList = area;
	}
	else {
		/* insert area in usableList */
		area->next = usableList;
		usableList = area;
	}

	usemup(&heapSem);
}