1 /* nedalloc, an alternative malloc implementation for multiple threads without
 
   2 lock contention based on dlmalloc v2.8.3. (C) 2005 Niall Douglas
 
   4 Boost Software License - Version 1.0 - August 17th, 2003
 
   6 Permission is hereby granted, free of charge, to any person or organization
 
   7 obtaining a copy of the software and accompanying documentation covered by
 
   8 this license (the "Software") to use, reproduce, display, distribute,
 
   9 execute, and transmit the Software, and to prepare derivative works of the
 
  10 Software, and to permit third-parties to whom the Software is furnished to
 
  11 do so, all subject to the following:
 
  13 The copyright notices in the Software and this entire statement, including
 
  14 the above license grant, this restriction and the following disclaimer,
 
  15 must be included in all copies of the Software, in whole or in part, and
 
  16 all derivative works of the Software, unless such copies or derivative
 
  17 works are solely in the form of machine-executable object code generated by
 
  18 a source language processor.
 
  20 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 
  21 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
  22 FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
 
  23 SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
 
  24 FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
 
  25 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 
  26 DEALINGS IN THE SOFTWARE.
 
  33 /* See malloc.c.h for what each function does.
 
  35 REPLACE_SYSTEM_ALLOCATOR causes nedalloc's functions to be called malloc,
 
  36 free etc. instead of nedmalloc, nedfree etc. You may or may not want this.
 
  38 NO_NED_NAMESPACE prevents the functions from being defined in the nedalloc
 
  39 namespace when in C++ (uses the global namespace instead).
 
  41 EXTSPEC can be defined to be __declspec(dllexport) or
 
  42 __attribute__ ((visibility("default"))) or whatever you like. It defaults
 
  45 USE_LOCKS can be 2 if you want to define your own MLOCK_T, INITIAL_LOCK,
 
  46 ACQUIRE_LOCK, RELEASE_LOCK, TRY_LOCK, IS_LOCKED and NULL_LOCK_INITIALIZER.
 
  50 #include <stddef.h>   /* for size_t */
 
  53  #define EXTSPEC extern
 
  56 #if defined(_MSC_VER) && _MSC_VER>=1400
 
  57  #define MALLOCATTR __declspec(restrict)
 
  60  #define MALLOCATTR __attribute__ ((malloc))
 
  66 #ifdef REPLACE_SYSTEM_ALLOCATOR
 
  67  #define nedmalloc               malloc
 
  68  #define nedcalloc               calloc
 
  69  #define nedrealloc              realloc
 
  71  #define nedmemalign             memalign
 
  72  #define nedmallinfo             mallinfo
 
  73  #define nedmallopt              mallopt
 
  74  #define nedmalloc_trim          malloc_trim
 
  75  #define nedmalloc_stats         malloc_stats
 
  76  #define nedmalloc_footprint     malloc_footprint
 
  77  #define nedindependent_calloc   independent_calloc
 
  78  #define nedindependent_comalloc independent_comalloc
 
  80   #define nedblksize              _msize
 
  92 #if defined(__cplusplus)
 
  93  #if !defined(NO_NED_NAMESPACE)
 
  98  #define THROWSPEC throw()
 
 103 /* These are the global functions */
 
 105 /* Gets the usable size of an allocated block. Note this will always be bigger than what was
 
 106 asked for due to rounding etc.
 
 108 EXTSPEC size_t nedblksize(void *mem) THROWSPEC;
 
 110 EXTSPEC void nedsetvalue(void *v) THROWSPEC;
 
 112 EXTSPEC MALLOCATTR void * nedmalloc(size_t size) THROWSPEC;
 
 113 EXTSPEC MALLOCATTR void * nedcalloc(size_t no, size_t size) THROWSPEC;
 
 114 EXTSPEC MALLOCATTR void * nedrealloc(void *mem, size_t size) THROWSPEC;
 
 115 EXTSPEC void   nedfree(void *mem) THROWSPEC;
 
 116 EXTSPEC MALLOCATTR void * nedmemalign(size_t alignment, size_t bytes) THROWSPEC;
 
 118 EXTSPEC struct mallinfo nedmallinfo(void) THROWSPEC;
 
 120 EXTSPEC int    nedmallopt(int parno, int value) THROWSPEC;
 
 121 EXTSPEC int    nedmalloc_trim(size_t pad) THROWSPEC;
 
 122 EXTSPEC void   nedmalloc_stats(void) THROWSPEC;
 
 123 EXTSPEC size_t nedmalloc_footprint(void) THROWSPEC;
 
 124 EXTSPEC MALLOCATTR void **nedindependent_calloc(size_t elemsno, size_t elemsize, void **chunks) THROWSPEC;
 
 125 EXTSPEC MALLOCATTR void **nedindependent_comalloc(size_t elems, size_t *sizes, void **chunks) THROWSPEC;
 
 127 /* These are the pool functions */
 
 129 typedef struct nedpool_t nedpool;
 
 131 /* Creates a memory pool for use with the nedp* functions below.
 
 132 Capacity is how much to allocate immediately (if you know you'll be allocating a lot
 
 133 of memory very soon) which you can leave at zero. Threads specifies how many threads
 
 134 will *normally* be accessing the pool concurrently. Setting this to zero means it
 
 135 extends on demand, but be careful of this as it can rapidly consume system resources
 
 136 where bursts of concurrent threads use a pool at once.
 
 138 EXTSPEC MALLOCATTR nedpool *nedcreatepool(size_t capacity, int threads) THROWSPEC;
 
 140 /* Destroys a memory pool previously created by nedcreatepool().
 
 142 EXTSPEC void neddestroypool(nedpool *p) THROWSPEC;
 
 144 /* Sets a value to be associated with a pool. You can retrieve this value by passing
 
 145 any memory block allocated from that pool.
 
 147 EXTSPEC void nedpsetvalue(nedpool *p, void *v) THROWSPEC;
 
 148 /* Gets a previously set value using nedpsetvalue() or zero if memory is unknown.
 
 149 Optionally can also retrieve pool.
 
 151 EXTSPEC void *nedgetvalue(nedpool **p, void *mem) THROWSPEC;
 
 153 /* Disables the thread cache for the calling thread, returning any existing cache
 
 154 data to the central pool.
 
 156 EXTSPEC void neddisablethreadcache(nedpool *p) THROWSPEC;
 
 158 EXTSPEC MALLOCATTR void * nedpmalloc(nedpool *p, size_t size) THROWSPEC;
 
 159 EXTSPEC MALLOCATTR void * nedpcalloc(nedpool *p, size_t no, size_t size) THROWSPEC;
 
 160 EXTSPEC MALLOCATTR void * nedprealloc(nedpool *p, void *mem, size_t size) THROWSPEC;
 
 161 EXTSPEC void   nedpfree(nedpool *p, void *mem) THROWSPEC;
 
 162 EXTSPEC MALLOCATTR void * nedpmemalign(nedpool *p, size_t alignment, size_t bytes) THROWSPEC;
 
 164 EXTSPEC struct mallinfo nedpmallinfo(nedpool *p) THROWSPEC;
 
 166 EXTSPEC int    nedpmallopt(nedpool *p, int parno, int value) THROWSPEC;
 
 167 EXTSPEC int    nedpmalloc_trim(nedpool *p, size_t pad) THROWSPEC;
 
 168 EXTSPEC void   nedpmalloc_stats(nedpool *p) THROWSPEC;
 
 169 EXTSPEC size_t nedpmalloc_footprint(nedpool *p) THROWSPEC;
 
 170 EXTSPEC MALLOCATTR void **nedpindependent_calloc(nedpool *p, size_t elemsno, size_t elemsize, void **chunks) THROWSPEC;
 
 171 EXTSPEC MALLOCATTR void **nedpindependent_comalloc(nedpool *p, size_t elems, size_t *sizes, void **chunks) THROWSPEC;
 
 173 #if defined(__cplusplus)