void free(void *pointer) { int i, tsize, found = 0; char *start = pointer; if (!start) return; for (i=0; i<allocedNodes; i++) { if (zalloced[i].start == start) { tsize = zalloced[i].size; #if ZDEBUG zout -= tsize; printf(" zz out %d\n",zout); #endif zdelete(zalloced, i); allocedNodes--; found = 1; break; } } if (!found) return; for (i=0; i<availableNodes; i++) { if ((start+tsize) == zavailable[i].start) // merge it in { zavailable[i].start = start; zavailable[i].size += tsize; zcoalesce(); return; } if (i>0 && (zavailable[i-1].start + zavailable[i-1].size == start)) { zavailable[i-1].size += tsize; zcoalesce(); return; } if ((start+tsize) < zavailable[i].start) { zinsert(zavailable, i); availableNodes++; zavailable[i].start = start; zavailable[i].size = tsize; return; } } zavailable[i].start = start; zavailable[i].size = tsize; availableNodes++; zcoalesce(); return; }
void * safe_malloc(size_t size, const char *file, int line) { int i; #if BEST_FIT int bestFit; size_t smallestSize; #endif char * ret = 0; if ( !zalloc_base ) { // this used to follow the bss but some bios' corrupted it... malloc_init((char *)ZALLOC_ADDR, ZALLOC_LEN, ZALLOC_NODES, malloc_error); } size = ((size + 0xf) & ~0xf); if (size == 0) { if (zerror) (*zerror)((char *)0xdeadbeef, 0, file, line); } #if BEST_FIT smallestSize = 0; bestFit = -1; #endif for (i = 0; i < availableNodes; i++) { // find node with equal size, or if not found, // then smallest node that fits. if ( zavailable[i].size == size ) { zallocate(ret = zavailable[i].start, size); zdelete(zavailable, i); availableNodes--; goto done; } #if BEST_FIT else { if ((zavailable[i].size > size) && ((smallestSize == 0) || (zavailable[i].size < smallestSize))) { bestFit = i; smallestSize = zavailable[i].size; } } #else else if ( zavailable[i].size > size ) { zallocate(ret = zavailable[i].start, size); zavailable[i].start += size; zavailable[i].size -= size; goto done; } #endif }
static void zcoalesce(void) { int i; for (i=0; i<availableNodes-1; i++) { if (zavailable[i].start + zavailable[i].size == zavailable[i+1].start) { zavailable[i].size += zavailable[i+1].size; zdelete(zavailable, i+1); availableNodes--; return; } } }
void * malloc(size_t size) { int i; char *ret = 0; #if 0 extern char _DATA__end; #endif if (!zalloc_base) { // this used to follow the bss but some bios' corrupted it... malloc_init((char *)ZALLOC_ADDR, ZALLOC_LEN, ZALLOC_NODES); } size = ((size + 0xf) & ~0xf); for (i=0; i<availableNodes; i++) { // uses first possible node, doesn't try to find best fit if (zavailable[i].size == size) { zallocate(ret = zavailable[i].start, size); zdelete(zavailable, i); availableNodes--; goto done; } else if (zavailable[i].size > size) { zallocate(ret = zavailable[i].start, size); zavailable[i].start += size; zavailable[i].size -= size; goto done; } } done: #if 0 /* if (ret + size >= (char*)_sp()) _stop("stack clobbered"); */ if (ret + size >= (char *)(ZALLOC_ADDR + ZALLOC_LEN)) _stop("Out of memory"); #endif if (ret != 0) bzero(ret, size); return (void *)ret; }