aboutsummaryrefslogtreecommitdiff
path: root/malloc/malloc.c
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@gmail.com>2011-09-10 18:10:17 -0400
committerUlrich Drepper <drepper@gmail.com>2011-09-10 18:10:17 -0400
commit22a89187139a9083ca73989bfd11597e0f85cb61 (patch)
treeb4aed5fc659f72e14dc14dc68d68c8de4895893f /malloc/malloc.c
parentd063d164335938d557460bebaa7cfe388157b627 (diff)
downloadglibc-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.c1650
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