void * malloc(size_t size) { void *ptr = NULL; switch(mallocState) { case UNINITIALIZED: LOCK; mallocState = INITIALIZING; UNLOCK; if(loadLibC(LIBC)) { exit(-1); } LOCK; mallocState = INITIALIZED; UNLOCK; case INITIALIZED: if(size == 0) return (void *) NULL; size += REDZONESIZE * 2; ptr = realmalloc(size); if(! ptr) return ptr; realmemset(ptr, 0, size); if(addAlloc(size, ptr) != 0) { realfree(ptr); return NULL; } return ptr + REDZONESIZE; break; case INITIALIZING: if(size == 0) return NULL; return staticMalloc(size); break; } return NULL; }
static void * _malloc_unlocked(size_t size) { size_t n; TREE *tp, *sp; size_t o_bit1; COUNT(nmalloc); ASSERT(WORDSIZE == ALIGN); /* check for size that could overflow calculations */ if (size > MAX_MALLOC) { errno = ENOMEM; return (NULL); } /* make sure that size is 0 mod ALIGN */ ROUND(size); /* see if the last free block can be used */ if (Lfree) { sp = BLOCK(Lfree); n = SIZE(sp); CLRBITS01(n); if (n == size) { /* * exact match, use it as is */ freeidx = (freeidx + FREESIZE - 1) & FREEMASK; /* 1 back */ flist[freeidx] = Lfree = NULL; return (DATA(sp)); } else if (size >= MINSIZE && n > size) { /* * got a big enough piece */ freeidx = (freeidx + FREESIZE - 1) & FREEMASK; /* 1 back */ flist[freeidx] = Lfree = NULL; o_bit1 = SIZE(sp) & BIT1; SIZE(sp) = n; goto leftover; } } o_bit1 = 0; /* perform free's of space since last malloc */ cleanfree(NULL); /* small blocks */ if (size < MINSIZE) return (_smalloc(size)); /* search for an elt of the right size */ sp = NULL; n = 0; if (Root) { tp = Root; for (;;) { /* branch left */ if (SIZE(tp) >= size) { if (n == 0 || n >= SIZE(tp)) { sp = tp; n = SIZE(tp); } if (LEFT(tp)) tp = LEFT(tp); else break; } else { /* branch right */ if (RIGHT(tp)) tp = RIGHT(tp); else break; } } if (sp) { t_delete(sp); } else if (tp != Root) { /* make the searched-to element the root */ t_splay(tp); Root = tp; } } /* if found none fitted in the tree */ if (!sp) { if (Bottom && size <= SIZE(Bottom)) { sp = Bottom; CLRBITS01(SIZE(sp)); } else if ((sp = _morecore(size)) == NULL) /* no more memory */ return (NULL); } /* tell the forward neighbor that we're busy */ CLRBIT1(SIZE(NEXT(sp))); ASSERT(ISBIT0(SIZE(NEXT(sp)))); leftover: /* if the leftover is enough for a new free piece */ if ((n = (SIZE(sp) - size)) >= MINSIZE + WORDSIZE) { n -= WORDSIZE; SIZE(sp) = size; tp = NEXT(sp); SIZE(tp) = n|BIT0; realfree(DATA(tp)); } else if (BOTTOM(sp)) Bottom = NULL; /* return the allocated space */ SIZE(sp) |= BIT0 | o_bit1; return (DATA(sp)); }