Newer
Older
if (remainder_size >= (long)MINSIZE)
{
remainder = chunk_at_offset(p, nb);
set_head(remainder, remainder_size | PREV_INUSE);
set_head_size(p, nb);
fREe(chunk2mem(remainder));
}
check_inuse_chunk(p);
return chunk2mem(p);
}
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
/*
valloc just invokes memalign with alignment argument equal
to the page size of the system (or as near to this as can
be figured out from all the includes/defines above.)
*/
#if __STD_C
Void_t* vALLOc(size_t bytes)
#else
Void_t* vALLOc(bytes) size_t bytes;
#endif
{
return mEMALIGn (malloc_getpagesize, bytes);
}
/*
pvalloc just invokes valloc for the nearest pagesize
that will accommodate request
*/
#if __STD_C
Void_t* pvALLOc(size_t bytes)
#else
Void_t* pvALLOc(bytes) size_t bytes;
#endif
{
size_t pagesize = malloc_getpagesize;
return mEMALIGn (pagesize, (bytes + pagesize - 1) & ~(pagesize - 1));
}
/*
calloc calls malloc, then zeroes out the allocated chunk.
*/
#if __STD_C
Void_t* cALLOc(size_t n, size_t elem_size)
#else
Void_t* cALLOc(n, elem_size) size_t n; size_t elem_size;
#endif
{
mchunkptr p;
INTERNAL_SIZE_T csz;
INTERNAL_SIZE_T sz = n * elem_size;
/* check if expand_top called, in which case don't need to clear */
#ifdef CONFIG_SYS_MALLOC_CLEAR_ON_INIT
#if MORECORE_CLEARS
mchunkptr oldtop = top;
INTERNAL_SIZE_T oldtopsize = chunksize(top);
#if CONFIG_VAL(SYS_MALLOC_F_LEN)
if (!(gd->flags & GD_FLG_FULL_MALLOC_INIT)) {
MALLOC_ZERO(mem, sz);
return mem;
}
#endif
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);
#ifdef CONFIG_SYS_MALLOC_CLEAR_ON_INIT
#if MORECORE_CLEARS
if (p == oldtop && csz > oldtopsize)
{
/* clear only the bytes from non-freshly-sbrked memory */
csz = oldtopsize;
}
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
#endif
MALLOC_ZERO(mem, csz - SIZE_SZ);
return mem;
}
}
/*
cfree just calls free. It is needed/defined on some systems
that pair it with calloc, presumably for odd historical reasons.
*/
#if !defined(INTERNAL_LINUX_C_LIB) || !defined(__ELF__)
#if __STD_C
void cfree(Void_t *mem)
#else
void cfree(mem) Void_t *mem;
#endif
{
fREe(mem);
}
#endif
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
/*
Malloc_trim gives memory back to the system (via negative
arguments to sbrk) if there is unused memory at the `high' end of
the malloc pool. You can call this after freeing large blocks of
memory to potentially reduce the system-level memory requirements
of a program. However, it cannot guarantee to reduce memory. Under
some allocation patterns, some large free blocks of memory will be
locked between two used chunks, so they cannot be given back to
the system.
The `pad' argument to malloc_trim represents the amount of free
trailing space to leave untrimmed. If this argument is zero,
only the minimum amount of memory to maintain internal data
structures will be left (one page or less). Non-zero arguments
can be supplied to maintain enough trailing space to service
future expected allocations without having to re-obtain memory
from the system.
Malloc_trim returns 1 if it actually released any memory, else 0.
*/
#if __STD_C
int malloc_trim(size_t pad)
#else
int malloc_trim(pad) size_t pad;
#endif
{
long top_size; /* Amount of top-most memory */
long extra; /* Amount to release */
char* current_brk; /* address returned by pre-check sbrk call */
char* new_brk; /* address returned by negative sbrk call */
unsigned long pagesz = malloc_getpagesize;
top_size = chunksize(top);
extra = ((top_size - pad - MINSIZE + (pagesz-1)) / pagesz - 1) * pagesz;
if (extra < (long)pagesz) /* Not enough memory to release */
return 0;
else
{
/* Test to make sure no one else called sbrk */
current_brk = (char*)(MORECORE (0));
if (current_brk != (char*)(top) + top_size)
return 0; /* Apparently we don't own memory; must fail */
else
{
new_brk = (char*)(MORECORE (-extra));
if (new_brk == (char*)(MORECORE_FAILURE)) /* sbrk failed? */
{
/* Try to figure out what we have */
current_brk = (char*)(MORECORE (0));
top_size = current_brk - (char*)top;
if (top_size >= (long)MINSIZE) /* if not, we are very very dead! */
{
sbrked_mem = current_brk - sbrk_base;
set_head(top, top_size | PREV_INUSE);
}
check_chunk(top);
return 0;
/* Success. Adjust top accordingly. */
set_head(top, (top_size - extra) | PREV_INUSE);
sbrked_mem -= extra;
check_chunk(top);
return 1;
/*
malloc_usable_size:
This routine tells you how many bytes you can actually use in an
allocated chunk, which may be more than you requested (although
often not). You can use this many bytes without worrying about
overwriting other allocated objects. Not a particularly great
programming practice, but still sometimes useful.
*/
#if __STD_C
size_t malloc_usable_size(Void_t* mem)
#else
size_t malloc_usable_size(mem) Void_t* mem;
#endif
{
mchunkptr p;
return 0;
else
{
p = mem2chunk(mem);
if(!chunk_is_mmapped(p))
{
if (!inuse(p)) return 0;
check_inuse_chunk(p);
return chunksize(p) - SIZE_SZ;
}
return chunksize(p) - 2*SIZE_SZ;
}
}
/* Utility to update current_mallinfo for malloc_stats and mallinfo() */
#ifdef DEBUG
static void malloc_update_mallinfo()
{
int i;
mbinptr b;
mchunkptr p;
#ifdef DEBUG
mchunkptr q;
#endif
INTERNAL_SIZE_T avail = chunksize(top);
int navail = ((long)(avail) >= (long)MINSIZE)? 1 : 0;
for (i = 1; i < NAV; ++i)
{
b = bin_at(i);
for (p = last(b); p != b; p = p->bk)
{
#ifdef DEBUG
check_free_chunk(p);
for (q = next_chunk(p);
q < top && inuse(q) && (long)(chunksize(q)) >= (long)MINSIZE;
q = next_chunk(q))
check_inuse_chunk(q);
#endif
avail += chunksize(p);
navail++;
}
}
current_mallinfo.ordblks = navail;
current_mallinfo.uordblks = sbrked_mem - avail;
current_mallinfo.fordblks = avail;
current_mallinfo.hblks = n_mmaps;
current_mallinfo.hblkhd = mmapped_mem;
current_mallinfo.keepcost = chunksize(top);
}
#endif /* DEBUG */
/*
malloc_stats:
Prints on the amount of space obtain from the system (both
via sbrk and mmap), the maximum amount (which may be more than
current if malloc_trim and/or munmap got called), the maximum
number of simultaneous mmap regions used, and the current number
of bytes allocated via malloc (or realloc, etc) but not yet
freed. (Note that this is the number of bytes allocated, not the
number requested. It will be larger than the number requested
because of alignment and bookkeeping overhead.)
*/
#ifdef DEBUG
void malloc_stats()
{
malloc_update_mallinfo();
printf("max system bytes = %10u\n",
(unsigned int)(current_mallinfo.uordblks + mmapped_mem));
#if HAVE_MMAP
printf("max mmap regions = %10u\n",
#endif /* DEBUG */
/*
mallinfo returns a copy of updated current mallinfo.
*/
#ifdef DEBUG
struct mallinfo mALLINFo()
{
malloc_update_mallinfo();
return current_mallinfo;
}
#endif /* DEBUG */
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
/*
mallopt:
mallopt is the general SVID/XPG interface to tunable parameters.
The format is to provide a (parameter-number, parameter-value) pair.
mallopt then sets the corresponding parameter to the argument
value if it can (i.e., so long as the value is meaningful),
and returns 1 if successful else 0.
See descriptions of tunable parameters above.
*/
#if __STD_C
int mALLOPt(int param_number, int value)
#else
int mALLOPt(param_number, value) int param_number; int value;
#endif
{
switch(param_number)
{
case M_TRIM_THRESHOLD:
trim_threshold = value; return 1;
case M_TOP_PAD:
top_pad = value; return 1;
case M_MMAP_THRESHOLD:
mmap_threshold = value; return 1;
case M_MMAP_MAX:
#if HAVE_MMAP
n_mmaps_max = value; return 1;
#else
if (value != 0) return 0; else n_mmaps_max = value; return 1;
#endif
default:
return 0;
}
}
#if CONFIG_VAL(SYS_MALLOC_F_LEN)
assert(gd->malloc_base); /* Set up by crt0.S */
gd->malloc_limit = CONFIG_VAL(SYS_MALLOC_F_LEN);
gd->malloc_ptr = 0;
#endif
return 0;
}
/*
History:
V2.6.6 Sun Dec 5 07:42:19 1999 Doug Lea (dl at gee)
* return null for negative arguments
* Added Several WIN32 cleanups from Martin C. Fong <mcfong@yahoo.com>
* Add 'LACKS_SYS_PARAM_H' for those systems without 'sys/param.h'
(e.g. WIN32 platforms)
* Cleanup up header file inclusion for WIN32 platforms
* Cleanup code to avoid Microsoft Visual C++ compiler complaints
* Add 'USE_DL_PREFIX' to quickly allow co-existence with existing
memory allocation routines
* Set 'malloc_getpagesize' for WIN32 platforms (needs more work)
* Use 'assert' rather than 'ASSERT' in WIN32 code to conform to
* Improve WIN32 'sbrk()' emulation's 'findRegion()' routine to
avoid infinite loop
* Always call 'fREe()' rather than 'free()'
V2.6.5 Wed Jun 17 15:57:31 1998 Doug Lea (dl at gee)
* Fixed ordering problem with boundary-stamping
V2.6.3 Sun May 19 08:17:58 1996 Doug Lea (dl at gee)
* Added pvalloc, as recommended by H.J. Liu
* Added 64bit pointer support mainly from Wolfram Gloger
* Added anonymously donated WIN32 sbrk emulation
* Malloc, calloc, getpagesize: add optimizations from Raymond Nijssen
* malloc_extend_top: fix mask error that caused wastage after
* Add linux mremap support code from HJ Liu
V2.6.2 Tue Dec 5 06:52:55 1995 Doug Lea (dl at gee)
* Integrated most documentation with the code.
* Add support for mmap, with help from
* Use last_remainder in more cases.
* Pack bins using idea from colin@nyx10.cs.du.edu
* Use ordered bins instead of best-fit threshhold
* Eliminate block-local decls to simplify tracing and debugging.
* Support another case of realloc via move into top
* Fix error occuring when initial sbrk_base not word-aligned.
* Rely on page size for units instead of SBRK_UNIT to
* Add `pad' argument to malloc_trim and top_pad mallopt parameter.
* More precautions for cases where other routines call sbrk,
courtesy of Wolfram Gloger (Gloger@lrz.uni-muenchen.de).
* Inverted this history list
V2.6.1 Sat Dec 2 14:10:57 1995 Doug Lea (dl at gee)
* Re-tuned and fixed to behave more nicely with V2.6.0 changes.
* Removed all preallocation code since under current scheme
the work required to undo bad preallocations exceeds
the work saved in good cases for most test programs.
* No longer use return list or unconsolidated bins since
no scheme using them consistently outperforms those that don't
given above changes.
* Use best fit for very large chunks to prevent some worst-cases.
* Added some support for debugging
V2.6.0 Sat Nov 4 07:05:23 1995 Doug Lea (dl at gee)
* Removed footers when chunks are in use. Thanks to
V2.5.4 Wed Nov 1 07:54:51 1995 Doug Lea (dl at gee)
* Added malloc_trim, with help from Wolfram Gloger
V2.5.3 Tue Apr 26 10:16:01 1994 Doug Lea (dl at g)
V2.5.2 Tue Apr 5 16:20:40 1994 Doug Lea (dl at g)
* realloc: try to expand in both directions
* malloc: swap order of clean-bin strategy;
* realloc: only conditionally expand backwards
* Try not to scavenge used bins
* Use bin counts as a guide to preallocation
* Occasionally bin return list chunks in first scan
* Add a few optimizations from colin@nyx10.cs.du.edu
V2.5.1 Sat Aug 14 15:40:43 1993 Doug Lea (dl at g)
* faster bin computation & slightly different binning
* merged all consolidations to one part of malloc proper
* Scan 2 returns chunks (not just 1)
* Propagate failure in realloc if malloc returns 0
* Add stuff to allow compilation on non-ANSI compilers
V2.5 Sat Aug 7 07:41:59 1993 Doug Lea (dl at g.oswego.edu)
* removed potential for odd address access in prev_chunk
* removed dependency on getpagesize.h
* misc cosmetics and a bit more internal documentation
* anticosmetics: mangled names in macros to evade debugger strangeness
* tested on sparc, hp-700, dec-mips, rs6000
with gcc & native cc (hp, dec only) allowing
Detlefs & Zorn comparison study (in SIGPLAN Notices.)
Trial version Fri Aug 28 13:14:29 1992 Doug Lea (dl at g.oswego.edu)
* Based loosely on libg++-1.2X malloc. (It retains some of the overall