diff options
| author | Ulrich Drepper <drepper@gmail.com> | 2011-09-10 18:10:17 -0400 |
|---|---|---|
| committer | Ulrich Drepper <drepper@gmail.com> | 2011-09-10 18:10:17 -0400 |
| commit | 22a89187139a9083ca73989bfd11597e0f85cb61 (patch) | |
| tree | b4aed5fc659f72e14dc14dc68d68c8de4895893f /malloc/malloc.c | |
| parent | d063d164335938d557460bebaa7cfe388157b627 (diff) | |
| download | glibc-22a89187139a9083ca73989bfd11597e0f85cb61.tar.xz glibc-22a89187139a9083ca73989bfd11597e0f85cb61.zip | |
Simplify malloc code
Remove all kinds of unused configuration options and dead code.
Diffstat (limited to 'malloc/malloc.c')
| -rw-r--r-- | malloc/malloc.c | 1650 |
1 files changed, 203 insertions, 1447 deletions
diff --git a/malloc/malloc.c b/malloc/malloc.c index d7af63dae5..0683eee2a1 100644 --- a/malloc/malloc.c +++ b/malloc/malloc.c @@ -74,20 +74,20 @@ Standard (ANSI/SVID/...) functions: malloc(size_t n); calloc(size_t n_elements, size_t element_size); - free(Void_t* p); - realloc(Void_t* p, size_t n); + free(void* p); + realloc(void* p, size_t n); memalign(size_t alignment, size_t n); valloc(size_t n); mallinfo() mallopt(int parameter_number, int parameter_value) Additional functions: - independent_calloc(size_t n_elements, size_t size, Void_t* chunks[]); - independent_comalloc(size_t n_elements, size_t sizes[], Void_t* chunks[]); + independent_calloc(size_t n_elements, size_t size, void* chunks[]); + independent_comalloc(size_t n_elements, size_t sizes[], void* chunks[]); pvalloc(size_t n); - cfree(Void_t* p); + cfree(void* p); malloc_trim(size_t pad); - malloc_usable_size(Void_t* p); + malloc_usable_size(void* p); malloc_stats(); * Vital statistics: @@ -145,7 +145,7 @@ failure action and then return null. (Requests may also also fail because a system is out of memory.) - Thread-safety: thread-safe unless NO_THREADS is defined + Thread-safety: thread-safe Compliance: I believe it is compliant with the 1997 Single Unix Specification Also SVID/XPG, ANSI C, and probably others as well. @@ -154,8 +154,7 @@ People have reported using previous versions of this malloc on all versions of Unix, sometimes by tweaking some of the defines - below. It has been tested most extensively on Solaris and - Linux. It is also reported to work on WIN32 platforms. + below. It has been tested most extensively on Solaris and Linux. People also report using it in stand-alone embedded systems. The implementation is in straight, hand-tuned ANSI C. It is not @@ -170,19 +169,8 @@ Compilation Environment options: - __STD_C derived from C compiler defines - WIN32 NOT defined - HAVE_MEMCPY defined - USE_MEMCPY 1 if HAVE_MEMCPY is defined - HAVE_MMAP defined as 1 - MMAP_CLEARS 1 HAVE_MREMAP 0 unless linux defined - USE_ARENAS the same as HAVE_MMAP malloc_getpagesize derived from system #includes, or 4096 if not - HAVE_USR_INCLUDE_MALLOC_H NOT defined - LACKS_UNISTD_H NOT defined unless WIN32 - LACKS_SYS_PARAM_H NOT defined unless WIN32 - LACKS_SYS_MMAN_H NOT defined unless WIN32 Changing default word sizes: @@ -197,7 +185,7 @@ USE_MALLOC_LOCK NOT defined MALLOC_DEBUG NOT defined REALLOC_ZERO_BYTES_FREES 1 - MALLOC_FAILURE_ACTION errno = ENOMEM, if __STD_C defined, else no-op + MALLOC_FAILURE_ACTION errno = ENOMEM TRIM_FASTBINS 0 Options for customizing MORECORE: @@ -221,67 +209,28 @@ probably don't want to touch unless you are extending or adapting malloc. */ /* - __STD_C should be nonzero if using ANSI-standard C compiler, a C++ - compiler, or a C compiler sufficiently close to ANSI to get away - with it. + void* is the pointer type that malloc should say it returns */ -#ifndef __STD_C -#if defined(__STDC__) || defined(__cplusplus) -#define __STD_C 1 -#else -#define __STD_C 0 -#endif -#endif /*__STD_C*/ - - -/* - Void_t* is the pointer type that malloc should say it returns -*/ - -#ifndef Void_t -#if (__STD_C || defined(WIN32)) -#define Void_t void -#else -#define Void_t char -#endif -#endif /*Void_t*/ +#ifndef void +#define void void +#endif /*void*/ -#if __STD_C #include <stddef.h> /* for size_t */ #include <stdlib.h> /* for getenv(), abort() */ -#else -#include <sys/types.h> -#endif #include <malloc-machine.h> -#ifdef _LIBC -#ifdef ATOMIC_FASTBINS #include <atomic.h> -#endif #include <stdio-common/_itoa.h> #include <bits/wordsize.h> #include <sys/sysinfo.h> -#endif #ifdef __cplusplus extern "C" { #endif -/* define LACKS_UNISTD_H if your system does not have a <unistd.h>. */ - -/* #define LACKS_UNISTD_H */ - -#ifndef LACKS_UNISTD_H #include <unistd.h> -#endif - -/* define LACKS_SYS_PARAM_H if your system does not have a <sys/param.h>. */ - -/* #define LACKS_SYS_PARAM_H */ - - #include <stdio.h> /* needed for malloc_stats */ #include <errno.h> /* needed for optional MALLOC_FAILURE_ACTION */ @@ -486,7 +435,6 @@ __malloc_assert (const char *assertion, const char *file, unsigned int line, #define public_gET_STATe dlget_state #define public_sET_STATe dlset_state #else /* USE_DL_PREFIX */ -#ifdef _LIBC /* Special defines for the GNU C library. */ #define public_cALLOc __libc_calloc @@ -515,79 +463,13 @@ __malloc_assert (const char *assertion, const char *file, unsigned int line, #define MORECORE (*__morecore) #define MORECORE_FAILURE 0 -Void_t * __default_morecore (ptrdiff_t); -Void_t *(*__morecore)(ptrdiff_t) = __default_morecore; - -#else /* !_LIBC */ -#define public_cALLOc calloc -#define public_fREe free -#define public_cFREe cfree -#define public_mALLOc malloc -#define public_mEMALIGn memalign -#define public_rEALLOc realloc -#define public_vALLOc valloc -#define public_pVALLOc pvalloc -#define public_mALLINFo mallinfo -#define public_mALLOPt mallopt -#define public_mTRIm malloc_trim -#define public_mSTATs malloc_stats -#define public_mUSABLe malloc_usable_size -#define public_iCALLOc independent_calloc -#define public_iCOMALLOc independent_comalloc -#define public_gET_STATe malloc_get_state -#define public_sET_STATe malloc_set_state -#endif /* _LIBC */ -#endif /* USE_DL_PREFIX */ - -#ifndef _LIBC -#define __builtin_expect(expr, val) (expr) - -#define fwrite(buf, size, count, fp) _IO_fwrite (buf, size, count, fp) -#endif - -/* - HAVE_MEMCPY should be defined if you are not otherwise using - ANSI STD C, but still have memcpy and memset in your C library - and want to use them in calloc and realloc. Otherwise simple - macro versions are defined below. - - USE_MEMCPY should be defined as 1 if you actually want to - have memset and memcpy called. People report that the macro - versions are faster than libc versions on some systems. - - Even if USE_MEMCPY is set to 1, loops to copy/clear small chunks - (of <= 36 bytes) are manually unrolled in realloc and calloc. -*/ - -#define HAVE_MEMCPY - -#ifndef USE_MEMCPY -#ifdef HAVE_MEMCPY -#define USE_MEMCPY 1 -#else -#define USE_MEMCPY 0 -#endif -#endif +void * __default_morecore (ptrdiff_t); +void *(*__morecore)(ptrdiff_t) = __default_morecore; +#endif /* USE_DL_PREFIX */ -#if (__STD_C || defined(HAVE_MEMCPY)) -#ifdef _LIBC -# include <string.h> -#else -#ifdef WIN32 -/* On Win32 memset and memcpy are already declared in windows.h */ -#else -#if __STD_C -void* memset(void*, int, size_t); -void* memcpy(void*, const void*, size_t); -#else -Void_t* memset(); -Void_t* memcpy(); -#endif -#endif -#endif -#endif +#include <string.h> /* Force a value to be in a register and stop the compiler referring @@ -605,13 +487,9 @@ Void_t* memcpy(); */ #ifndef MALLOC_FAILURE_ACTION -#if __STD_C #define MALLOC_FAILURE_ACTION \ errno = ENOMEM; -#else -#define MALLOC_FAILURE_ACTION -#endif #endif /* @@ -619,16 +497,6 @@ Void_t* memcpy(); */ -#ifdef LACKS_UNISTD_H -#if !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__NetBSD__) -#if __STD_C -extern Void_t* sbrk(ptrdiff_t); -#else -extern Void_t* sbrk(); -#endif -#endif -#endif - /* MORECORE is the name of the routine to call to obtain more memory from the system. See below for general guidance on writing @@ -689,49 +557,16 @@ extern Void_t* sbrk(); /* - Define HAVE_MMAP as true to optionally make malloc() use mmap() to - allocate very large blocks. These will be returned to the - operating system immediately after a free(). Also, if mmap - is available, it is used as a backup strategy in cases where - MORECORE fails to provide space from system. - - This malloc is best tuned to work with mmap for large requests. - If you do not have mmap, operations involving very large chunks (1MB - or so) may be slower than you'd like. -*/ - -#ifndef HAVE_MMAP -#define HAVE_MMAP 1 - -/* - Standard unix mmap using /dev/zero clears memory so calloc doesn't - need to. -*/ - -#ifndef MMAP_CLEARS -#define MMAP_CLEARS 1 -#endif - -#else /* no mmap */ -#ifndef MMAP_CLEARS -#define MMAP_CLEARS 0 -#endif -#endif - - -/* MMAP_AS_MORECORE_SIZE is the minimum mmap size argument to use if - sbrk fails, and mmap is used as a backup (which is done only if - HAVE_MMAP). The value must be a multiple of page size. This - backup strategy generally applies only when systems have "holes" in - address space, so sbrk cannot perform contiguous expansion, but - there is still space available on system. On systems for which - this is known to be useful (i.e. most linux kernels), this occurs - only when programs allocate huge amounts of memory. Between this, - and the fact that mmap regions tend to be limited, the size should - be large, to avoid too many mmap calls and thus avoid running out - of kernel resources. -*/ + sbrk fails, and mmap is used as a backup. The value must be a + multiple of page size. This backup strategy generally applies only + when systems have "holes" in address space, so sbrk cannot perform + contiguous expansion, but there is still space available on system. + On systems for which this is known to be useful (i.e. most linux + kernels), this occurs only when programs allocate huge amounts of + memory. Between this, and the fact that mmap regions tend to be + limited, the size should be large, to avoid too many mmap calls and + thus avoid running out of kernel resources. */ #ifndef MMAP_AS_MORECORE_SIZE #define MMAP_AS_MORECORE_SIZE (1024 * 1024) @@ -750,16 +585,7 @@ extern Void_t* sbrk(); #define HAVE_MREMAP 0 #endif -#endif /* HAVE_MMAP */ - -/* Define USE_ARENAS to enable support for multiple `arenas'. These - are allocated using mmap(), are necessary for threads and - occasionally useful to overcome address space limitations affecting - sbrk(). */ - -#ifndef USE_ARENAS -#define USE_ARENAS HAVE_MMAP -#endif +#endif /* HAVE_MREMAP */ /* @@ -776,54 +602,8 @@ extern Void_t* sbrk(); #ifndef malloc_getpagesize - -#ifndef LACKS_UNISTD_H -# include <unistd.h> -#endif - -# ifdef _SC_PAGESIZE /* some SVR4 systems omit an underscore */ -# ifndef _SC_PAGE_SIZE -# define _SC_PAGE_SIZE _SC_PAGESIZE -# endif -# endif - -# ifdef _SC_PAGE_SIZE -# define malloc_getpagesize sysconf(_SC_PAGE_SIZE) -# else -# if defined(BSD) || defined(DGUX) || defined(HAVE_GETPAGESIZE) - extern size_t getpagesize(); -# define malloc_getpagesize getpagesize() -# else -# ifdef WIN32 /* use supplied emulation of getpagesize */ -# define malloc_getpagesize getpagesize() -# else -# ifndef LACKS_SYS_PARAM_H -# include <sys/param.h> -# endif -# ifdef EXEC_PAGESIZE -# define malloc_getpagesize EXEC_PAGESIZE -# else -# ifdef NBPG -# ifndef CLSIZE -# define malloc_getpagesize NBPG -# else -# define malloc_getpagesize (NBPG * CLSIZE) -# endif -# else -# ifdef NBPC -# define malloc_getpagesize NBPC -# else -# ifdef PAGESIZE -# define malloc_getpagesize PAGESIZE -# else /* just guess */ -# define malloc_getpagesize (4096) -# endif -# endif -# endif -# endif -# endif -# endif -# endif +# include <unistd.h> +# define malloc_getpagesize sysconf(_SC_PAGE_SIZE) #endif /* @@ -840,25 +620,8 @@ extern Void_t* sbrk(); bunch of fields that are not even meaningful in this version of malloc. These fields are are instead filled by mallinfo() with other numbers that might be of interest. - - HAVE_USR_INCLUDE_MALLOC_H should be set if you have a - /usr/include/malloc.h file that includes a declaration of struct - mallinfo. If so, it is included; else an SVID2/XPG2 compliant - version is declared below. These must be precisely the same for - mallinfo() to work. The original SVID version of this struct, - defined on most systems with mallinfo, declares all fields as - ints. But some others define as unsigned long. If your system - defines the fields using a type of different width than listed here, - you must #include your system version and #define - HAVE_USR_INCLUDE_MALLOC_H. */ -/* #define HAVE_USR_INCLUDE_MALLOC_H */ - -#ifdef HAVE_USR_INCLUDE_MALLOC_H -#include "/usr/include/malloc.h" -#endif - /* ---------- description of public routines ------------ */ @@ -876,17 +639,11 @@ extern Void_t* sbrk(); differs across systems, but is in all cases less than the maximum representable value of a size_t. */ -#if __STD_C -Void_t* public_mALLOc(size_t); -#else -Void_t* public_mALLOc(); -#endif -#ifdef libc_hidden_proto +void* public_mALLOc(size_t); libc_hidden_proto (public_mALLOc) -#endif /* - free(Void_t* p) + free(void* p) Releases the chunk of memory pointed to by p, that had been previously allocated using malloc or a related routine such as realloc. It has no effect if p is null. It can have arbitrary (i.e., bad!) @@ -896,28 +653,18 @@ libc_hidden_proto (public_mALLOc) when possible, automatically trigger operations that give back unused memory to the system, thus reducing program footprint. */ -#if __STD_C -void public_fREe(Void_t*); -#else -void public_fREe(); -#endif -#ifdef libc_hidden_proto +void public_fREe(void*); libc_hidden_proto (public_fREe) -#endif /* calloc(size_t n_elements, size_t element_size); Returns a pointer to n_elements * element_size bytes, with all locations set to zero. */ -#if __STD_C -Void_t* public_cALLOc(size_t, size_t); -#else -Void_t* public_cALLOc(); -#endif +void* public_cALLOc(size_t, size_t); /* - realloc(Void_t* p, size_t n) + realloc(void* p, size_t n) Returns a pointer to a chunk of size n that contains the same data as does chunk p up to the minimum of (n, p's size) bytes, or null if no space is available. @@ -943,14 +690,8 @@ Void_t* public_cALLOc(); The old unix realloc convention of allowing the last-free'd chunk to be used as an argument to realloc is not supported. */ -#if __STD_C -Void_t* public_rEALLOc(Void_t*, size_t); -#else -Void_t* public_rEALLOc(); -#endif -#ifdef libc_hidden_proto +void* public_rEALLOc(void*, size_t); libc_hidden_proto (public_rEALLOc) -#endif /* memalign(size_t alignment, size_t n); @@ -964,25 +705,15 @@ libc_hidden_proto (public_rEALLOc) Overreliance on memalign is a sure way to fragment space. */ -#if __STD_C -Void_t* public_mEMALIGn(size_t, size_t); -#else -Void_t* public_mEMALIGn(); -#endif -#ifdef libc_hidden_proto +void* public_mEMALIGn(size_t, size_t); libc_hidden_proto (public_mEMALIGn) -#endif /* valloc(size_t n); Equivalent to memalign(pagesize, n), where pagesize is the page size of the system. If the pagesize is unknown, 4096 is used. */ -#if __STD_C -Void_t* public_vALLOc(size_t); -#else -Void_t* public_vALLOc(); -#endif +void* public_vALLOc(size_t); @@ -1007,11 +738,7 @@ Void_t* public_vALLOc(); M_MMAP_THRESHOLD -3 128*1024 any (or 0 if no MMAP support) M_MMAP_MAX -4 65536 any (0 disables use of mmap) */ -#if __STD_C int public_mALLOPt(int, int); -#else -int public_mALLOPt(); -#endif /* @@ -1037,137 +764,7 @@ int public_mALLOPt(); be kept as longs, the reported values may wrap around zero and thus be inaccurate. */ -#if __STD_C struct mallinfo public_mALLINFo(void); -#else -struct mallinfo public_mALLINFo(); -#endif - -#ifndef _LIBC -/* - independent_calloc(size_t n_elements, size_t element_size, Void_t* chunks[]); - - independent_calloc is similar to calloc, but instead of returning a - single cleared space, it returns an array of pointers to n_elements - independent elements that can hold contents of size elem_size, each - of which starts out cleared, and can be independently freed, - realloc'ed etc. The elements are guaranteed to be adjacently - allocated (this is not guaranteed to occur with multiple callocs or - mallocs), which may also improve cache locality in some - applications. - - The "chunks" argument is optional (i.e., may be null, which is - probably the most typical usage). If it is null, the returned array - is itself dynamically allocated and should also be freed when it is - no longer needed. Otherwise, the chunks array must be of at least - n_elements in length. It is filled in with the pointers to the - chunks. - - In either case, independent_calloc returns this pointer array, or - null if the allocation failed. If n_elements is zero and "chunks" - is null, it returns a chunk representing an array with zero elements - (which should be freed if not wanted). - - Each element must be individually freed when it is no longer - needed. If you'd like to instead be able to free all at once, you - should instead use regular calloc and assign pointers into this - space to represent elements. (In this case though, you cannot - independently free elements.) - - independent_calloc simplifies and speeds up implementations of many - kinds of pools. It may also be useful when constructing large data - structures that initially have a fixed number of fixed-sized nodes, - but the number is not known at compile time, and some of the nodes - may later need to be freed. For example: - - struct Node { int item; struct Node* next; }; - - struct Node* build_list() { - struct Node** pool; - int n = read_number_of_nodes_needed(); - if (n <= 0) return 0; - pool = (struct Node**)(independent_calloc(n, sizeof(struct Node), 0); - if (pool == 0) die(); - // organize into a linked list... - struct Node* first = pool[0]; - for (i = 0; i < n-1; ++i) - pool[i]->next = pool[i+1]; - free(pool); // Can now free the array (or not, if it is needed later) - return first; - } -*/ -#if __STD_C -Void_t** public_iCALLOc(size_t, size_t, Void_t**); -#else -Void_t** public_iCALLOc(); -#endif - -/* - independent_comalloc(size_t n_elements, size_t sizes[], Void_t* chunks[]); - - independent_comalloc allocates, all at once, a set of n_elements - chunks with sizes indicated in the "sizes" array. It returns - an array of pointers to these elements, each of which can be - independently freed, realloc'ed etc. The elements are guaranteed to - be adjacently allocated (this is not guaranteed to occur with - multiple callocs or mallocs), which may also improve cache locality - in some applications. - - The "chunks" argument is optional (i.e., may be null). If it is null - the returned array is itself dynamically allocated and should also - be freed when it is no longer needed. Otherwise, the chunks array - must be of at least n_elements in length. It is filled in with the - pointers to the chunks. - - In either case, independent_comalloc returns this pointer array, or - null if the allocation failed. If n_elements is zero and chunks is - null, it returns a chunk representing an array with zero elements - (which should be freed if not wanted). - - Each element must be individually freed when it is no longer - needed. If you'd like to instead be able to free all at once, you - should instead use a single regular malloc, and assign pointers at - particular offsets in the aggregate space. (In this case though, you - cannot independently free elements.) - - independent_comallac differs from independent_calloc in that each - element may have a different size, and also that it does not - automatically clear elements. - - independent_comalloc can be used to speed up allocation in cases - where several structs or objects must always be allocated at the - same time. For example: - - struct Head { ... } - struct Foot { ... } - - void send_message(char* msg) { - int msglen = strlen(msg); - size_t sizes[3] = { sizeof(struct Head), msglen, sizeof(struct Foot) }; - void* chunks[3]; - if (independent_comalloc(3, sizes, chunks) == 0) - die(); - struct Head* head = (struct Head*)(chunks[0]); - char* body = (char*)(chunks[1]); - struct Foot* foot = (struct Foot*)(chunks[2]); - // ... - } - - In general though, independent_comalloc is worth using only for - larger values of n_elements. For small values, you probably won't - detect enough difference from series of malloc calls to bother. - - Overuse of independent_comalloc can increase overall memory usage, - since it cannot reuse existing noncontiguous small chunks that - might be available for some of the elements. -*/ -#if __STD_C -Void_t** public_iCOMALLOc(size_t, size_t*, Void_t**); -#else -Void_t** public_iCOMALLOc(); -#endif - -#endif /* _LIBC */ /* @@ -1175,25 +772,17 @@ Void_t** public_iCOMALLOc(); Equivalent to valloc(minimum-page-that-holds(n)), that is, round up n to nearest pagesize. */ -#if __STD_C -Void_t* public_pVALLOc(size_t); -#else -Void_t* public_pVALLOc(); -#endif +void* public_pVALLOc(size_t); /* - cfree(Void_t* p); + cfree(void* p); Equivalent to free(p). cfree is needed/defined on some systems that pair it with calloc, for odd historical reasons (such as: cfree is used in example code in the first edition of K&R). */ -#if __STD_C -void public_cFREe(Void_t*); -#else -void public_cFREe(); -#endif +void public_cFREe(void*); /* malloc_trim(size_t pad); @@ -1219,14 +808,10 @@ void public_cFREe(); On systems that do not support "negative sbrks", it will always return 0. */ -#if __STD_C int public_mTRIm(size_t); -#else -int public_mTRIm(); -#endif /* - malloc_usable_size(Void_t* p); + malloc_usable_size(void* p); Returns the number of bytes you can actually use in an allocated chunk, which may be more than you requested (although @@ -1240,11 +825,7 @@ int public_mTRIm(); assert(malloc_usable_size(p) >= 256); */ -#if __STD_C -size_t p |
