xref: /openbmc/u-boot/include/malloc.h (revision 172e3c11901229f0fb88317ac73a47d944a74f46)
15b1d7137Swdenk /*
25b1d7137Swdenk   A version of malloc/free/realloc written by Doug Lea and released to the
35b1d7137Swdenk   public domain.  Send questions/comments/complaints/performance data
45b1d7137Swdenk   to dl@cs.oswego.edu
55b1d7137Swdenk 
65b1d7137Swdenk * VERSION 2.6.6  Sun Mar  5 19:10:03 2000  Doug Lea  (dl at gee)
75b1d7137Swdenk 
85b1d7137Swdenk    Note: There may be an updated version of this malloc obtainable at
95b1d7137Swdenk 	   ftp://g.oswego.edu/pub/misc/malloc.c
105b1d7137Swdenk 	 Check before installing!
115b1d7137Swdenk 
125b1d7137Swdenk * Why use this malloc?
135b1d7137Swdenk 
145b1d7137Swdenk   This is not the fastest, most space-conserving, most portable, or
155b1d7137Swdenk   most tunable malloc ever written. However it is among the fastest
165b1d7137Swdenk   while also being among the most space-conserving, portable and tunable.
175b1d7137Swdenk   Consistent balance across these factors results in a good general-purpose
185b1d7137Swdenk   allocator. For a high-level description, see
195b1d7137Swdenk      http://g.oswego.edu/dl/html/malloc.html
205b1d7137Swdenk 
215b1d7137Swdenk * Synopsis of public routines
225b1d7137Swdenk 
235b1d7137Swdenk   (Much fuller descriptions are contained in the program documentation below.)
245b1d7137Swdenk 
255b1d7137Swdenk   malloc(size_t n);
265b1d7137Swdenk      Return a pointer to a newly allocated chunk of at least n bytes, or null
275b1d7137Swdenk      if no space is available.
285b1d7137Swdenk   free(Void_t* p);
295b1d7137Swdenk      Release the chunk of memory pointed to by p, or no effect if p is null.
305b1d7137Swdenk   realloc(Void_t* p, size_t n);
315b1d7137Swdenk      Return a pointer to a chunk of size n that contains the same data
325b1d7137Swdenk      as does chunk p up to the minimum of (n, p's size) bytes, or null
335b1d7137Swdenk      if no space is available. The returned pointer may or may not be
345b1d7137Swdenk      the same as p. If p is null, equivalent to malloc.  Unless the
355b1d7137Swdenk      #define REALLOC_ZERO_BYTES_FREES below is set, realloc with a
365b1d7137Swdenk      size argument of zero (re)allocates a minimum-sized chunk.
375b1d7137Swdenk   memalign(size_t alignment, size_t n);
385b1d7137Swdenk      Return a pointer to a newly allocated chunk of n bytes, aligned
395b1d7137Swdenk      in accord with the alignment argument, which must be a power of
405b1d7137Swdenk      two.
415b1d7137Swdenk   valloc(size_t n);
425b1d7137Swdenk      Equivalent to memalign(pagesize, n), where pagesize is the page
435b1d7137Swdenk      size of the system (or as near to this as can be figured out from
445b1d7137Swdenk      all the includes/defines below.)
455b1d7137Swdenk   pvalloc(size_t n);
465b1d7137Swdenk      Equivalent to valloc(minimum-page-that-holds(n)), that is,
475b1d7137Swdenk      round up n to nearest pagesize.
485b1d7137Swdenk   calloc(size_t unit, size_t quantity);
495b1d7137Swdenk      Returns a pointer to quantity * unit bytes, with all locations
505b1d7137Swdenk      set to zero.
515b1d7137Swdenk   cfree(Void_t* p);
525b1d7137Swdenk      Equivalent to free(p).
535b1d7137Swdenk   malloc_trim(size_t pad);
545b1d7137Swdenk      Release all but pad bytes of freed top-most memory back
555b1d7137Swdenk      to the system. Return 1 if successful, else 0.
565b1d7137Swdenk   malloc_usable_size(Void_t* p);
575b1d7137Swdenk      Report the number usable allocated bytes associated with allocated
585b1d7137Swdenk      chunk p. This may or may not report more bytes than were requested,
595b1d7137Swdenk      due to alignment and minimum size constraints.
605b1d7137Swdenk   malloc_stats();
615b1d7137Swdenk      Prints brief summary statistics on stderr.
625b1d7137Swdenk   mallinfo()
635b1d7137Swdenk      Returns (by copy) a struct containing various summary statistics.
645b1d7137Swdenk   mallopt(int parameter_number, int parameter_value)
655b1d7137Swdenk      Changes one of the tunable parameters described below. Returns
665b1d7137Swdenk      1 if successful in changing the parameter, else 0.
675b1d7137Swdenk 
685b1d7137Swdenk * Vital statistics:
695b1d7137Swdenk 
705b1d7137Swdenk   Alignment:                            8-byte
715b1d7137Swdenk        8 byte alignment is currently hardwired into the design.  This
725b1d7137Swdenk        seems to suffice for all current machines and C compilers.
735b1d7137Swdenk 
745b1d7137Swdenk   Assumed pointer representation:       4 or 8 bytes
755b1d7137Swdenk        Code for 8-byte pointers is untested by me but has worked
765b1d7137Swdenk        reliably by Wolfram Gloger, who contributed most of the
775b1d7137Swdenk        changes supporting this.
785b1d7137Swdenk 
795b1d7137Swdenk   Assumed size_t  representation:       4 or 8 bytes
805b1d7137Swdenk        Note that size_t is allowed to be 4 bytes even if pointers are 8.
815b1d7137Swdenk 
825b1d7137Swdenk   Minimum overhead per allocated chunk: 4 or 8 bytes
835b1d7137Swdenk        Each malloced chunk has a hidden overhead of 4 bytes holding size
845b1d7137Swdenk        and status information.
855b1d7137Swdenk 
865b1d7137Swdenk   Minimum allocated size: 4-byte ptrs:  16 bytes    (including 4 overhead)
875b1d7137Swdenk 			  8-byte ptrs:  24/32 bytes (including, 4/8 overhead)
885b1d7137Swdenk 
895b1d7137Swdenk        When a chunk is freed, 12 (for 4byte ptrs) or 20 (for 8 byte
905b1d7137Swdenk        ptrs but 4 byte size) or 24 (for 8/8) additional bytes are
915b1d7137Swdenk        needed; 4 (8) for a trailing size field
925b1d7137Swdenk        and 8 (16) bytes for free list pointers. Thus, the minimum
935b1d7137Swdenk        allocatable size is 16/24/32 bytes.
945b1d7137Swdenk 
955b1d7137Swdenk        Even a request for zero bytes (i.e., malloc(0)) returns a
965b1d7137Swdenk        pointer to something of the minimum allocatable size.
975b1d7137Swdenk 
985b1d7137Swdenk   Maximum allocated size: 4-byte size_t: 2^31 -  8 bytes
995b1d7137Swdenk 			  8-byte size_t: 2^63 - 16 bytes
1005b1d7137Swdenk 
1015b1d7137Swdenk        It is assumed that (possibly signed) size_t bit values suffice to
1025b1d7137Swdenk        represent chunk sizes. `Possibly signed' is due to the fact
1035b1d7137Swdenk        that `size_t' may be defined on a system as either a signed or
1045b1d7137Swdenk        an unsigned type. To be conservative, values that would appear
1055b1d7137Swdenk        as negative numbers are avoided.
1065b1d7137Swdenk        Requests for sizes with a negative sign bit when the request
1075b1d7137Swdenk        size is treaded as a long will return null.
1085b1d7137Swdenk 
1095b1d7137Swdenk   Maximum overhead wastage per allocated chunk: normally 15 bytes
1105b1d7137Swdenk 
1115b1d7137Swdenk        Alignnment demands, plus the minimum allocatable size restriction
1125b1d7137Swdenk        make the normal worst-case wastage 15 bytes (i.e., up to 15
1135b1d7137Swdenk        more bytes will be allocated than were requested in malloc), with
1145b1d7137Swdenk        two exceptions:
1155b1d7137Swdenk 	 1. Because requests for zero bytes allocate non-zero space,
1165b1d7137Swdenk 	    the worst case wastage for a request of zero bytes is 24 bytes.
1175b1d7137Swdenk 	 2. For requests >= mmap_threshold that are serviced via
1185b1d7137Swdenk 	    mmap(), the worst case wastage is 8 bytes plus the remainder
1195b1d7137Swdenk 	    from a system page (the minimal mmap unit); typically 4096 bytes.
1205b1d7137Swdenk 
1215b1d7137Swdenk * Limitations
1225b1d7137Swdenk 
1235b1d7137Swdenk     Here are some features that are NOT currently supported
1245b1d7137Swdenk 
1255b1d7137Swdenk     * No user-definable hooks for callbacks and the like.
1265b1d7137Swdenk     * No automated mechanism for fully checking that all accesses
1275b1d7137Swdenk       to malloced memory stay within their bounds.
1285b1d7137Swdenk     * No support for compaction.
1295b1d7137Swdenk 
1305b1d7137Swdenk * Synopsis of compile-time options:
1315b1d7137Swdenk 
1325b1d7137Swdenk     People have reported using previous versions of this malloc on all
1335b1d7137Swdenk     versions of Unix, sometimes by tweaking some of the defines
1345b1d7137Swdenk     below. It has been tested most extensively on Solaris and
1355b1d7137Swdenk     Linux. It is also reported to work on WIN32 platforms.
1365b1d7137Swdenk     People have also reported adapting this malloc for use in
1375b1d7137Swdenk     stand-alone embedded systems.
1385b1d7137Swdenk 
1395b1d7137Swdenk     The implementation is in straight, hand-tuned ANSI C.  Among other
1405b1d7137Swdenk     consequences, it uses a lot of macros.  Because of this, to be at
1415b1d7137Swdenk     all usable, this code should be compiled using an optimizing compiler
1425b1d7137Swdenk     (for example gcc -O2) that can simplify expressions and control
1435b1d7137Swdenk     paths.
1445b1d7137Swdenk 
1455b1d7137Swdenk   __STD_C                  (default: derived from C compiler defines)
1465b1d7137Swdenk      Nonzero if using ANSI-standard C compiler, a C++ compiler, or
1475b1d7137Swdenk      a C compiler sufficiently close to ANSI to get away with it.
1485b1d7137Swdenk   DEBUG                    (default: NOT defined)
1495b1d7137Swdenk      Define to enable debugging. Adds fairly extensive assertion-based
1505b1d7137Swdenk      checking to help track down memory errors, but noticeably slows down
1515b1d7137Swdenk      execution.
1525b1d7137Swdenk   REALLOC_ZERO_BYTES_FREES (default: NOT defined)
1535b1d7137Swdenk      Define this if you think that realloc(p, 0) should be equivalent
1545b1d7137Swdenk      to free(p). Otherwise, since malloc returns a unique pointer for
1555b1d7137Swdenk      malloc(0), so does realloc(p, 0).
1565b1d7137Swdenk   HAVE_MEMCPY               (default: defined)
1575b1d7137Swdenk      Define if you are not otherwise using ANSI STD C, but still
1585b1d7137Swdenk      have memcpy and memset in your C library and want to use them.
1595b1d7137Swdenk      Otherwise, simple internal versions are supplied.
1605b1d7137Swdenk   USE_MEMCPY               (default: 1 if HAVE_MEMCPY is defined, 0 otherwise)
1615b1d7137Swdenk      Define as 1 if you want the C library versions of memset and
1625b1d7137Swdenk      memcpy called in realloc and calloc (otherwise macro versions are used).
1635b1d7137Swdenk      At least on some platforms, the simple macro versions usually
1645b1d7137Swdenk      outperform libc versions.
1655b1d7137Swdenk   HAVE_MMAP                 (default: defined as 1)
1665b1d7137Swdenk      Define to non-zero to optionally make malloc() use mmap() to
1675b1d7137Swdenk      allocate very large blocks.
1685b1d7137Swdenk   HAVE_MREMAP                 (default: defined as 0 unless Linux libc set)
1695b1d7137Swdenk      Define to non-zero to optionally make realloc() use mremap() to
1705b1d7137Swdenk      reallocate very large blocks.
1715b1d7137Swdenk   malloc_getpagesize        (default: derived from system #includes)
1725b1d7137Swdenk      Either a constant or routine call returning the system page size.
1735b1d7137Swdenk   HAVE_USR_INCLUDE_MALLOC_H (default: NOT defined)
1745b1d7137Swdenk      Optionally define if you are on a system with a /usr/include/malloc.h
1755b1d7137Swdenk      that declares struct mallinfo. It is not at all necessary to
1765b1d7137Swdenk      define this even if you do, but will ensure consistency.
1775b1d7137Swdenk   INTERNAL_SIZE_T           (default: size_t)
1785b1d7137Swdenk      Define to a 32-bit type (probably `unsigned int') if you are on a
1795b1d7137Swdenk      64-bit machine, yet do not want or need to allow malloc requests of
1805b1d7137Swdenk      greater than 2^31 to be handled. This saves space, especially for
1815b1d7137Swdenk      very small chunks.
1825b1d7137Swdenk   INTERNAL_LINUX_C_LIB      (default: NOT defined)
1835b1d7137Swdenk      Defined only when compiled as part of Linux libc.
1845b1d7137Swdenk      Also note that there is some odd internal name-mangling via defines
1855b1d7137Swdenk      (for example, internally, `malloc' is named `mALLOc') needed
1865b1d7137Swdenk      when compiling in this case. These look funny but don't otherwise
1875b1d7137Swdenk      affect anything.
1885b1d7137Swdenk   WIN32                     (default: undefined)
1895b1d7137Swdenk      Define this on MS win (95, nt) platforms to compile in sbrk emulation.
1905b1d7137Swdenk   LACKS_UNISTD_H            (default: undefined if not WIN32)
1915b1d7137Swdenk      Define this if your system does not have a <unistd.h>.
1925b1d7137Swdenk   LACKS_SYS_PARAM_H         (default: undefined if not WIN32)
1935b1d7137Swdenk      Define this if your system does not have a <sys/param.h>.
1945b1d7137Swdenk   MORECORE                  (default: sbrk)
1955b1d7137Swdenk      The name of the routine to call to obtain more memory from the system.
1965b1d7137Swdenk   MORECORE_FAILURE          (default: -1)
1975b1d7137Swdenk      The value returned upon failure of MORECORE.
1985b1d7137Swdenk   MORECORE_CLEARS           (default 1)
199472d5460SYork Sun      true (1) if the routine mapped to MORECORE zeroes out memory (which
2005b1d7137Swdenk      holds for sbrk).
2015b1d7137Swdenk   DEFAULT_TRIM_THRESHOLD
2025b1d7137Swdenk   DEFAULT_TOP_PAD
2035b1d7137Swdenk   DEFAULT_MMAP_THRESHOLD
2045b1d7137Swdenk   DEFAULT_MMAP_MAX
2055b1d7137Swdenk      Default values of tunable parameters (described in detail below)
2065b1d7137Swdenk      controlling interaction with host system routines (sbrk, mmap, etc).
2075b1d7137Swdenk      These values may also be changed dynamically via mallopt(). The
2085b1d7137Swdenk      preset defaults are those that give best performance for typical
2095b1d7137Swdenk      programs/systems.
2105b1d7137Swdenk   USE_DL_PREFIX             (default: undefined)
2115b1d7137Swdenk      Prefix all public routines with the string 'dl'.  Useful to
2125b1d7137Swdenk      quickly avoid procedure declaration conflicts and linker symbol
2135b1d7137Swdenk      conflicts with existing memory allocation routines.
2145b1d7137Swdenk 
2155b1d7137Swdenk 
2165b1d7137Swdenk */
2175b1d7137Swdenk 
2185b1d7137Swdenk 
21960a3f404SJean-Christophe PLAGNIOL-VILLARD #ifndef __MALLOC_H__
22060a3f404SJean-Christophe PLAGNIOL-VILLARD #define __MALLOC_H__
2215b1d7137Swdenk 
2225b1d7137Swdenk /* Preliminaries */
2235b1d7137Swdenk 
2245b1d7137Swdenk #ifndef __STD_C
2255b1d7137Swdenk #ifdef __STDC__
2265b1d7137Swdenk #define __STD_C     1
2275b1d7137Swdenk #else
2285b1d7137Swdenk #if __cplusplus
2295b1d7137Swdenk #define __STD_C     1
2305b1d7137Swdenk #else
2315b1d7137Swdenk #define __STD_C     0
2325b1d7137Swdenk #endif /*__cplusplus*/
2335b1d7137Swdenk #endif /*__STDC__*/
2345b1d7137Swdenk #endif /*__STD_C*/
2355b1d7137Swdenk 
2365b1d7137Swdenk #ifndef Void_t
2375b1d7137Swdenk #if (__STD_C || defined(WIN32))
2385b1d7137Swdenk #define Void_t      void
2395b1d7137Swdenk #else
2405b1d7137Swdenk #define Void_t      char
2415b1d7137Swdenk #endif
2425b1d7137Swdenk #endif /*Void_t*/
2435b1d7137Swdenk 
2445b1d7137Swdenk #if __STD_C
2455b1d7137Swdenk #include <linux/stddef.h>	/* for size_t */
2465b1d7137Swdenk #else
2475b1d7137Swdenk #include <sys/types.h>
2485b1d7137Swdenk #endif	/* __STD_C */
2495b1d7137Swdenk 
2505b1d7137Swdenk #ifdef __cplusplus
2515b1d7137Swdenk extern "C" {
2525b1d7137Swdenk #endif
2535b1d7137Swdenk 
2545b1d7137Swdenk #if 0	/* not for U-Boot */
2555b1d7137Swdenk #include <stdio.h>	/* needed for malloc_stats */
2565b1d7137Swdenk #endif
2575b1d7137Swdenk 
2585b1d7137Swdenk 
2595b1d7137Swdenk /*
2605b1d7137Swdenk   Compile-time options
2615b1d7137Swdenk */
2625b1d7137Swdenk 
2635b1d7137Swdenk 
2645b1d7137Swdenk /*
2655b1d7137Swdenk     Debugging:
2665b1d7137Swdenk 
2675b1d7137Swdenk     Because freed chunks may be overwritten with link fields, this
2685b1d7137Swdenk     malloc will often die when freed memory is overwritten by user
2695b1d7137Swdenk     programs.  This can be very effective (albeit in an annoying way)
2705b1d7137Swdenk     in helping track down dangling pointers.
2715b1d7137Swdenk 
2725b1d7137Swdenk     If you compile with -DDEBUG, a number of assertion checks are
2735b1d7137Swdenk     enabled that will catch more memory errors. You probably won't be
2745b1d7137Swdenk     able to make much sense of the actual assertion errors, but they
2755b1d7137Swdenk     should help you locate incorrectly overwritten memory.  The
2765b1d7137Swdenk     checking is fairly extensive, and will slow down execution
2775b1d7137Swdenk     noticeably. Calling malloc_stats or mallinfo with DEBUG set will
2785b1d7137Swdenk     attempt to check every non-mmapped allocated and free chunk in the
2795b1d7137Swdenk     course of computing the summmaries. (By nature, mmapped regions
2805b1d7137Swdenk     cannot be checked very much automatically.)
2815b1d7137Swdenk 
2825b1d7137Swdenk     Setting DEBUG may also be helpful if you are trying to modify
2835b1d7137Swdenk     this code. The assertions in the check routines spell out in more
2845b1d7137Swdenk     detail the assumptions and invariants underlying the algorithms.
2855b1d7137Swdenk 
2865b1d7137Swdenk */
2875b1d7137Swdenk 
2885b1d7137Swdenk /*
2895b1d7137Swdenk   INTERNAL_SIZE_T is the word-size used for internal bookkeeping
2905b1d7137Swdenk   of chunk sizes. On a 64-bit machine, you can reduce malloc
2915b1d7137Swdenk   overhead by defining INTERNAL_SIZE_T to be a 32 bit `unsigned int'
2925b1d7137Swdenk   at the expense of not being able to handle requests greater than
2935b1d7137Swdenk   2^31. This limitation is hardly ever a concern; you are encouraged
2945b1d7137Swdenk   to set this. However, the default version is the same as size_t.
2955b1d7137Swdenk */
2965b1d7137Swdenk 
2975b1d7137Swdenk #ifndef INTERNAL_SIZE_T
2985b1d7137Swdenk #define INTERNAL_SIZE_T size_t
2995b1d7137Swdenk #endif
3005b1d7137Swdenk 
3015b1d7137Swdenk /*
3025b1d7137Swdenk   REALLOC_ZERO_BYTES_FREES should be set if a call to
3035b1d7137Swdenk   realloc with zero bytes should be the same as a call to free.
3045b1d7137Swdenk   Some people think it should. Otherwise, since this malloc
3055b1d7137Swdenk   returns a unique pointer for malloc(0), so does realloc(p, 0).
3065b1d7137Swdenk */
3075b1d7137Swdenk 
3085b1d7137Swdenk 
3095b1d7137Swdenk /*   #define REALLOC_ZERO_BYTES_FREES */
3105b1d7137Swdenk 
3115b1d7137Swdenk 
3125b1d7137Swdenk /*
3135b1d7137Swdenk   WIN32 causes an emulation of sbrk to be compiled in
3145b1d7137Swdenk   mmap-based options are not currently supported in WIN32.
3155b1d7137Swdenk */
3165b1d7137Swdenk 
3175b1d7137Swdenk /* #define WIN32 */
3185b1d7137Swdenk #ifdef WIN32
3195b1d7137Swdenk #define MORECORE wsbrk
3205b1d7137Swdenk #define HAVE_MMAP 0
3215b1d7137Swdenk 
3225b1d7137Swdenk #define LACKS_UNISTD_H
3235b1d7137Swdenk #define LACKS_SYS_PARAM_H
3245b1d7137Swdenk 
3255b1d7137Swdenk /*
3265b1d7137Swdenk   Include 'windows.h' to get the necessary declarations for the
3275b1d7137Swdenk   Microsoft Visual C++ data structures and routines used in the 'sbrk'
3285b1d7137Swdenk   emulation.
3295b1d7137Swdenk 
3305b1d7137Swdenk   Define WIN32_LEAN_AND_MEAN so that only the essential Microsoft
3315b1d7137Swdenk   Visual C++ header files are included.
3325b1d7137Swdenk */
3335b1d7137Swdenk #define WIN32_LEAN_AND_MEAN
3345b1d7137Swdenk #include <windows.h>
3355b1d7137Swdenk #endif
3365b1d7137Swdenk 
3375b1d7137Swdenk 
3385b1d7137Swdenk /*
3395b1d7137Swdenk   HAVE_MEMCPY should be defined if you are not otherwise using
3405b1d7137Swdenk   ANSI STD C, but still have memcpy and memset in your C library
3415b1d7137Swdenk   and want to use them in calloc and realloc. Otherwise simple
3425b1d7137Swdenk   macro versions are defined here.
3435b1d7137Swdenk 
3445b1d7137Swdenk   USE_MEMCPY should be defined as 1 if you actually want to
3455b1d7137Swdenk   have memset and memcpy called. People report that the macro
3465b1d7137Swdenk   versions are often enough faster than libc versions on many
3475b1d7137Swdenk   systems that it is better to use them.
3485b1d7137Swdenk 
3495b1d7137Swdenk */
3505b1d7137Swdenk 
3515b1d7137Swdenk #define HAVE_MEMCPY
3525b1d7137Swdenk 
3535b1d7137Swdenk #ifndef USE_MEMCPY
3545b1d7137Swdenk #ifdef HAVE_MEMCPY
3555b1d7137Swdenk #define USE_MEMCPY 1
3565b1d7137Swdenk #else
3575b1d7137Swdenk #define USE_MEMCPY 0
3585b1d7137Swdenk #endif
3595b1d7137Swdenk #endif
3605b1d7137Swdenk 
3615b1d7137Swdenk #if (__STD_C || defined(HAVE_MEMCPY))
3625b1d7137Swdenk 
3635b1d7137Swdenk #if __STD_C
3645b1d7137Swdenk void* memset(void*, int, size_t);
3655b1d7137Swdenk void* memcpy(void*, const void*, size_t);
3665b1d7137Swdenk #else
3675b1d7137Swdenk #ifdef WIN32
3688bde7f77Swdenk /* On Win32 platforms, 'memset()' and 'memcpy()' are already declared in */
3698bde7f77Swdenk /* 'windows.h' */
3705b1d7137Swdenk #else
3715b1d7137Swdenk Void_t* memset();
3725b1d7137Swdenk Void_t* memcpy();
3735b1d7137Swdenk #endif
3745b1d7137Swdenk #endif
3755b1d7137Swdenk #endif
3765b1d7137Swdenk 
3775b1d7137Swdenk #if USE_MEMCPY
3785b1d7137Swdenk 
3795b1d7137Swdenk /* The following macros are only invoked with (2n+1)-multiples of
3805b1d7137Swdenk    INTERNAL_SIZE_T units, with a positive integer n. This is exploited
3815b1d7137Swdenk    for fast inline execution when n is small. */
3825b1d7137Swdenk 
3835b1d7137Swdenk #define MALLOC_ZERO(charp, nbytes)                                            \
3845b1d7137Swdenk do {                                                                          \
3855b1d7137Swdenk   INTERNAL_SIZE_T mzsz = (nbytes);                                            \
3865b1d7137Swdenk   if(mzsz <= 9*sizeof(mzsz)) {                                                \
3875b1d7137Swdenk     INTERNAL_SIZE_T* mz = (INTERNAL_SIZE_T*) (charp);                         \
3885b1d7137Swdenk     if(mzsz >= 5*sizeof(mzsz)) {     *mz++ = 0;                               \
3895b1d7137Swdenk 				     *mz++ = 0;                               \
3905b1d7137Swdenk       if(mzsz >= 7*sizeof(mzsz)) {   *mz++ = 0;                               \
3915b1d7137Swdenk 				     *mz++ = 0;                               \
3925b1d7137Swdenk 	if(mzsz >= 9*sizeof(mzsz)) { *mz++ = 0;                               \
3935b1d7137Swdenk 				     *mz++ = 0; }}}                           \
3945b1d7137Swdenk 				     *mz++ = 0;                               \
3955b1d7137Swdenk 				     *mz++ = 0;                               \
3965b1d7137Swdenk 				     *mz   = 0;                               \
3975b1d7137Swdenk   } else memset((charp), 0, mzsz);                                            \
3985b1d7137Swdenk } while(0)
3995b1d7137Swdenk 
4005b1d7137Swdenk #define MALLOC_COPY(dest,src,nbytes)                                          \
4015b1d7137Swdenk do {                                                                          \
4025b1d7137Swdenk   INTERNAL_SIZE_T mcsz = (nbytes);                                            \
4035b1d7137Swdenk   if(mcsz <= 9*sizeof(mcsz)) {                                                \
4045b1d7137Swdenk     INTERNAL_SIZE_T* mcsrc = (INTERNAL_SIZE_T*) (src);                        \
4055b1d7137Swdenk     INTERNAL_SIZE_T* mcdst = (INTERNAL_SIZE_T*) (dest);                       \
4065b1d7137Swdenk     if(mcsz >= 5*sizeof(mcsz)) {     *mcdst++ = *mcsrc++;                     \
4075b1d7137Swdenk 				     *mcdst++ = *mcsrc++;                     \
4085b1d7137Swdenk       if(mcsz >= 7*sizeof(mcsz)) {   *mcdst++ = *mcsrc++;                     \
4095b1d7137Swdenk 				     *mcdst++ = *mcsrc++;                     \
4105b1d7137Swdenk 	if(mcsz >= 9*sizeof(mcsz)) { *mcdst++ = *mcsrc++;                     \
4115b1d7137Swdenk 				     *mcdst++ = *mcsrc++; }}}                 \
4125b1d7137Swdenk 				     *mcdst++ = *mcsrc++;                     \
4135b1d7137Swdenk 				     *mcdst++ = *mcsrc++;                     \
4145b1d7137Swdenk 				     *mcdst   = *mcsrc  ;                     \
4155b1d7137Swdenk   } else memcpy(dest, src, mcsz);                                             \
4165b1d7137Swdenk } while(0)
4175b1d7137Swdenk 
4185b1d7137Swdenk #else /* !USE_MEMCPY */
4195b1d7137Swdenk 
4205b1d7137Swdenk /* Use Duff's device for good zeroing/copying performance. */
4215b1d7137Swdenk 
4225b1d7137Swdenk #define MALLOC_ZERO(charp, nbytes)                                            \
4235b1d7137Swdenk do {                                                                          \
4245b1d7137Swdenk   INTERNAL_SIZE_T* mzp = (INTERNAL_SIZE_T*)(charp);                           \
4255b1d7137Swdenk   long mctmp = (nbytes)/sizeof(INTERNAL_SIZE_T), mcn;                         \
4265b1d7137Swdenk   if (mctmp < 8) mcn = 0; else { mcn = (mctmp-1)/8; mctmp %= 8; }             \
4275b1d7137Swdenk   switch (mctmp) {                                                            \
4285b1d7137Swdenk     case 0: for(;;) { *mzp++ = 0;                                             \
4295b1d7137Swdenk     case 7:           *mzp++ = 0;                                             \
4305b1d7137Swdenk     case 6:           *mzp++ = 0;                                             \
4315b1d7137Swdenk     case 5:           *mzp++ = 0;                                             \
4325b1d7137Swdenk     case 4:           *mzp++ = 0;                                             \
4335b1d7137Swdenk     case 3:           *mzp++ = 0;                                             \
4345b1d7137Swdenk     case 2:           *mzp++ = 0;                                             \
4355b1d7137Swdenk     case 1:           *mzp++ = 0; if(mcn <= 0) break; mcn--; }                \
4365b1d7137Swdenk   }                                                                           \
4375b1d7137Swdenk } while(0)
4385b1d7137Swdenk 
4395b1d7137Swdenk #define MALLOC_COPY(dest,src,nbytes)                                          \
4405b1d7137Swdenk do {                                                                          \
4415b1d7137Swdenk   INTERNAL_SIZE_T* mcsrc = (INTERNAL_SIZE_T*) src;                            \
4425b1d7137Swdenk   INTERNAL_SIZE_T* mcdst = (INTERNAL_SIZE_T*) dest;                           \
4435b1d7137Swdenk   long mctmp = (nbytes)/sizeof(INTERNAL_SIZE_T), mcn;                         \
4445b1d7137Swdenk   if (mctmp < 8) mcn = 0; else { mcn = (mctmp-1)/8; mctmp %= 8; }             \
4455b1d7137Swdenk   switch (mctmp) {                                                            \
4465b1d7137Swdenk     case 0: for(;;) { *mcdst++ = *mcsrc++;                                    \
4475b1d7137Swdenk     case 7:           *mcdst++ = *mcsrc++;                                    \
4485b1d7137Swdenk     case 6:           *mcdst++ = *mcsrc++;                                    \
4495b1d7137Swdenk     case 5:           *mcdst++ = *mcsrc++;                                    \
4505b1d7137Swdenk     case 4:           *mcdst++ = *mcsrc++;                                    \
4515b1d7137Swdenk     case 3:           *mcdst++ = *mcsrc++;                                    \
4525b1d7137Swdenk     case 2:           *mcdst++ = *mcsrc++;                                    \
4535b1d7137Swdenk     case 1:           *mcdst++ = *mcsrc++; if(mcn <= 0) break; mcn--; }       \
4545b1d7137Swdenk   }                                                                           \
4555b1d7137Swdenk } while(0)
4565b1d7137Swdenk 
4575b1d7137Swdenk #endif
4585b1d7137Swdenk 
4595b1d7137Swdenk 
4605b1d7137Swdenk /*
4615b1d7137Swdenk   Define HAVE_MMAP to optionally make malloc() use mmap() to
4625b1d7137Swdenk   allocate very large blocks.  These will be returned to the
4635b1d7137Swdenk   operating system immediately after a free().
4645b1d7137Swdenk */
4655b1d7137Swdenk 
4665b1d7137Swdenk /***
4675b1d7137Swdenk #ifndef HAVE_MMAP
4685b1d7137Swdenk #define HAVE_MMAP 1
4695b1d7137Swdenk #endif
4705b1d7137Swdenk ***/
4715b1d7137Swdenk #undef	HAVE_MMAP	/* Not available for U-Boot */
4725b1d7137Swdenk 
4735b1d7137Swdenk /*
4745b1d7137Swdenk   Define HAVE_MREMAP to make realloc() use mremap() to re-allocate
4755b1d7137Swdenk   large blocks.  This is currently only possible on Linux with
4765b1d7137Swdenk   kernel versions newer than 1.3.77.
4775b1d7137Swdenk */
4785b1d7137Swdenk 
4795b1d7137Swdenk /***
4805b1d7137Swdenk #ifndef HAVE_MREMAP
4815b1d7137Swdenk #ifdef INTERNAL_LINUX_C_LIB
4825b1d7137Swdenk #define HAVE_MREMAP 1
4835b1d7137Swdenk #else
4845b1d7137Swdenk #define HAVE_MREMAP 0
4855b1d7137Swdenk #endif
4865b1d7137Swdenk #endif
4875b1d7137Swdenk ***/
4885b1d7137Swdenk #undef	HAVE_MREMAP	/* Not available for U-Boot */
4895b1d7137Swdenk 
490213adf6dSMarek Vasut #ifdef HAVE_MMAP
4915b1d7137Swdenk 
4925b1d7137Swdenk #include <unistd.h>
4935b1d7137Swdenk #include <fcntl.h>
4945b1d7137Swdenk #include <sys/mman.h>
4955b1d7137Swdenk 
4965b1d7137Swdenk #if !defined(MAP_ANONYMOUS) && defined(MAP_ANON)
4975b1d7137Swdenk #define MAP_ANONYMOUS MAP_ANON
4985b1d7137Swdenk #endif
4995b1d7137Swdenk 
5005b1d7137Swdenk #endif /* HAVE_MMAP */
5015b1d7137Swdenk 
5025b1d7137Swdenk /*
5035b1d7137Swdenk   Access to system page size. To the extent possible, this malloc
5045b1d7137Swdenk   manages memory from the system in page-size units.
5055b1d7137Swdenk 
5065b1d7137Swdenk   The following mechanics for getpagesize were adapted from
5075b1d7137Swdenk   bsd/gnu getpagesize.h
5085b1d7137Swdenk */
5095b1d7137Swdenk 
5105b1d7137Swdenk #define	LACKS_UNISTD_H	/* Shortcut for U-Boot */
5115b1d7137Swdenk #define	malloc_getpagesize	4096
5125b1d7137Swdenk 
5135b1d7137Swdenk #ifndef LACKS_UNISTD_H
5145b1d7137Swdenk #  include <unistd.h>
5155b1d7137Swdenk #endif
5165b1d7137Swdenk 
5175b1d7137Swdenk #ifndef malloc_getpagesize
5185b1d7137Swdenk #  ifdef _SC_PAGESIZE         /* some SVR4 systems omit an underscore */
5195b1d7137Swdenk #    ifndef _SC_PAGE_SIZE
5205b1d7137Swdenk #      define _SC_PAGE_SIZE _SC_PAGESIZE
5215b1d7137Swdenk #    endif
5225b1d7137Swdenk #  endif
5235b1d7137Swdenk #  ifdef _SC_PAGE_SIZE
5245b1d7137Swdenk #    define malloc_getpagesize sysconf(_SC_PAGE_SIZE)
5255b1d7137Swdenk #  else
5265b1d7137Swdenk #    if defined(BSD) || defined(DGUX) || defined(HAVE_GETPAGESIZE)
5275b1d7137Swdenk        extern size_t getpagesize();
5285b1d7137Swdenk #      define malloc_getpagesize getpagesize()
5295b1d7137Swdenk #    else
5305b1d7137Swdenk #      ifdef WIN32
5315b1d7137Swdenk #        define malloc_getpagesize (4096) /* TBD: Use 'GetSystemInfo' instead */
5325b1d7137Swdenk #      else
5335b1d7137Swdenk #        ifndef LACKS_SYS_PARAM_H
5345b1d7137Swdenk #          include <sys/param.h>
5355b1d7137Swdenk #        endif
5365b1d7137Swdenk #        ifdef EXEC_PAGESIZE
5375b1d7137Swdenk #          define malloc_getpagesize EXEC_PAGESIZE
5385b1d7137Swdenk #        else
5395b1d7137Swdenk #          ifdef NBPG
5405b1d7137Swdenk #            ifndef CLSIZE
5415b1d7137Swdenk #              define malloc_getpagesize NBPG
5425b1d7137Swdenk #            else
5435b1d7137Swdenk #              define malloc_getpagesize (NBPG * CLSIZE)
5445b1d7137Swdenk #            endif
5455b1d7137Swdenk #          else
5465b1d7137Swdenk #            ifdef NBPC
5475b1d7137Swdenk #              define malloc_getpagesize NBPC
5485b1d7137Swdenk #            else
5495b1d7137Swdenk #              ifdef PAGESIZE
5505b1d7137Swdenk #                define malloc_getpagesize PAGESIZE
5515b1d7137Swdenk #              else
5525b1d7137Swdenk #                define malloc_getpagesize (4096) /* just guess */
5535b1d7137Swdenk #              endif
5545b1d7137Swdenk #            endif
5555b1d7137Swdenk #          endif
5565b1d7137Swdenk #        endif
5575b1d7137Swdenk #      endif
5585b1d7137Swdenk #    endif
5595b1d7137Swdenk #  endif
5605b1d7137Swdenk #endif
5615b1d7137Swdenk 
5625b1d7137Swdenk 
5635b1d7137Swdenk /*
5645b1d7137Swdenk 
5655b1d7137Swdenk   This version of malloc supports the standard SVID/XPG mallinfo
5665b1d7137Swdenk   routine that returns a struct containing the same kind of
5675b1d7137Swdenk   information you can get from malloc_stats. It should work on
5685b1d7137Swdenk   any SVID/XPG compliant system that has a /usr/include/malloc.h
5695b1d7137Swdenk   defining struct mallinfo. (If you'd like to install such a thing
5705b1d7137Swdenk   yourself, cut out the preliminary declarations as described above
5715b1d7137Swdenk   and below and save them in a malloc.h file. But there's no
5725b1d7137Swdenk   compelling reason to bother to do this.)
5735b1d7137Swdenk 
5745b1d7137Swdenk   The main declaration needed is the mallinfo struct that is returned
5755b1d7137Swdenk   (by-copy) by mallinfo().  The SVID/XPG malloinfo struct contains a
5765b1d7137Swdenk   bunch of fields, most of which are not even meaningful in this
5775b1d7137Swdenk   version of malloc. Some of these fields are are instead filled by
5785b1d7137Swdenk   mallinfo() with other numbers that might possibly be of interest.
5795b1d7137Swdenk 
5805b1d7137Swdenk   HAVE_USR_INCLUDE_MALLOC_H should be set if you have a
5815b1d7137Swdenk   /usr/include/malloc.h file that includes a declaration of struct
5825b1d7137Swdenk   mallinfo.  If so, it is included; else an SVID2/XPG2 compliant
5835b1d7137Swdenk   version is declared below.  These must be precisely the same for
5845b1d7137Swdenk   mallinfo() to work.
5855b1d7137Swdenk 
5865b1d7137Swdenk */
5875b1d7137Swdenk 
5885b1d7137Swdenk /* #define HAVE_USR_INCLUDE_MALLOC_H */
5895b1d7137Swdenk 
590213adf6dSMarek Vasut #ifdef HAVE_USR_INCLUDE_MALLOC_H
5915b1d7137Swdenk #include "/usr/include/malloc.h"
5925b1d7137Swdenk #else
5935b1d7137Swdenk 
5945b1d7137Swdenk /* SVID2/XPG mallinfo structure */
5955b1d7137Swdenk 
5965b1d7137Swdenk struct mallinfo {
5975b1d7137Swdenk   int arena;    /* total space allocated from system */
5985b1d7137Swdenk   int ordblks;  /* number of non-inuse chunks */
5995b1d7137Swdenk   int smblks;   /* unused -- always zero */
6005b1d7137Swdenk   int hblks;    /* number of mmapped regions */
6015b1d7137Swdenk   int hblkhd;   /* total space in mmapped regions */
6025b1d7137Swdenk   int usmblks;  /* unused -- always zero */
6035b1d7137Swdenk   int fsmblks;  /* unused -- always zero */
6045b1d7137Swdenk   int uordblks; /* total allocated space */
6055b1d7137Swdenk   int fordblks; /* total non-inuse space */
6065b1d7137Swdenk   int keepcost; /* top-most, releasable (via malloc_trim) space */
6075b1d7137Swdenk };
6085b1d7137Swdenk 
6095b1d7137Swdenk /* SVID2/XPG mallopt options */
6105b1d7137Swdenk 
6115b1d7137Swdenk #define M_MXFAST  1    /* UNUSED in this malloc */
6125b1d7137Swdenk #define M_NLBLKS  2    /* UNUSED in this malloc */
6135b1d7137Swdenk #define M_GRAIN   3    /* UNUSED in this malloc */
6145b1d7137Swdenk #define M_KEEP    4    /* UNUSED in this malloc */
6155b1d7137Swdenk 
6165b1d7137Swdenk #endif
6175b1d7137Swdenk 
6185b1d7137Swdenk /* mallopt options that actually do something */
6195b1d7137Swdenk 
6205b1d7137Swdenk #define M_TRIM_THRESHOLD    -1
6215b1d7137Swdenk #define M_TOP_PAD           -2
6225b1d7137Swdenk #define M_MMAP_THRESHOLD    -3
6235b1d7137Swdenk #define M_MMAP_MAX          -4
6245b1d7137Swdenk 
6255b1d7137Swdenk 
6265b1d7137Swdenk #ifndef DEFAULT_TRIM_THRESHOLD
6275b1d7137Swdenk #define DEFAULT_TRIM_THRESHOLD (128 * 1024)
6285b1d7137Swdenk #endif
6295b1d7137Swdenk 
6305b1d7137Swdenk /*
6315b1d7137Swdenk     M_TRIM_THRESHOLD is the maximum amount of unused top-most memory
6325b1d7137Swdenk       to keep before releasing via malloc_trim in free().
6335b1d7137Swdenk 
6345b1d7137Swdenk       Automatic trimming is mainly useful in long-lived programs.
6355b1d7137Swdenk       Because trimming via sbrk can be slow on some systems, and can
6365b1d7137Swdenk       sometimes be wasteful (in cases where programs immediately
6375b1d7137Swdenk       afterward allocate more large chunks) the value should be high
6385b1d7137Swdenk       enough so that your overall system performance would improve by
6395b1d7137Swdenk       releasing.
6405b1d7137Swdenk 
6415b1d7137Swdenk       The trim threshold and the mmap control parameters (see below)
6425b1d7137Swdenk       can be traded off with one another. Trimming and mmapping are
6435b1d7137Swdenk       two different ways of releasing unused memory back to the
6445b1d7137Swdenk       system. Between these two, it is often possible to keep
6455b1d7137Swdenk       system-level demands of a long-lived program down to a bare
6465b1d7137Swdenk       minimum. For example, in one test suite of sessions measuring
6475b1d7137Swdenk       the XF86 X server on Linux, using a trim threshold of 128K and a
6485b1d7137Swdenk       mmap threshold of 192K led to near-minimal long term resource
6495b1d7137Swdenk       consumption.
6505b1d7137Swdenk 
6515b1d7137Swdenk       If you are using this malloc in a long-lived program, it should
6525b1d7137Swdenk       pay to experiment with these values.  As a rough guide, you
6535b1d7137Swdenk       might set to a value close to the average size of a process
6545b1d7137Swdenk       (program) running on your system.  Releasing this much memory
6555b1d7137Swdenk       would allow such a process to run in memory.  Generally, it's
6565b1d7137Swdenk       worth it to tune for trimming rather tham memory mapping when a
6575b1d7137Swdenk       program undergoes phases where several large chunks are
6585b1d7137Swdenk       allocated and released in ways that can reuse each other's
6595b1d7137Swdenk       storage, perhaps mixed with phases where there are no such
6605b1d7137Swdenk       chunks at all.  And in well-behaved long-lived programs,
6615b1d7137Swdenk       controlling release of large blocks via trimming versus mapping
6625b1d7137Swdenk       is usually faster.
6635b1d7137Swdenk 
6645b1d7137Swdenk       However, in most programs, these parameters serve mainly as
6655b1d7137Swdenk       protection against the system-level effects of carrying around
6665b1d7137Swdenk       massive amounts of unneeded memory. Since frequent calls to
6675b1d7137Swdenk       sbrk, mmap, and munmap otherwise degrade performance, the default
6685b1d7137Swdenk       parameters are set to relatively high values that serve only as
6695b1d7137Swdenk       safeguards.
6705b1d7137Swdenk 
6715b1d7137Swdenk       The default trim value is high enough to cause trimming only in
6725b1d7137Swdenk       fairly extreme (by current memory consumption standards) cases.
6735b1d7137Swdenk       It must be greater than page size to have any useful effect.  To
6745b1d7137Swdenk       disable trimming completely, you can set to (unsigned long)(-1);
6755b1d7137Swdenk 
6765b1d7137Swdenk 
6775b1d7137Swdenk */
6785b1d7137Swdenk 
6795b1d7137Swdenk 
6805b1d7137Swdenk #ifndef DEFAULT_TOP_PAD
6815b1d7137Swdenk #define DEFAULT_TOP_PAD        (0)
6825b1d7137Swdenk #endif
6835b1d7137Swdenk 
6845b1d7137Swdenk /*
6855b1d7137Swdenk     M_TOP_PAD is the amount of extra `padding' space to allocate or
6865b1d7137Swdenk       retain whenever sbrk is called. It is used in two ways internally:
6875b1d7137Swdenk 
6885b1d7137Swdenk       * When sbrk is called to extend the top of the arena to satisfy
6895b1d7137Swdenk 	a new malloc request, this much padding is added to the sbrk
6905b1d7137Swdenk 	request.
6915b1d7137Swdenk 
6925b1d7137Swdenk       * When malloc_trim is called automatically from free(),
6935b1d7137Swdenk 	it is used as the `pad' argument.
6945b1d7137Swdenk 
6955b1d7137Swdenk       In both cases, the actual amount of padding is rounded
6965b1d7137Swdenk       so that the end of the arena is always a system page boundary.
6975b1d7137Swdenk 
6985b1d7137Swdenk       The main reason for using padding is to avoid calling sbrk so
6995b1d7137Swdenk       often. Having even a small pad greatly reduces the likelihood
7005b1d7137Swdenk       that nearly every malloc request during program start-up (or
7015b1d7137Swdenk       after trimming) will invoke sbrk, which needlessly wastes
7025b1d7137Swdenk       time.
7035b1d7137Swdenk 
7045b1d7137Swdenk       Automatic rounding-up to page-size units is normally sufficient
7055b1d7137Swdenk       to avoid measurable overhead, so the default is 0.  However, in
7065b1d7137Swdenk       systems where sbrk is relatively slow, it can pay to increase
7075b1d7137Swdenk       this value, at the expense of carrying around more memory than
7085b1d7137Swdenk       the program needs.
7095b1d7137Swdenk 
7105b1d7137Swdenk */
7115b1d7137Swdenk 
7125b1d7137Swdenk 
7135b1d7137Swdenk #ifndef DEFAULT_MMAP_THRESHOLD
7145b1d7137Swdenk #define DEFAULT_MMAP_THRESHOLD (128 * 1024)
7155b1d7137Swdenk #endif
7165b1d7137Swdenk 
7175b1d7137Swdenk /*
7185b1d7137Swdenk 
7195b1d7137Swdenk     M_MMAP_THRESHOLD is the request size threshold for using mmap()
7205b1d7137Swdenk       to service a request. Requests of at least this size that cannot
7215b1d7137Swdenk       be allocated using already-existing space will be serviced via mmap.
7225b1d7137Swdenk       (If enough normal freed space already exists it is used instead.)
7235b1d7137Swdenk 
7245b1d7137Swdenk       Using mmap segregates relatively large chunks of memory so that
7255b1d7137Swdenk       they can be individually obtained and released from the host
7265b1d7137Swdenk       system. A request serviced through mmap is never reused by any
7275b1d7137Swdenk       other request (at least not directly; the system may just so
7285b1d7137Swdenk       happen to remap successive requests to the same locations).
7295b1d7137Swdenk 
7305b1d7137Swdenk       Segregating space in this way has the benefit that mmapped space
7315b1d7137Swdenk       can ALWAYS be individually released back to the system, which
7325b1d7137Swdenk       helps keep the system level memory demands of a long-lived
7335b1d7137Swdenk       program low. Mapped memory can never become `locked' between
7345b1d7137Swdenk       other chunks, as can happen with normally allocated chunks, which
7355b1d7137Swdenk       menas that even trimming via malloc_trim would not release them.
7365b1d7137Swdenk 
7375b1d7137Swdenk       However, it has the disadvantages that:
7385b1d7137Swdenk 
7395b1d7137Swdenk 	 1. The space cannot be reclaimed, consolidated, and then
7405b1d7137Swdenk 	    used to service later requests, as happens with normal chunks.
7415b1d7137Swdenk 	 2. It can lead to more wastage because of mmap page alignment
7425b1d7137Swdenk 	    requirements
7435b1d7137Swdenk 	 3. It causes malloc performance to be more dependent on host
7445b1d7137Swdenk 	    system memory management support routines which may vary in
7455b1d7137Swdenk 	    implementation quality and may impose arbitrary
7465b1d7137Swdenk 	    limitations. Generally, servicing a request via normal
7475b1d7137Swdenk 	    malloc steps is faster than going through a system's mmap.
7485b1d7137Swdenk 
7495b1d7137Swdenk       All together, these considerations should lead you to use mmap
7505b1d7137Swdenk       only for relatively large requests.
7515b1d7137Swdenk 
7525b1d7137Swdenk 
7535b1d7137Swdenk */
7545b1d7137Swdenk 
7555b1d7137Swdenk 
7565b1d7137Swdenk #ifndef DEFAULT_MMAP_MAX
757213adf6dSMarek Vasut #ifdef HAVE_MMAP
7585b1d7137Swdenk #define DEFAULT_MMAP_MAX       (64)
7595b1d7137Swdenk #else
7605b1d7137Swdenk #define DEFAULT_MMAP_MAX       (0)
7615b1d7137Swdenk #endif
7625b1d7137Swdenk #endif
7635b1d7137Swdenk 
7645b1d7137Swdenk /*
7655b1d7137Swdenk     M_MMAP_MAX is the maximum number of requests to simultaneously
7665b1d7137Swdenk       service using mmap. This parameter exists because:
7675b1d7137Swdenk 
7685b1d7137Swdenk 	 1. Some systems have a limited number of internal tables for
7695b1d7137Swdenk 	    use by mmap.
7705b1d7137Swdenk 	 2. In most systems, overreliance on mmap can degrade overall
7715b1d7137Swdenk 	    performance.
7725b1d7137Swdenk 	 3. If a program allocates many large regions, it is probably
7735b1d7137Swdenk 	    better off using normal sbrk-based allocation routines that
7745b1d7137Swdenk 	    can reclaim and reallocate normal heap memory. Using a
7755b1d7137Swdenk 	    small value allows transition into this mode after the
7765b1d7137Swdenk 	    first few allocations.
7775b1d7137Swdenk 
7785b1d7137Swdenk       Setting to 0 disables all use of mmap.  If HAVE_MMAP is not set,
7795b1d7137Swdenk       the default value is 0, and attempts to set it to non-zero values
7805b1d7137Swdenk       in mallopt will fail.
7815b1d7137Swdenk */
7825b1d7137Swdenk 
7835b1d7137Swdenk 
7845b1d7137Swdenk /*
7855b1d7137Swdenk     USE_DL_PREFIX will prefix all public routines with the string 'dl'.
7865b1d7137Swdenk       Useful to quickly avoid procedure declaration conflicts and linker
7875b1d7137Swdenk       symbol conflicts with existing memory allocation routines.
7885b1d7137Swdenk 
7895b1d7137Swdenk */
7905b1d7137Swdenk 
7915b1d7137Swdenk /* #define USE_DL_PREFIX */
7925b1d7137Swdenk 
7935b1d7137Swdenk 
7945b1d7137Swdenk /*
7955b1d7137Swdenk 
7965b1d7137Swdenk   Special defines for linux libc
7975b1d7137Swdenk 
7985b1d7137Swdenk   Except when compiled using these special defines for Linux libc
7995b1d7137Swdenk   using weak aliases, this malloc is NOT designed to work in
8005b1d7137Swdenk   multithreaded applications.  No semaphores or other concurrency
8015b1d7137Swdenk   control are provided to ensure that multiple malloc or free calls
8025b1d7137Swdenk   don't run at the same time, which could be disasterous. A single
8035b1d7137Swdenk   semaphore could be used across malloc, realloc, and free (which is
8045b1d7137Swdenk   essentially the effect of the linux weak alias approach). It would
8055b1d7137Swdenk   be hard to obtain finer granularity.
8065b1d7137Swdenk 
8075b1d7137Swdenk */
8085b1d7137Swdenk 
8095b1d7137Swdenk 
8105b1d7137Swdenk #ifdef INTERNAL_LINUX_C_LIB
8115b1d7137Swdenk 
8125b1d7137Swdenk #if __STD_C
8135b1d7137Swdenk 
8145b1d7137Swdenk Void_t * __default_morecore_init (ptrdiff_t);
8155b1d7137Swdenk Void_t *(*__morecore)(ptrdiff_t) = __default_morecore_init;
8165b1d7137Swdenk 
8175b1d7137Swdenk #else
8185b1d7137Swdenk 
8195b1d7137Swdenk Void_t * __default_morecore_init ();
8205b1d7137Swdenk Void_t *(*__morecore)() = __default_morecore_init;
8215b1d7137Swdenk 
8225b1d7137Swdenk #endif
8235b1d7137Swdenk 
8245b1d7137Swdenk #define MORECORE (*__morecore)
8255b1d7137Swdenk #define MORECORE_FAILURE 0
8265b1d7137Swdenk #define MORECORE_CLEARS 1
8275b1d7137Swdenk 
8285b1d7137Swdenk #else /* INTERNAL_LINUX_C_LIB */
8295b1d7137Swdenk 
8305b1d7137Swdenk #if __STD_C
8315b1d7137Swdenk extern Void_t*     sbrk(ptrdiff_t);
8325b1d7137Swdenk #else
8335b1d7137Swdenk extern Void_t*     sbrk();
8345b1d7137Swdenk #endif
8355b1d7137Swdenk 
8365b1d7137Swdenk #ifndef MORECORE
8375b1d7137Swdenk #define MORECORE sbrk
8385b1d7137Swdenk #endif
8395b1d7137Swdenk 
8405b1d7137Swdenk #ifndef MORECORE_FAILURE
8415b1d7137Swdenk #define MORECORE_FAILURE -1
8425b1d7137Swdenk #endif
8435b1d7137Swdenk 
8445b1d7137Swdenk #ifndef MORECORE_CLEARS
8455b1d7137Swdenk #define MORECORE_CLEARS 1
8465b1d7137Swdenk #endif
8475b1d7137Swdenk 
8485b1d7137Swdenk #endif /* INTERNAL_LINUX_C_LIB */
8495b1d7137Swdenk 
8505b1d7137Swdenk #if defined(INTERNAL_LINUX_C_LIB) && defined(__ELF__)
8515b1d7137Swdenk 
8525b1d7137Swdenk #define cALLOc		__libc_calloc
8535b1d7137Swdenk #define fREe		__libc_free
8545b1d7137Swdenk #define mALLOc		__libc_malloc
8555b1d7137Swdenk #define mEMALIGn	__libc_memalign
8565b1d7137Swdenk #define rEALLOc		__libc_realloc
8575b1d7137Swdenk #define vALLOc		__libc_valloc
8585b1d7137Swdenk #define pvALLOc		__libc_pvalloc
8595b1d7137Swdenk #define mALLINFo	__libc_mallinfo
8605b1d7137Swdenk #define mALLOPt		__libc_mallopt
8615b1d7137Swdenk 
8625b1d7137Swdenk #pragma weak calloc = __libc_calloc
8635b1d7137Swdenk #pragma weak free = __libc_free
8645b1d7137Swdenk #pragma weak cfree = __libc_free
8655b1d7137Swdenk #pragma weak malloc = __libc_malloc
8665b1d7137Swdenk #pragma weak memalign = __libc_memalign
8675b1d7137Swdenk #pragma weak realloc = __libc_realloc
8685b1d7137Swdenk #pragma weak valloc = __libc_valloc
8695b1d7137Swdenk #pragma weak pvalloc = __libc_pvalloc
8705b1d7137Swdenk #pragma weak mallinfo = __libc_mallinfo
8715b1d7137Swdenk #pragma weak mallopt = __libc_mallopt
8725b1d7137Swdenk 
8735b1d7137Swdenk #else
8745b1d7137Swdenk 
8751eb0c03cSHans de Goede #if CONFIG_IS_ENABLED(SYS_MALLOC_SIMPLE)
876c9356be3SSimon Glass #define malloc malloc_simple
877c9356be3SSimon Glass #define realloc realloc_simple
878c9356be3SSimon Glass #define memalign memalign_simple
free(void * ptr)879c9356be3SSimon Glass static inline void free(void *ptr) {}
880c9356be3SSimon Glass void *calloc(size_t nmemb, size_t size);
881c9356be3SSimon Glass void *memalign_simple(size_t alignment, size_t bytes);
882c9356be3SSimon Glass void *realloc_simple(void *ptr, size_t size);
883*7cbd2d2eSSimon Glass void malloc_simple_info(void);
884c9356be3SSimon Glass #else
885c9356be3SSimon Glass 
8865b1d7137Swdenk # ifdef USE_DL_PREFIX
8875b1d7137Swdenk # define cALLOc		dlcalloc
8885b1d7137Swdenk # define fREe		dlfree
8895b1d7137Swdenk # define mALLOc		dlmalloc
8905b1d7137Swdenk # define mEMALIGn	dlmemalign
8915b1d7137Swdenk # define rEALLOc		dlrealloc
8925b1d7137Swdenk # define vALLOc		dlvalloc
8935b1d7137Swdenk # define pvALLOc		dlpvalloc
8945b1d7137Swdenk # define mALLINFo	dlmallinfo
8955b1d7137Swdenk # define mALLOPt		dlmallopt
8965b1d7137Swdenk # else /* USE_DL_PREFIX */
8975b1d7137Swdenk # define cALLOc		calloc
8985b1d7137Swdenk # define fREe		free
8995b1d7137Swdenk # define mALLOc		malloc
9005b1d7137Swdenk # define mEMALIGn	memalign
9015b1d7137Swdenk # define rEALLOc		realloc
9025b1d7137Swdenk # define vALLOc		valloc
9035b1d7137Swdenk # define pvALLOc		pvalloc
9045b1d7137Swdenk # define mALLINFo	mallinfo
9055b1d7137Swdenk # define mALLOPt		mallopt
9065b1d7137Swdenk # endif /* USE_DL_PREFIX */
9075b1d7137Swdenk 
9085b1d7137Swdenk #endif
9095b1d7137Swdenk 
910fb5cf7f1SSimon Glass /* Set up pre-relocation malloc() ready for use */
911fb5cf7f1SSimon Glass int initf_malloc(void);
912fb5cf7f1SSimon Glass 
9135b1d7137Swdenk /* Public routines */
9145b1d7137Swdenk 
915c9356be3SSimon Glass /* Simple versions which can be used when space is tight */
916c9356be3SSimon Glass void *malloc_simple(size_t size);
917c9356be3SSimon Glass 
9182f0bcd4dSStephen Warren #pragma GCC visibility push(hidden)
9195b1d7137Swdenk # if __STD_C
9205b1d7137Swdenk 
9215b1d7137Swdenk Void_t* mALLOc(size_t);
9225b1d7137Swdenk void    fREe(Void_t*);
9235b1d7137Swdenk Void_t* rEALLOc(Void_t*, size_t);
9245b1d7137Swdenk Void_t* mEMALIGn(size_t, size_t);
9255b1d7137Swdenk Void_t* vALLOc(size_t);
9265b1d7137Swdenk Void_t* pvALLOc(size_t);
9275b1d7137Swdenk Void_t* cALLOc(size_t, size_t);
9285b1d7137Swdenk void    cfree(Void_t*);
9295b1d7137Swdenk int     malloc_trim(size_t);
9305b1d7137Swdenk size_t  malloc_usable_size(Void_t*);
9315b1d7137Swdenk void    malloc_stats(void);
9325b1d7137Swdenk int     mALLOPt(int, int);
9335b1d7137Swdenk struct mallinfo mALLINFo(void);
9345b1d7137Swdenk # else
9355b1d7137Swdenk Void_t* mALLOc();
9365b1d7137Swdenk void    fREe();
9375b1d7137Swdenk Void_t* rEALLOc();
9385b1d7137Swdenk Void_t* mEMALIGn();
9395b1d7137Swdenk Void_t* vALLOc();
9405b1d7137Swdenk Void_t* pvALLOc();
9415b1d7137Swdenk Void_t* cALLOc();
9425b1d7137Swdenk void    cfree();
9435b1d7137Swdenk int     malloc_trim();
9445b1d7137Swdenk size_t  malloc_usable_size();
9455b1d7137Swdenk void    malloc_stats();
9465b1d7137Swdenk int     mALLOPt();
9475b1d7137Swdenk struct mallinfo mALLINFo();
9485b1d7137Swdenk # endif
949c9356be3SSimon Glass #endif
9502f0bcd4dSStephen Warren #pragma GCC visibility pop
9515b1d7137Swdenk 
9525e93bd1cSPeter Tyser /*
9535e93bd1cSPeter Tyser  * Begin and End of memory area for malloc(), and current "brk"
9545e93bd1cSPeter Tyser  */
9555e93bd1cSPeter Tyser extern ulong mem_malloc_start;
9565e93bd1cSPeter Tyser extern ulong mem_malloc_end;
9575e93bd1cSPeter Tyser extern ulong mem_malloc_brk;
9585b1d7137Swdenk 
959d4e8ada0SPeter Tyser void mem_malloc_init(ulong start, ulong size);
960d4e8ada0SPeter Tyser 
9615b1d7137Swdenk #ifdef __cplusplus
9625b1d7137Swdenk };  /* end of extern "C" */
9635b1d7137Swdenk #endif
96460a3f404SJean-Christophe PLAGNIOL-VILLARD 
96560a3f404SJean-Christophe PLAGNIOL-VILLARD #endif /* __MALLOC_H__ */
966