--- malloc.c.sav Mon Nov 25 15:14:55 2002 +++ malloc.c Mon Nov 25 16:43:08 2002 @@ -2337,8 +2337,10 @@ void weak_variable (*__after_morecore_ho */ #if __STD_C +__inline__ static void do_check_chunk(mstate av, mchunkptr p) #else +__inline__ static void do_check_chunk(av, p) mstate av; mchunkptr p; #endif { @@ -2386,8 +2388,10 @@ static void do_check_chunk(av, p) mstate */ #if __STD_C +__inline__ static void do_check_free_chunk(mstate av, mchunkptr p) #else +__inline__ static void do_check_free_chunk(av, p) mstate av; mchunkptr p; #endif { @@ -2424,8 +2428,10 @@ static void do_check_free_chunk(av, p) m */ #if __STD_C +__inline__ static void do_check_inuse_chunk(mstate av, mchunkptr p) #else +__inline__ static void do_check_inuse_chunk(av, p) mstate av; mchunkptr p; #endif { @@ -2465,8 +2471,10 @@ static void do_check_inuse_chunk(av, p) */ #if __STD_C +__inline__ static void do_check_remalloced_chunk(mstate av, mchunkptr p, INTERNAL_SIZE_T s) #else +__inline__ static void do_check_remalloced_chunk(av, p, s) mstate av; mchunkptr p; INTERNAL_SIZE_T s; #endif @@ -2498,8 +2506,10 @@ mstate av; mchunkptr p; INTERNAL_SIZE_T */ #if __STD_C +__inline__ static void do_check_malloced_chunk(mstate av, mchunkptr p, INTERNAL_SIZE_T s) #else +__inline__ static void do_check_malloced_chunk(av, p, s) mstate av; mchunkptr p; INTERNAL_SIZE_T s; #endif @@ -2532,6 +2542,7 @@ mstate av; mchunkptr p; INTERNAL_SIZE_T display chunk addresses, sizes, bins, and other instrumentation. */ +__inline__ static void do_check_malloc_state(mstate av) { int i; @@ -2668,8 +2679,10 @@ static void do_check_malloc_state(mstate */ #if __STD_C +__inline__ static Void_t* sYSMALLOc(INTERNAL_SIZE_T nb, mstate av) #else +__inline__ static Void_t* sYSMALLOc(nb, av) INTERNAL_SIZE_T nb; mstate av; #endif { @@ -3121,8 +3134,10 @@ static Void_t* sYSMALLOc(nb, av) INTERNA */ #if __STD_C +__inline__ static int sYSTRIm(size_t pad, mstate av) #else +__inline__ static int sYSTRIm(pad, av) size_t pad; mstate av; #endif { @@ -3182,6 +3197,7 @@ static int sYSTRIm(pad, av) size_t pad; #ifdef HAVE_MMAP +__inline__ static void internal_function #if __STD_C @@ -3211,6 +3227,7 @@ munmap_chunk(p) mchunkptr p; #if HAVE_MREMAP +__inline__ static mchunkptr internal_function #if __STD_C @@ -3262,458 +3279,11 @@ mremap_chunk(p, new_size) mchunkptr p; s #endif /* HAVE_MMAP */ -/*------------------------ Public wrappers. --------------------------------*/ - -Void_t* -public_mALLOc(size_t bytes) -{ - mstate ar_ptr; - Void_t *victim; - - __malloc_ptr_t (*hook) __MALLOC_P ((size_t, __const __malloc_ptr_t)) = - __malloc_hook; - if (hook != NULL) - return (*hook)(bytes, RETURN_ADDRESS (0)); - - arena_get(ar_ptr, bytes); - if(!ar_ptr) - return 0; - victim = _int_malloc(ar_ptr, bytes); - if(!victim) { - /* Maybe the failure is due to running out of mmapped areas. */ - if(ar_ptr != &main_arena) { - (void)mutex_unlock(&ar_ptr->mutex); - (void)mutex_lock(&main_arena.mutex); - victim = _int_malloc(&main_arena, bytes); - (void)mutex_unlock(&main_arena.mutex); - } else { -#if USE_ARENAS - /* ... or sbrk() has failed and there is still a chance to mmap() */ - ar_ptr = arena_get2(ar_ptr->next ? ar_ptr : 0, bytes); - (void)mutex_unlock(&main_arena.mutex); - if(ar_ptr) { - victim = _int_malloc(ar_ptr, bytes); - (void)mutex_unlock(&ar_ptr->mutex); - } -#endif - } - } else - (void)mutex_unlock(&ar_ptr->mutex); - assert(!victim || chunk_is_mmapped(mem2chunk(victim)) || - ar_ptr == arena_for_chunk(mem2chunk(victim))); - return victim; -} - -void -public_fREe(Void_t* mem) -{ - mstate ar_ptr; - mchunkptr p; /* chunk corresponding to mem */ - - void (*hook) __MALLOC_P ((__malloc_ptr_t, __const __malloc_ptr_t)) = - __free_hook; - if (hook != NULL) { - (*hook)(mem, RETURN_ADDRESS (0)); - return; - } - - if (mem == 0) /* free(0) has no effect */ - return; - - p = mem2chunk(mem); - -#if HAVE_MMAP - if (chunk_is_mmapped(p)) /* release mmapped memory. */ - { - munmap_chunk(p); - return; - } -#endif - - ar_ptr = arena_for_chunk(p); -#if THREAD_STATS - if(!mutex_trylock(&ar_ptr->mutex)) - ++(ar_ptr->stat_lock_direct); - else { - (void)mutex_lock(&ar_ptr->mutex); - ++(ar_ptr->stat_lock_wait); - } -#else - (void)mutex_lock(&ar_ptr->mutex); -#endif - _int_free(ar_ptr, mem); - (void)mutex_unlock(&ar_ptr->mutex); -} - -Void_t* -public_rEALLOc(Void_t* oldmem, size_t bytes) -{ - mstate ar_ptr; - INTERNAL_SIZE_T nb; /* padded request size */ - - mchunkptr oldp; /* chunk corresponding to oldmem */ - INTERNAL_SIZE_T oldsize; /* its size */ - - Void_t* newp; /* chunk to return */ - - __malloc_ptr_t (*hook) __MALLOC_P ((__malloc_ptr_t, size_t, - __const __malloc_ptr_t)) = - __realloc_hook; - if (hook != NULL) - return (*hook)(oldmem, bytes, RETURN_ADDRESS (0)); - -#if REALLOC_ZERO_BYTES_FREES - if (bytes == 0 && oldmem != NULL) { public_fREe(oldmem); return 0; } -#endif - - /* realloc of null is supposed to be same as malloc */ - if (oldmem == 0) return public_mALLOc(bytes); - - oldp = mem2chunk(oldmem); - oldsize = chunksize(oldp); - - checked_request2size(bytes, nb); - -#if HAVE_MMAP - if (chunk_is_mmapped(oldp)) - { - Void_t* newmem; - -#if HAVE_MREMAP - newp = mremap_chunk(oldp, nb); - if(newp) return chunk2mem(newp); -#endif - /* Note the extra SIZE_SZ overhead. */ - if(oldsize - SIZE_SZ >= nb) return oldmem; /* do nothing */ - /* Must alloc, copy, free. */ - newmem = public_mALLOc(bytes); - if (newmem == 0) return 0; /* propagate failure */ - MALLOC_COPY(newmem, oldmem, oldsize - 2*SIZE_SZ); - munmap_chunk(oldp); - return newmem; - } -#endif - - ar_ptr = arena_for_chunk(oldp); -#if THREAD_STATS - if(!mutex_trylock(&ar_ptr->mutex)) - ++(ar_ptr->stat_lock_direct); - else { - (void)mutex_lock(&ar_ptr->mutex); - ++(ar_ptr->stat_lock_wait); - } -#else - (void)mutex_lock(&ar_ptr->mutex); -#endif - -#ifndef NO_THREADS - /* As in malloc(), remember this arena for the next allocation. */ - tsd_setspecific(arena_key, (Void_t *)ar_ptr); -#endif - - newp = _int_realloc(ar_ptr, oldmem, bytes); - - (void)mutex_unlock(&ar_ptr->mutex); - assert(!newp || chunk_is_mmapped(mem2chunk(newp)) || - ar_ptr == arena_for_chunk(mem2chunk(newp))); - return newp; -} - -Void_t* -public_mEMALIGn(size_t alignment, size_t bytes) -{ - mstate ar_ptr; - Void_t *p; - - __malloc_ptr_t (*hook) __MALLOC_PMT ((size_t, size_t, - __const __malloc_ptr_t)) = - __memalign_hook; - if (hook != NULL) - return (*hook)(alignment, bytes, RETURN_ADDRESS (0)); - - /* If need less alignment than we give anyway, just relay to malloc */ - if (alignment <= MALLOC_ALIGNMENT) return public_mALLOc(bytes); - - /* Otherwise, ensure that it is at least a minimum chunk size */ - if (alignment < MINSIZE) alignment = MINSIZE; - - arena_get(ar_ptr, bytes + alignment + MINSIZE); - if(!ar_ptr) - return 0; - p = _int_memalign(ar_ptr, alignment, bytes); - (void)mutex_unlock(&ar_ptr->mutex); - if(!p) { - /* Maybe the failure is due to running out of mmapped areas. */ - if(ar_ptr != &main_arena) { - (void)mutex_lock(&main_arena.mutex); - p = _int_memalign(&main_arena, alignment, bytes); - (void)mutex_unlock(&main_arena.mutex); - } else { -#if USE_ARENAS - /* ... or sbrk() has failed and there is still a chance to mmap() */ - ar_ptr = arena_get2(ar_ptr->next ? ar_ptr : 0, bytes); - if(ar_ptr) { - p = _int_memalign(ar_ptr, alignment, bytes); - (void)mutex_unlock(&ar_ptr->mutex); - } -#endif - } - } - assert(!p || chunk_is_mmapped(mem2chunk(p)) || - ar_ptr == arena_for_chunk(mem2chunk(p))); - return p; -} - -Void_t* -public_vALLOc(size_t bytes) -{ - mstate ar_ptr; - Void_t *p; - - if(__malloc_initialized < 0) - ptmalloc_init (); - arena_get(ar_ptr, bytes + mp_.pagesize + MINSIZE); - if(!ar_ptr) - return 0; - p = _int_valloc(ar_ptr, bytes); - (void)mutex_unlock(&ar_ptr->mutex); - return p; -} - -Void_t* -public_pVALLOc(size_t bytes) -{ - mstate ar_ptr; - Void_t *p; - - if(__malloc_initialized < 0) - ptmalloc_init (); - arena_get(ar_ptr, bytes + 2*mp_.pagesize + MINSIZE); - p = _int_pvalloc(ar_ptr, bytes); - (void)mutex_unlock(&ar_ptr->mutex); - return p; -} - -Void_t* -public_cALLOc(size_t n, size_t elem_size) -{ - mstate av; - mchunkptr oldtop, p; - INTERNAL_SIZE_T bytes, sz, csz, oldtopsize; - Void_t* mem; - unsigned long clearsize; - unsigned long nclears; - INTERNAL_SIZE_T* d; - __malloc_ptr_t (*hook) __MALLOC_PMT ((size_t, __const __malloc_ptr_t)) = - __malloc_hook; - - /* size_t is unsigned so the behavior on overflow is defined. */ - bytes = n * elem_size; -#define HALF_INTERNAL_SIZE_T \ - (((INTERNAL_SIZE_T) 1) << (8 * sizeof (INTERNAL_SIZE_T) / 2)) - if (__builtin_expect ((n | elem_size) >= HALF_INTERNAL_SIZE_T, 0)) { - if (elem_size != 0 && bytes / elem_size != n) { - MALLOC_FAILURE_ACTION; - return 0; - } - } - - if (hook != NULL) { - sz = bytes; - mem = (*hook)(sz, RETURN_ADDRESS (0)); - if(mem == 0) - return 0; -#ifdef HAVE_MEMCPY - return memset(mem, 0, sz); -#else - while(sz > 0) ((char*)mem)[--sz] = 0; /* rather inefficient */ - return mem; -#endif - } - - sz = bytes; - - arena_get(av, sz); - if(!av) - return 0; - - /* Check if we hand out the top chunk, in which case there may be no - need to clear. */ -#if MORECORE_CLEARS - oldtop = top(av); - oldtopsize = chunksize(top(av)); -#if MORECORE_CLEARS < 2 - /* Only newly allocated memory is guaranteed to be cleared. */ - if (av == &main_arena && - oldtopsize < mp_.sbrk_base + av->max_system_mem - (char *)oldtop) - oldtopsize = (mp_.sbrk_base + av->max_system_mem - (char *)oldtop); -#endif -#endif - mem = _int_malloc(av, sz); - - /* Only clearing follows, so we can unlock early. */ - (void)mutex_unlock(&av->mutex); - - assert(!mem || chunk_is_mmapped(mem2chunk(mem)) || - av == arena_for_chunk(mem2chunk(mem))); - - if (mem == 0) { - /* Maybe the failure is due to running out of mmapped areas. */ - if(av != &main_arena) { - (void)mutex_lock(&main_arena.mutex); - mem = _int_malloc(&main_arena, sz); - (void)mutex_unlock(&main_arena.mutex); - } else { -#if USE_ARENAS - /* ... or sbrk() has failed and there is still a chance to mmap() */ - (void)mutex_lock(&main_arena.mutex); - av = arena_get2(av->next ? av : 0, sz); - (void)mutex_unlock(&main_arena.mutex); - if(av) { - mem = _int_malloc(av, sz); - (void)mutex_unlock(&av->mutex); - } -#endif - } - if (mem == 0) return 0; - } - p = mem2chunk(mem); - - /* Two optional cases in which clearing not necessary */ -#if HAVE_MMAP - if (chunk_is_mmapped(p)) - return mem; -#endif - - csz = chunksize(p); - -#if MORECORE_CLEARS - if (p == oldtop && csz > oldtopsize) { - /* clear only the bytes from non-freshly-sbrked memory */ - csz = oldtopsize; - } -#endif - - /* Unroll clear of <= 36 bytes (72 if 8byte sizes). We know that - contents have an odd number of INTERNAL_SIZE_T-sized words; - minimally 3. */ - d = (INTERNAL_SIZE_T*)mem; - clearsize = csz - SIZE_SZ; - nclears = clearsize / sizeof(INTERNAL_SIZE_T); - assert(nclears >= 3); - - if (nclears > 9) - MALLOC_ZERO(d, clearsize); - - else { - *(d+0) = 0; - *(d+1) = 0; - *(d+2) = 0; - if (nclears > 4) { - *(d+3) = 0; - *(d+4) = 0; - if (nclears > 6) { - *(d+5) = 0; - *(d+6) = 0; - if (nclears > 8) { - *(d+7) = 0; - *(d+8) = 0; - } - } - } - } - - return mem; -} - -Void_t** -public_iCALLOc(size_t n, size_t elem_size, Void_t** chunks) -{ - mstate ar_ptr; - Void_t** m; - - arena_get(ar_ptr, n*elem_size); - if(!ar_ptr) - return 0; - - m = _int_icalloc(ar_ptr, n, elem_size, chunks); - (void)mutex_unlock(&ar_ptr->mutex); - return m; -} - -Void_t** -public_iCOMALLOc(size_t n, size_t sizes[], Void_t** chunks) -{ - mstate ar_ptr; - Void_t** m; - - arena_get(ar_ptr, 0); - if(!ar_ptr) - return 0; - - m = _int_icomalloc(ar_ptr, n, sizes, chunks); - (void)mutex_unlock(&ar_ptr->mutex); - return m; -} - -#ifndef _LIBC - -void -public_cFREe(Void_t* m) -{ - public_fREe(m); -} - -#endif /* _LIBC */ - -int -public_mTRIm(size_t s) -{ - int result; - - (void)mutex_lock(&main_arena.mutex); - result = mTRIm(s); - (void)mutex_unlock(&main_arena.mutex); - return result; -} - -size_t -public_mUSABLe(Void_t* m) -{ - size_t result; - - result = mUSABLe(m); - return result; -} - -void -public_mSTATs() -{ - mSTATs(); -} - -struct mallinfo public_mALLINFo() -{ - struct mallinfo m; - - (void)mutex_lock(&main_arena.mutex); - m = mALLINFo(&main_arena); - (void)mutex_unlock(&main_arena.mutex); - return m; -} - -int -public_mALLOPt(int p, int v) -{ - int result; - result = mALLOPt(p, v); - return result; -} - /* ------------------------------ malloc ------------------------------ */ +__inline__ Void_t* _int_malloc(mstate av, size_t bytes) { @@ -4098,6 +3668,7 @@ _int_malloc(mstate av, size_t bytes) ------------------------------ free ------------------------------ */ +__inline__ void _int_free(mstate av, Void_t* mem) { @@ -4270,6 +3841,7 @@ _int_free(mstate av, Void_t* mem) initialization code. */ +__inline__ #if __STD_C static void malloc_consolidate(mstate av) #else @@ -4372,6 +3944,7 @@ static void malloc_consolidate(av) mstat ------------------------------ realloc ------------------------------ */ +__inline__ Void_t* _int_realloc(mstate av, Void_t* oldmem, size_t bytes) { @@ -4597,6 +4170,7 @@ _int_realloc(mstate av, Void_t* oldmem, ------------------------------ memalign ------------------------------ */ +__inline__ Void_t* _int_memalign(mstate av, size_t alignment, size_t bytes) { @@ -4702,6 +4276,7 @@ _int_memalign(mstate av, size_t alignmen ------------------------------ calloc ------------------------------ */ +__inline__ #if __STD_C Void_t* cALLOc(size_t n_elements, size_t elem_size) #else @@ -4763,6 +4338,7 @@ Void_t* cALLOc(n_elements, elem_size) si ------------------------- independent_calloc ------------------------- */ +__inline__ Void_t** #if __STD_C _int_icalloc(mstate av, size_t n_elements, size_t elem_size, Void_t* chunks[]) @@ -4803,6 +4379,7 @@ mstate av; size_t n_elements; size_t siz */ +__inline__ static Void_t** #if __STD_C iALLOc(mstate av, size_t n_elements, size_t* sizes, int opts, Void_t* chunks[]) @@ -4928,6 +4505,7 @@ mstate av; size_t n_elements; size_t* si ------------------------------ valloc ------------------------------ */ +__inline__ Void_t* #if __STD_C _int_valloc(mstate av, size_t bytes) @@ -4965,6 +4543,7 @@ _int_pvalloc(av, bytes) mstate av, size_ ------------------------------ malloc_trim ------------------------------ */ +__inline__ #if __STD_C int mTRIm(size_t pad) #else @@ -5187,6 +4766,455 @@ int mALLOPt(param_number, value) int par } +/*------------------------ Public wrappers. --------------------------------*/ + +Void_t* +public_mALLOc(size_t bytes) +{ + mstate ar_ptr; + Void_t *victim; + + __malloc_ptr_t (*hook) __MALLOC_P ((size_t, __const __malloc_ptr_t)) = + __malloc_hook; + if (hook != NULL) + return (*hook)(bytes, RETURN_ADDRESS (0)); + + arena_get(ar_ptr, bytes); + if(!ar_ptr) + return 0; + victim = _int_malloc(ar_ptr, bytes); + if(!victim) { + /* Maybe the failure is due to running out of mmapped areas. */ + if(ar_ptr != &main_arena) { + (void)mutex_unlock(&ar_ptr->mutex); + (void)mutex_lock(&main_arena.mutex); + victim = _int_malloc(&main_arena, bytes); + (void)mutex_unlock(&main_arena.mutex); + } else { +#if USE_ARENAS + /* ... or sbrk() has failed and there is still a chance to mmap() */ + ar_ptr = arena_get2(ar_ptr->next ? ar_ptr : 0, bytes); + (void)mutex_unlock(&main_arena.mutex); + if(ar_ptr) { + victim = _int_malloc(ar_ptr, bytes); + (void)mutex_unlock(&ar_ptr->mutex); + } +#endif + } + } else + (void)mutex_unlock(&ar_ptr->mutex); + assert(!victim || chunk_is_mmapped(mem2chunk(victim)) || + ar_ptr == arena_for_chunk(mem2chunk(victim))); + return victim; +} + +void +public_fREe(Void_t* mem) +{ + mstate ar_ptr; + mchunkptr p; /* chunk corresponding to mem */ + + void (*hook) __MALLOC_P ((__malloc_ptr_t, __const __malloc_ptr_t)) = + __free_hook; + if (hook != NULL) { + (*hook)(mem, RETURN_ADDRESS (0)); + return; + } + + if (mem == 0) /* free(0) has no effect */ + return; + + p = mem2chunk(mem); + +#if HAVE_MMAP + if (chunk_is_mmapped(p)) /* release mmapped memory. */ + { + munmap_chunk(p); + return; + } +#endif + + ar_ptr = arena_for_chunk(p); +#if THREAD_STATS + if(!mutex_trylock(&ar_ptr->mutex)) + ++(ar_ptr->stat_lock_direct); + else { + (void)mutex_lock(&ar_ptr->mutex); + ++(ar_ptr->stat_lock_wait); + } +#else + (void)mutex_lock(&ar_ptr->mutex); +#endif + _int_free(ar_ptr, mem); + (void)mutex_unlock(&ar_ptr->mutex); +} + +Void_t* +public_rEALLOc(Void_t* oldmem, size_t bytes) +{ + mstate ar_ptr; + INTERNAL_SIZE_T nb; /* padded request size */ + + mchunkptr oldp; /* chunk corresponding to oldmem */ + INTERNAL_SIZE_T oldsize; /* its size */ + + Void_t* newp; /* chunk to return */ + + __malloc_ptr_t (*hook) __MALLOC_P ((__malloc_ptr_t, size_t, + __const __malloc_ptr_t)) = + __realloc_hook; + if (hook != NULL) + return (*hook)(oldmem, bytes, RETURN_ADDRESS (0)); + +#if REALLOC_ZERO_BYTES_FREES + if (bytes == 0 && oldmem != NULL) { public_fREe(oldmem); return 0; } +#endif + + /* realloc of null is supposed to be same as malloc */ + if (oldmem == 0) return public_mALLOc(bytes); + + oldp = mem2chunk(oldmem); + oldsize = chunksize(oldp); + + checked_request2size(bytes, nb); + +#if HAVE_MMAP + if (chunk_is_mmapped(oldp)) + { + Void_t* newmem; + +#if HAVE_MREMAP + newp = mremap_chunk(oldp, nb); + if(newp) return chunk2mem(newp); +#endif + /* Note the extra SIZE_SZ overhead. */ + if(oldsize - SIZE_SZ >= nb) return oldmem; /* do nothing */ + /* Must alloc, copy, free. */ + newmem = public_mALLOc(bytes); + if (newmem == 0) return 0; /* propagate failure */ + MALLOC_COPY(newmem, oldmem, oldsize - 2*SIZE_SZ); + munmap_chunk(oldp); + return newmem; + } +#endif + + ar_ptr = arena_for_chunk(oldp); +#if THREAD_STATS + if(!mutex_trylock(&ar_ptr->mutex)) + ++(ar_ptr->stat_lock_direct); + else { + (void)mutex_lock(&ar_ptr->mutex); + ++(ar_ptr->stat_lock_wait); + } +#else + (void)mutex_lock(&ar_ptr->mutex); +#endif + +#ifndef NO_THREADS + /* As in malloc(), remember this arena for the next allocation. */ + tsd_setspecific(arena_key, (Void_t *)ar_ptr); +#endif + + newp = _int_realloc(ar_ptr, oldmem, bytes); + + (void)mutex_unlock(&ar_ptr->mutex); + assert(!newp || chunk_is_mmapped(mem2chunk(newp)) || + ar_ptr == arena_for_chunk(mem2chunk(newp))); + return newp; +} + +Void_t* +public_mEMALIGn(size_t alignment, size_t bytes) +{ + mstate ar_ptr; + Void_t *p; + + __malloc_ptr_t (*hook) __MALLOC_PMT ((size_t, size_t, + __const __malloc_ptr_t)) = + __memalign_hook; + if (hook != NULL) + return (*hook)(alignment, bytes, RETURN_ADDRESS (0)); + + /* If need less alignment than we give anyway, just relay to malloc */ + if (alignment <= MALLOC_ALIGNMENT) return public_mALLOc(bytes); + + /* Otherwise, ensure that it is at least a minimum chunk size */ + if (alignment < MINSIZE) alignment = MINSIZE; + + arena_get(ar_ptr, bytes + alignment + MINSIZE); + if(!ar_ptr) + return 0; + p = _int_memalign(ar_ptr, alignment, bytes); + (void)mutex_unlock(&ar_ptr->mutex); + if(!p) { + /* Maybe the failure is due to running out of mmapped areas. */ + if(ar_ptr != &main_arena) { + (void)mutex_lock(&main_arena.mutex); + p = _int_memalign(&main_arena, alignment, bytes); + (void)mutex_unlock(&main_arena.mutex); + } else { +#if USE_ARENAS + /* ... or sbrk() has failed and there is still a chance to mmap() */ + ar_ptr = arena_get2(ar_ptr->next ? ar_ptr : 0, bytes); + if(ar_ptr) { + p = _int_memalign(ar_ptr, alignment, bytes); + (void)mutex_unlock(&ar_ptr->mutex); + } +#endif + } + } + assert(!p || chunk_is_mmapped(mem2chunk(p)) || + ar_ptr == arena_for_chunk(mem2chunk(p))); + return p; +} + +Void_t* +public_vALLOc(size_t bytes) +{ + mstate ar_ptr; + Void_t *p; + + if(__malloc_initialized < 0) + ptmalloc_init (); + arena_get(ar_ptr, bytes + mp_.pagesize + MINSIZE); + if(!ar_ptr) + return 0; + p = _int_valloc(ar_ptr, bytes); + (void)mutex_unlock(&ar_ptr->mutex); + return p; +} + +Void_t* +public_pVALLOc(size_t bytes) +{ + mstate ar_ptr; + Void_t *p; + + if(__malloc_initialized < 0) + ptmalloc_init (); + arena_get(ar_ptr, bytes + 2*mp_.pagesize + MINSIZE); + p = _int_pvalloc(ar_ptr, bytes); + (void)mutex_unlock(&ar_ptr->mutex); + return p; +} + +Void_t* +public_cALLOc(size_t n, size_t elem_size) +{ + mstate av; + mchunkptr oldtop, p; + INTERNAL_SIZE_T bytes, sz, csz, oldtopsize; + Void_t* mem; + unsigned long clearsize; + unsigned long nclears; + INTERNAL_SIZE_T* d; + __malloc_ptr_t (*hook) __MALLOC_PMT ((size_t, __const __malloc_ptr_t)) = + __malloc_hook; + + /* size_t is unsigned so the behavior on overflow is defined. */ + bytes = n * elem_size; +#define HALF_INTERNAL_SIZE_T \ + (((INTERNAL_SIZE_T) 1) << (8 * sizeof (INTERNAL_SIZE_T) / 2)) + if (__builtin_expect ((n | elem_size) >= HALF_INTERNAL_SIZE_T, 0)) { + if (elem_size != 0 && bytes / elem_size != n) { + MALLOC_FAILURE_ACTION; + return 0; + } + } + + if (hook != NULL) { + sz = bytes; + mem = (*hook)(sz, RETURN_ADDRESS (0)); + if(mem == 0) + return 0; +#ifdef HAVE_MEMCPY + return memset(mem, 0, sz); +#else + while(sz > 0) ((char*)mem)[--sz] = 0; /* rather inefficient */ + return mem; +#endif + } + + sz = bytes; + + arena_get(av, sz); + if(!av) + return 0; + + /* Check if we hand out the top chunk, in which case there may be no + need to clear. */ +#if MORECORE_CLEARS + oldtop = top(av); + oldtopsize = chunksize(top(av)); +#if MORECORE_CLEARS < 2 + /* Only newly allocated memory is guaranteed to be cleared. */ + if (av == &main_arena && + oldtopsize < mp_.sbrk_base + av->max_system_mem - (char *)oldtop) + oldtopsize = (mp_.sbrk_base + av->max_system_mem - (char *)oldtop); +#endif +#endif + mem = _int_malloc(av, sz); + + /* Only clearing follows, so we can unlock early. */ + (void)mutex_unlock(&av->mutex); + + assert(!mem || chunk_is_mmapped(mem2chunk(mem)) || + av == arena_for_chunk(mem2chunk(mem))); + + if (mem == 0) { + /* Maybe the failure is due to running out of mmapped areas. */ + if(av != &main_arena) { + (void)mutex_lock(&main_arena.mutex); + mem = _int_malloc(&main_arena, sz); + (void)mutex_unlock(&main_arena.mutex); + } else { +#if USE_ARENAS + /* ... or sbrk() has failed and there is still a chance to mmap() */ + (void)mutex_lock(&main_arena.mutex); + av = arena_get2(av->next ? av : 0, sz); + (void)mutex_unlock(&main_arena.mutex); + if(av) { + mem = _int_malloc(av, sz); + (void)mutex_unlock(&av->mutex); + } +#endif + } + if (mem == 0) return 0; + } + p = mem2chunk(mem); + + /* Two optional cases in which clearing not necessary */ +#if HAVE_MMAP + if (chunk_is_mmapped(p)) + return mem; +#endif + + csz = chunksize(p); + +#if MORECORE_CLEARS + if (p == oldtop && csz > oldtopsize) { + /* clear only the bytes from non-freshly-sbrked memory */ + csz = oldtopsize; + } +#endif + + /* Unroll clear of <= 36 bytes (72 if 8byte sizes). We know that + contents have an odd number of INTERNAL_SIZE_T-sized words; + minimally 3. */ + d = (INTERNAL_SIZE_T*)mem; + clearsize = csz - SIZE_SZ; + nclears = clearsize / sizeof(INTERNAL_SIZE_T); + assert(nclears >= 3); + + if (nclears > 9) + MALLOC_ZERO(d, clearsize); + + else { + *(d+0) = 0; + *(d+1) = 0; + *(d+2) = 0; + if (nclears > 4) { + *(d+3) = 0; + *(d+4) = 0; + if (nclears > 6) { + *(d+5) = 0; + *(d+6) = 0; + if (nclears > 8) { + *(d+7) = 0; + *(d+8) = 0; + } + } + } + } + + return mem; +} + +Void_t** +public_iCALLOc(size_t n, size_t elem_size, Void_t** chunks) +{ + mstate ar_ptr; + Void_t** m; + + arena_get(ar_ptr, n*elem_size); + if(!ar_ptr) + return 0; + + m = _int_icalloc(ar_ptr, n, elem_size, chunks); + (void)mutex_unlock(&ar_ptr->mutex); + return m; +} + +Void_t** +public_iCOMALLOc(size_t n, size_t sizes[], Void_t** chunks) +{ + mstate ar_ptr; + Void_t** m; + + arena_get(ar_ptr, 0); + if(!ar_ptr) + return 0; + + m = _int_icomalloc(ar_ptr, n, sizes, chunks); + (void)mutex_unlock(&ar_ptr->mutex); + return m; +} + +#ifndef _LIBC + +void +public_cFREe(Void_t* m) +{ + public_fREe(m); +} + +#endif /* _LIBC */ + +int +public_mTRIm(size_t s) +{ + int result; + + (void)mutex_lock(&main_arena.mutex); + result = mTRIm(s); + (void)mutex_unlock(&main_arena.mutex); + return result; +} + +size_t +public_mUSABLe(Void_t* m) +{ + size_t result; + + result = mUSABLe(m); + return result; +} + +void +public_mSTATs() +{ + mSTATs(); +} + +struct mallinfo public_mALLINFo() +{ + struct mallinfo m; + + (void)mutex_lock(&main_arena.mutex); + m = mALLINFo(&main_arena); + (void)mutex_unlock(&main_arena.mutex); + return m; +} + +int +public_mALLOPt(int p, int v) +{ + int result; + result = mALLOPt(p, v); + return result; +} + + /* -------------------- Alternative MORECORE functions -------------------- */