nedmalloc.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  1. #ifdef NEDMALLOC_ENABLED
  2. /* nedalloc, an alternative malloc implementation for multiple threads without
  3. lock contention based on dlmalloc v2.8.3. (C) 2005-2009 Niall Douglas
  4. Boost Software License - Version 1.0 - August 17th, 2003
  5. Permission is hereby granted, free of charge, to any person or organization
  6. obtaining a copy of the software and accompanying documentation covered by
  7. this license (the "Software") to use, reproduce, display, distribute,
  8. execute, and transmit the Software, and to prepare derivative works of the
  9. Software, and to permit third-parties to whom the Software is furnished to
  10. do so, all subject to the following:
  11. The copyright notices in the Software and this entire statement, including
  12. the above license grant, this restriction and the following disclaimer,
  13. must be included in all copies of the Software, in whole or in part, and
  14. all derivative works of the Software, unless such copies or derivative
  15. works are solely in the form of machine-executable object code generated by
  16. a source language processor.
  17. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  18. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19. FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
  20. SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
  21. FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
  22. ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  23. DEALINGS IN THE SOFTWARE.
  24. */
  25. #ifndef NEDMALLOC_H
  26. #define NEDMALLOC_H
  27. #include "typedefs.h"
  28. #define MALLOC_ALIGNMENT DEFAULT_ALIGNMENT
  29. #ifdef PSP_ENABLED
  30. #define USE_LOCKS 0
  31. #define HAVE_MMAP 0
  32. #endif
  33. /* See malloc.c.h for what each function does.
  34. REPLACE_SYSTEM_ALLOCATOR on POSIX causes nedalloc's functions to be called
  35. malloc, free etc. instead of nedmalloc, nedfree etc. You may or may not want
  36. this. On Windows it causes nedmalloc to patch all loaded DLLs and binaries
  37. to replace usage of the system allocator.
  38. NO_NED_NAMESPACE prevents the functions from being defined in the nedalloc
  39. namespace when in C++ (uses the global namespace instead).
  40. NEDMALLOCEXTSPEC can be defined to be __declspec(dllexport) or
  41. __attribute__ ((visibility("default"))) or whatever you like. It defaults
  42. to extern unless NEDMALLOC_DLL_EXPORTS is set as it would be when building
  43. nedmalloc.dll.
  44. USE_LOCKS can be 2 if you want to define your own MLOCK_T, INITIAL_LOCK,
  45. ACQUIRE_LOCK, RELEASE_LOCK, TRY_LOCK, IS_LOCKED and NULL_LOCK_INITIALIZER.
  46. NEDMALLOC_DEBUG can be defined to cause DEBUG to be set differently for nedmalloc
  47. than for the rest of the build. Remember to set NDEBUG to disable all assertion
  48. checking too.
  49. USE_MAGIC_HEADERS causes nedalloc to allocate an extra three sizeof(size_t)
  50. to each block. nedpfree() and nedprealloc() can then automagically know when
  51. to free a system allocated block. Enabling this typically adds 20-50% to
  52. application memory usage.
  53. ENABLE_TOLERANT_NEDMALLOC is automatically turned on if REPLACE_SYSTEM_ALLOCATOR
  54. is set or the Windows DLL is being built. This causes nedmalloc to detect when a
  55. system allocator block is passed to it and to handle it appropriately. Note that
  56. without USE_MAGIC_HEADERS there is a very tiny chance that nedmalloc will segfault
  57. on non-Windows builds (it uses Win32 SEH to trap segfaults on Windows and there
  58. is no comparable system on POSIX).
  59. USE_ALLOCATOR can be one of these settings (it defaults to 1):
  60. 0: System allocator (nedmalloc now simply acts as a threadcache).
  61. WARNING: Intended for DEBUG USE ONLY - not all functions work correctly.
  62. 1: dlmalloc
  63. ENABLE_LARGE_PAGES enables support for requesting memory from the system in large
  64. (typically >=2Mb) pages if the host OS supports this. These occupy just a single
  65. TLB entry and can significantly improve performance in large working set applications.
  66. ENABLE_FAST_HEAP_DETECTION enables special logic to detect blocks allocated
  67. by the system heap. This avoids 1.5%-2% overhead when checking for non-nedmalloc
  68. blocks, but it assumes that the NT and glibc heaps function in a very specific
  69. fashion which may not hold true across OS upgrades.
  70. */
  71. #include <stddef.h> /* for size_t */
  72. #ifndef NEDMALLOCEXTSPEC
  73. #ifdef NEDMALLOC_DLL_EXPORTS
  74. #ifdef WIN32
  75. #define NEDMALLOCEXTSPEC extern __declspec(dllexport)
  76. #elif defined(__GNUC__)
  77. #define NEDMALLOCEXTSPEC extern __attribute__ ((visibility("default")))
  78. #endif
  79. #ifndef ENABLE_TOLERANT_NEDMALLOC
  80. #define ENABLE_TOLERANT_NEDMALLOC 1
  81. #endif
  82. #else
  83. #define NEDMALLOCEXTSPEC extern
  84. #endif
  85. #endif
  86. #if __STDC_VERSION__ >= 199901L /* C99 or better */
  87. #define RESTRICT restrict
  88. #else
  89. #if defined(_MSC_VER) && _MSC_VER>=1400
  90. #define RESTRICT __restrict
  91. #endif
  92. #ifdef __GNUC__
  93. #define RESTRICT __restrict
  94. #endif
  95. #endif
  96. #ifndef RESTRICT
  97. #define RESTRICT
  98. #endif
  99. #if defined(_MSC_VER) && _MSC_VER>=1400
  100. #define NEDMALLOCPTRATTR __declspec(restrict)
  101. #define NEDMALLOCNOALIASATTR __declspec(noalias)
  102. #endif
  103. #ifdef __GNUC__
  104. #define NEDMALLOCPTRATTR __attribute__ ((malloc))
  105. #endif
  106. #ifndef NEDMALLOCPTRATTR
  107. #define NEDMALLOCPTRATTR
  108. #endif
  109. #ifndef NEDMALLOCNOALIASATTR
  110. #define NEDMALLOCNOALIASATTR
  111. #endif
  112. #ifndef USE_MAGIC_HEADERS
  113. #define USE_MAGIC_HEADERS 0
  114. #endif
  115. #ifndef USE_ALLOCATOR
  116. #define USE_ALLOCATOR 1 /* dlmalloc */
  117. #endif
  118. #if !USE_ALLOCATOR && !USE_MAGIC_HEADERS
  119. #error If you are using the system allocator then you MUST use magic headers
  120. #endif
  121. #ifdef REPLACE_SYSTEM_ALLOCATOR
  122. #if USE_ALLOCATOR==0
  123. #error Cannot combine using the system allocator with replacing the system allocator
  124. #endif
  125. #ifndef ENABLE_TOLERANT_NEDMALLOC
  126. #define ENABLE_TOLERANT_NEDMALLOC 1
  127. #endif
  128. #ifndef WIN32 /* We have a dedicated patcher for Windows */
  129. #define nedmalloc malloc
  130. #define nedcalloc calloc
  131. #define nedrealloc realloc
  132. #define nedfree free
  133. #define nedmemalign memalign
  134. #define nedmallinfo mallinfo
  135. #define nedmallopt mallopt
  136. #define nedmalloc_trim malloc_trim
  137. #define nedmalloc_stats malloc_stats
  138. #define nedmalloc_footprint malloc_footprint
  139. #define nedindependent_calloc independent_calloc
  140. #define nedindependent_comalloc independent_comalloc
  141. #ifdef _MSC_VER
  142. #define nedblksize _msize
  143. #endif
  144. #endif
  145. #endif
  146. #if defined(__cplusplus)
  147. extern "C" {
  148. #endif
  149. struct nedmallinfo {
  150. size_t arena; /* non-mmapped space allocated from system */
  151. size_t ordblks; /* number of free chunks */
  152. size_t smblks; /* always 0 */
  153. size_t hblks; /* always 0 */
  154. size_t hblkhd; /* space in mmapped regions */
  155. size_t usmblks; /* maximum total allocated space */
  156. size_t fsmblks; /* always 0 */
  157. size_t uordblks; /* total allocated space */
  158. size_t fordblks; /* total free space */
  159. size_t keepcost; /* releasable (via malloc_trim) space */
  160. };
  161. #if defined(__cplusplus)
  162. }
  163. #endif
  164. #if defined(__cplusplus)
  165. #if !defined(NO_NED_NAMESPACE)
  166. namespace nedalloc {
  167. #else
  168. extern "C" {
  169. #endif
  170. #define THROWSPEC throw()
  171. #else
  172. #define THROWSPEC
  173. #endif
  174. /* These are the global functions */
  175. /* Gets the usable size of an allocated block. Note this will always be bigger than what was
  176. asked for due to rounding etc. Optionally returns 1 in isforeign if the block came from the
  177. system allocator - note that there is a small (>0.01%) but real chance of segfault on non-Windows
  178. systems when passing non-nedmalloc blocks if you don't use USE_MAGIC_HEADERS.
  179. */
  180. NEDMALLOCEXTSPEC NEDMALLOCNOALIASATTR size_t nedblksize(int *RESTRICT isforeign, void *RESTRICT mem) THROWSPEC;
  181. NEDMALLOCEXTSPEC NEDMALLOCNOALIASATTR void nedsetvalue(void *v) THROWSPEC;
  182. NEDMALLOCEXTSPEC NEDMALLOCNOALIASATTR NEDMALLOCPTRATTR void * nedmalloc(size_t size) THROWSPEC;
  183. NEDMALLOCEXTSPEC NEDMALLOCNOALIASATTR NEDMALLOCPTRATTR void * nedcalloc(size_t no, size_t size) THROWSPEC;
  184. NEDMALLOCEXTSPEC NEDMALLOCNOALIASATTR NEDMALLOCPTRATTR void * nedrealloc(void *mem, size_t size) THROWSPEC;
  185. NEDMALLOCEXTSPEC NEDMALLOCNOALIASATTR void nedfree(void *mem) THROWSPEC;
  186. NEDMALLOCEXTSPEC NEDMALLOCNOALIASATTR NEDMALLOCPTRATTR void * nedmemalign(size_t alignment, size_t bytes) THROWSPEC;
  187. NEDMALLOCEXTSPEC NEDMALLOCNOALIASATTR struct nedmallinfo nedmallinfo(void) THROWSPEC;
  188. NEDMALLOCEXTSPEC NEDMALLOCNOALIASATTR int nedmallopt(int parno, int value) THROWSPEC;
  189. NEDMALLOCEXTSPEC NEDMALLOCNOALIASATTR void* nedmalloc_internals(size_t *granularity, size_t *magic) THROWSPEC;
  190. NEDMALLOCEXTSPEC NEDMALLOCNOALIASATTR int nedmalloc_trim(size_t pad) THROWSPEC;
  191. NEDMALLOCEXTSPEC void nedmalloc_stats(void) THROWSPEC;
  192. NEDMALLOCEXTSPEC NEDMALLOCNOALIASATTR size_t nedmalloc_footprint(void) THROWSPEC;
  193. NEDMALLOCEXTSPEC NEDMALLOCNOALIASATTR NEDMALLOCPTRATTR void **nedindependent_calloc(size_t elemsno, size_t elemsize, void **chunks) THROWSPEC;
  194. NEDMALLOCEXTSPEC NEDMALLOCNOALIASATTR NEDMALLOCPTRATTR void **nedindependent_comalloc(size_t elems, size_t *sizes, void **chunks) THROWSPEC;
  195. /* Destroys the system memory pool used by the functions above.
  196. Useful for when you have nedmalloc in a DLL you're about to unload.
  197. If you call ANY nedmalloc functions after calling this you will
  198. get a fatal exception!
  199. */
  200. NEDMALLOCEXTSPEC void neddestroysyspool() THROWSPEC;
  201. /* These are the pool functions */
  202. struct nedpool_t;
  203. typedef struct nedpool_t nedpool;
  204. /* Creates a memory pool for use with the nedp* functions below.
  205. Capacity is how much to allocate immediately (if you know you'll be allocating a lot
  206. of memory very soon) which you can leave at zero. Threads specifies how many threads
  207. will *normally* be accessing the pool concurrently. Setting this to zero means it
  208. extends on demand, but be careful of this as it can rapidly consume system resources
  209. where bursts of concurrent threads use a pool at once.
  210. */
  211. NEDMALLOCEXTSPEC NEDMALLOCPTRATTR nedpool *nedcreatepool(size_t capacity, int threads) THROWSPEC;
  212. /* Destroys a memory pool previously created by nedcreatepool().
  213. */
  214. NEDMALLOCEXTSPEC void neddestroypool(nedpool *p) THROWSPEC;
  215. /* Returns a zero terminated snapshot of threadpools existing at the time of call. Call
  216. nedfree() on the returned list when you are done. Returns zero if there is only the
  217. system pool in existence.
  218. */
  219. NEDMALLOCEXTSPEC nedpool **nedpoollist() THROWSPEC;
  220. /* Sets a value to be associated with a pool. You can retrieve this value by passing
  221. any memory block allocated from that pool.
  222. */
  223. NEDMALLOCEXTSPEC void nedpsetvalue(nedpool *p, void *v) THROWSPEC;
  224. /* Gets a previously set value using nedpsetvalue() or zero if memory is unknown.
  225. Optionally can also retrieve pool. You can detect an unknown block by the return
  226. being zero and *p being unmodifed.
  227. */
  228. NEDMALLOCEXTSPEC void *nedgetvalue(nedpool **p, void *mem) THROWSPEC;
  229. /* Trims the thread cache for the calling thread, returning any existing cache
  230. data to the central pool. Remember to ALWAYS call with zero if you used the
  231. system pool. Setting disable to non-zero replicates neddisablethreadcache().
  232. */
  233. NEDMALLOCEXTSPEC void nedtrimthreadcache(nedpool *p, int disable) THROWSPEC;
  234. /* Disables the thread cache for the calling thread, returning any existing cache
  235. data to the central pool. Remember to ALWAYS call with zero if you used the
  236. system pool.
  237. */
  238. NEDMALLOCEXTSPEC void neddisablethreadcache(nedpool *p) THROWSPEC;
  239. NEDMALLOCEXTSPEC NEDMALLOCPTRATTR void * nedpmalloc(nedpool *p, size_t size) THROWSPEC;
  240. NEDMALLOCEXTSPEC NEDMALLOCPTRATTR void * nedpcalloc(nedpool *p, size_t no, size_t size) THROWSPEC;
  241. NEDMALLOCEXTSPEC NEDMALLOCPTRATTR void * nedprealloc(nedpool *p, void *mem, size_t size) THROWSPEC;
  242. NEDMALLOCEXTSPEC void nedpfree(nedpool *p, void *mem) THROWSPEC;
  243. NEDMALLOCEXTSPEC NEDMALLOCPTRATTR void * nedpmemalign(nedpool *p, size_t alignment, size_t bytes) THROWSPEC;
  244. NEDMALLOCEXTSPEC struct nedmallinfo nedpmallinfo(nedpool *p) THROWSPEC;
  245. NEDMALLOCEXTSPEC int nedpmallopt(nedpool *p, int parno, int value) THROWSPEC;
  246. NEDMALLOCEXTSPEC int nedpmalloc_trim(nedpool *p, size_t pad) THROWSPEC;
  247. NEDMALLOCEXTSPEC void nedpmalloc_stats(nedpool *p) THROWSPEC;
  248. NEDMALLOCEXTSPEC size_t nedpmalloc_footprint(nedpool *p) THROWSPEC;
  249. NEDMALLOCEXTSPEC NEDMALLOCPTRATTR void **nedpindependent_calloc(nedpool *p, size_t elemsno, size_t elemsize, void **chunks) THROWSPEC;
  250. NEDMALLOCEXTSPEC NEDMALLOCPTRATTR void **nedpindependent_comalloc(nedpool *p, size_t elems, size_t *sizes, void **chunks) THROWSPEC;
  251. #if defined(__cplusplus)
  252. }
  253. #endif
  254. #endif
  255. #endif