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