1 // Written in the D programming language.
2 /**
3 This module provides low-level bindings with the mimalloc C interface
4 Copyright: Copyright 2019 Ernesto Castellotti <erny.castell@gmail.com>
5 License:   $(HTTP https://www.mozilla.org/en-US/MPL/2.0/, Mozilla Public License - Version 2.0).
6 Authors:   $(HTTP github.com/ErnyTech, Ernesto Castellotti)
7 */
8 module neomimalloc.c.mimalloc;
9 
10 import core.stdc.config : c_long;
11 import core.stdc.stdio: FILE;
12 
13 extern(C) {
14     /**
15      * The mimalloc version
16      */
17     enum MI_MALLOC_VERSION = 100;
18 
19     /**
20      * Internal use
21      */
22     enum MI_SMALL_WSIZE_MAX = 128;
23 
24     /**
25      * Maximum size allowed for small allocations in mi_malloc_small and mi_zalloc_small (usually 128*sizeof(void*) (= 1KB on 64-bit systems))
26      */
27     enum MI_SMALL_SIZE_MAX = MI_SMALL_WSIZE_MAX * (void*).sizeof;
28 
29     /**
30      * Type of deferred free functions.
31      * 
32      * Params:
33      *      force = If true all outstanding items should be freed.
34      *      heartbeat = A monotonically increasing count.
35      *
36      * Most detailed when using a debug build.
37      */
38     alias mi_deferred_free_fun = void function(bool force, ulong heartbeat);
39 
40     /**
41      * Type of first-class heaps.
42      *
43      * A heap can only be used for (re)allocation in the thread that created this heap! Any allocated blocks can be freed by any other thread though.
44      */
45     struct mi_heap_t;
46 
47     /**
48      * An area of heap space contains blocks of a single size.
49      *
50      * The bytes in freed blocks are committed - used.
51      */
52     struct mi_heap_area_t {
53         void* blocks;       /** start of the area containing heap blocks */
54         size_t reserved;    /** bytes reserved for this area (virtual) */
55         size_t committed;   /** current available bytes for this area */
56         size_t used;        /** bytes in use by allocated blocks */
57         size_t block_size;  /** size in bytes of each block */
58     }
59 
60     /**
61      * Visitor function passed to mi_heap_visit_blocks()
62      *
63      * Returns:
64      *      true if ok, false to stop visiting (i.e. break)
65      * 
66      * This function is always first called for every area with block as a NULL pointer. If visit_all_blocks was true, the function is then called for every allocated block in that area.
67      */
68     alias mi_block_visit_fun = bool function(const(mi_heap_t)* heap, 
69                                             const(mi_heap_area_t)* area, 
70                                             void* block, size_t block_size, 
71                                             const(void)* arg);
72 
73     /**
74      * Runtime options.
75      */
76     enum mi_option_t {     
77         mi_option_show_stats = 0,       /** Print statistics to stderr when the program is done. */
78         mi_option_show_errors = 1,      /** Print error messages to stderr. */
79         mi_option_verbose = 2,          /** Print verbose messages to stderr. */
80         mi_option_secure = 3,           /** Experimental*/
81         mi_option_pool_commit = 4,      /** Experimental: Commit segments in large pools. */
82         mi_option_large_os_pages = 5,   /** Experimental: Use large os pages */
83         mi_option_page_reset = 6,       /** Experimental: Reset page memory when it becomes free. */
84         mi_option_cache_reset = 7,      /** Experimental: Reset segment memory when a segment is cached. */
85         _mi_option_last = 8
86 }
87 
88     /**
89      * Allocate size bytes.
90      * 
91      * Params:
92      *      size = number of bytes to allocate.
93      *
94      * Returns:
95      *      pointer to the allocated memory or NULL if out of memory. Returns a unique pointer if called with size 0.
96      */
97     @nogc pure @system nothrow void* mi_malloc(size_t size);
98 
99     /**
100      * Allocate count elements of size bytes.
101      * 
102      * Params:
103      *      count = The number of elements.
104      *      size = The size of each element.
105      *
106      * Returns:
107      *      A pointer to a block of count * size bytes, or NULL if out of memory or if count * size overflows.
108      *
109      * If there is no overflow, it behaves exactly like mi_malloc(p,count*size).
110      */
111     @nogc pure @system nothrow void* mi_mallocn(size_t count, size_t size);
112 
113     /**
114      * Allocate zero-initialized count elements of size bytes.
115      * 
116      * Params:
117      *      count = number of elements.
118      *      size = size of each element.
119      *
120      * Returns:
121      *      pointer to the allocated memory of size*count bytes, or NULL if either out of memory or when count*size overflows.
122      *
123      * Returns a unique pointer if called with either size or count of 0.
124      */
125     @nogc pure @system nothrow void* mi_calloc(size_t count, size_t size);
126 
127     /**
128      * Re-allocate memory to newsize bytes.
129      * 
130      * Params:
131      *      p = pointer to previously allocated memory (or NULL).
132      *      newsize = the new required size in bytes.
133      *
134      * Returns:
135      *      pointer to the re-allocated memory of newsize bytes, or NULL if out of memory. If NULL is returned, the pointer p is not freed. Otherwise the original pointer is either freed or returned as the reallocated result (in case it fits in-place with the new size). If the pointer p is NULL, it behaves as mi_malloc(newsize). If newsize is larger than the original size allocated for p, the bytes after size are uninitialized.
136      */
137     @nogc pure @system nothrow void* mi_realloc(void* p, size_t newsize);
138 
139     /**
140      * Re-allocate memory to newsize bytes.
141      * 
142      * Params:
143      *      p = pointer to previously allocated memory (or NULL).
144      *      newsize = the new required size in bytes.
145      *
146      * Returns:
147      *      pointer to the re-allocated memory of newsize bytes, or NULL if out of memory.
148      *
149      * In contrast to mi_realloc(), if NULL is returned, the original pointer p is freed (if it was not NULL itself). Otherwise the original pointer is either freed or returned as the reallocated result (in case it fits in-place with the new size). If the pointer p is NULL, it behaves as mi_malloc(newsize). If newsize is larger than the original size allocated for p, the bytes after size are uninitialized.
150      */
151     @nogc pure @system nothrow void* mi_reallocf(void* p, size_t newsize);
152 
153     /**
154      * Re-allocate memory to count elements of size bytes.
155      * 
156      * Params:
157      *      p = Pointer to a previously allocated block (or NULL).
158      *      count = The number of elements.
159      *      size = The size of each element.
160      *
161      * Returns:
162      *      A pointer to a re-allocated block of count * size bytes, or NULL if out of memory or if count * size overflows.
163      *
164      * If there is no overflow, it behaves exactly like mi_realloc(p,count*size).
165      */
166     @nogc pure @system nothrow void* mi_reallocn(void* p, size_t count, size_t size);
167 
168     /**
169      * Allocate zero-initialized size bytes.
170      * 
171      * Params:
172      *      size = The size in bytes.
173      *
174      * Returns:
175      *      Pointer to newly allocated zero initialized memory, or NULL if out of memory.
176      */
177     @nogc pure @system nothrow void* mi_zalloc(size_t size);
178 
179     /**
180      * Try to re-allocate memory to newsize bytes in place.
181      * 
182      * Params:
183      *      p = pointer to previously allocated memory (or NULL).
184      *      newsize = the new required size in bytes.
185      *
186      * Returns:
187      *      pointer to the re-allocated memory of newsize bytes (always equal to p), or NULL if either out of memory or if the memory could not be expanded in place. If NULL is returned, the pointer p is not freed. Otherwise the original pointer is returned as the reallocated result since it fits in-place with the new size. If newsize is larger than the original size allocated for p, the bytes after size are uninitialized.
188      */
189     @nogc pure @system nothrow void* mi_expand(void* p, size_t newsize);
190 
191     /**
192      * Free previously allocated memory.
193      *
194      * The pointer p must have been allocated before (or be NULL).
195      * 
196      * Params:
197      *      p = pointer to free, or NULL.
198      */
199     @nogc pure @system nothrow void mi_free(void* p);
200 
201     /**
202      * Allocate and duplicate a string.
203      * 
204      * Params:
205      *      s = string to duplicate (or NULL).
206      *
207      * Returns:
208      *      a pointer to newly allocated memory initialized to string s, or NULL if either out of memory or if s is NULL.
209      *
210      * Replacement for the standard strdup() such that mi_free() can be used on the returned result.
211      */
212     @nogc pure @system nothrow char* mi_strdup(const(char)* s);
213 
214     /**
215      * Allocate and duplicate a string up to n bytes.
216      * 
217      * Params:
218      *      s = string to duplicate (or NULL).
219      *      n = maximum number of bytes to copy (excluding the terminating zero).
220      *
221      * Returns:
222      *      a pointer to newly allocated memory initialized to string s up to the first n bytes (and always zero terminated), or NULL if either out of memory or if s is NULL.
223      *
224      * Replacement for the standard strndup() such that mi_free() can be used on the returned result.
225      */
226     @nogc pure @system nothrow char* mi_strndup(const(char)* s, size_t n);
227 
228     /**
229      * Resolve a file path name.
230      * 
231      * Params:
232      *      fname = File name.
233      *      resolved_name = Should be NULL (but can also point to a buffer of at least PATH_MAX bytes).
234      *
235      * Returns:
236      *      If successful a pointer to the resolved absolute file name, or NULL on failure (with errno set to the error code).
237      *
238      * If resolved_name was NULL, the returned result should be freed with mi_free().
239      *
240      * Replacement for the standard realpath() such that mi_free() can be used on the returned result (if resolved_name was NULL).
241      */
242     @nogc pure @system nothrow char* mi_realpath(const(char)* fname, char* resolved_name);
243 
244     /**
245      * Allocate a small object.
246      * 
247      * Params:
248      *      size = The size in bytes, can be at most MI_SMALL_SIZE_MAX.
249      *
250      * Returns:
251      *      a pointer to newly allocated memory of at least size bytes, or NULL if out of memory. This function is meant for use in run-time systems for best performance and does not check if size was indeed small – use with care!
252      */
253     @nogc pure @system nothrow void* mi_malloc_small(size_t size);
254     
255     /**
256      * Allocate a zero initialized small object.
257      * 
258      * Params:
259      *      size = The size in bytes, can be at most MI_SMALL_SIZE_MAX.
260      *
261      * Returns:
262      *      a pointer to newly allocated zero-initialized memory of at least size bytes, or NULL if out of memory. This function is meant for use in run-time systems for best performance and does not check if size was indeed small – use with care!
263      */
264     @nogc pure @system nothrow void* mi_zalloc_small (size_t size);
265     
266     /**
267      * Return the available bytes in a memory block.
268      * 
269      * Params:
270      *      p = Pointer to previously allocated memory (or NULL)
271      *
272      * Returns:
273      *      Returns the available bytes in the memory block, or 0 if p was NULL.
274      *
275      * The returned size can be used to call mi_expand successfully. The returned size is always at least equal to the allocated size of p, and, in the current design, should be less than 16.7% more.
276      */
277     @nogc pure @system nothrow size_t mi_usable_size(const(void)* p);
278     
279     /**
280      * Return the used allocation size.
281      * 
282      * Params:
283      *      size = The minimal required size in bytes.
284      *
285      * Returns:
286      *      the size n that will be allocated, where n >= size.
287      *
288      * Generally, mi_usable_size(mi_malloc(size)) == mi_good_size(size). This can be used to reduce internal wasted space when allocating buffers for example.
289      */
290     @nogc pure @system nothrow size_t mi_good_size(size_t size);
291     
292     /**
293      * Eagerly free memory.
294      * 
295      * Params:
296      *      force = If true, aggressively return memory to the OS (can be expensive!)
297      *
298      * Regular code should not have to call this function. It can be beneficial in very narrow circumstances; in particular, when a long running thread allocates a lot of blocks that are freed by other threads it may improve resource usage by calling this every once in a while.
299      */
300     @nogc pure @system nothrow void mi_collect(bool force);
301     
302     /**
303      * Print statistics.
304      * 
305      * Params:
306      *      out_ = Output file. Use NULL for stderr.
307      *
308      * Most detailed when using a debug build.
309      */
310     @nogc pure @system nothrow void mi_stats_print(FILE* out_);
311     
312     /**
313      * Reset statistics.
314      */
315     @nogc @system nothrow void mi_stats_reset();
316     
317     
318     /**
319      * Get mimalloc version
320      */
321     @nogc pure @system nothrow int mi_version();
322     
323     /**
324      * Initialize mimalloc on a process
325      */
326     @nogc @system nothrow void mi_process_init();
327     
328     /**
329      * Initialize mimalloc on a thread.
330      *
331      * Should not be used as on most systems (pthreads, windows) this is done automatically.
332      */
333     @nogc @system nothrow void mi_thread_init();
334     
335     /**
336      * Uninitialize mimalloc on a thread.
337      *
338      * Should not be used as on most systems (pthreads, windows) this is done automatically. Ensures that any memory that is not freed yet (but will be freed by other threads in the future) is properly handled.
339      */
340     @nogc @system nothrow void mi_thread_done();
341     
342     /**
343      * Print out heap statistics for this thread.
344      * 
345      * Params:
346      *      out_ = Output file. Use NULL for stderr.
347      *
348      * Most detailed when using a debug build.
349      */
350     @nogc pure @system nothrow void mi_thread_stats_print(FILE* out_);
351     
352     /**
353      * Register a deferred free function.
354      * 
355      * Params:
356      *      deferred_free = Address of a deferred free-ing function or NULL to unregister.
357      *
358      * Some runtime systems use deferred free-ing, for example when using reference counting to limit the worst case free time. Such systems can register (re-entrant) deferred free function to free more memory on demand. When the force parameter is true all possible memory should be freed. The per-thread heartbeat parameter is monotonically increasing and guaranteed to be deterministic if the program allocates deterministically. The deferred_free function is guaranteed to be called deterministically after some number of allocations (regardless of freeing or available free memory). At most one deferred_free function can be active.
359      */
360     @nogc @system nothrow void mi_register_deferred_free(const(mi_deferred_free_fun) deferred_free);
361 
362     /**
363      * Allocate size bytes aligned by alignment.
364      * 
365      * Params:
366      *      size = number of bytes to allocate.
367      *      alignment = the minimal alignment of the allocated memory.
368      *
369      * Returns:
370      *      pointer to the allocated memory or NULL if out of memory. The returned pointer is aligned by alignment, i.e. (uintptr_t)p % alignment == 0.
371      *
372      * Returns a unique pointer if called with size 0.
373      */
374     @nogc pure @system nothrow void* mi_malloc_aligned(size_t size, size_t alignment);
375     
376     /**
377      * Allocate size bytes aligned by alignment at a specified offset.
378      * 
379      * Params:
380      *      size = number of bytes to allocate.
381      *      alignment = the minimal alignment of the allocated memory at offset.
382      *      offset = the offset that should be aligned.
383      *
384      * Returns:
385      *      pointer to the allocated memory or NULL if out of memory. The returned pointer is aligned by alignment at offset, i.e. ((uintptr_t)p + offset) % alignment == 0.
386      *
387      * Returns a unique pointer if called with size 0.
388      */
389     @nogc pure @system nothrow void* mi_malloc_aligned_at(size_t size, size_t alignment, size_t offset);
390     
391     /**
392      * Allocate zero-initialized size bytes aligned by alignment.
393      */
394     @nogc pure @system nothrow void* mi_zalloc_aligned(size_t size, size_t alignment);
395     
396     /**
397      * Allocate zero-initialized size bytes aligned by alignment at a specified offset.
398      */
399     @nogc pure @system nothrow void* mi_zalloc_aligned_at(size_t size, size_t alignment, size_t offset);
400     
401     /**
402      * Allocate zero-initialized count elements of size bytes aligned by alignment.
403      */
404     @nogc pure @system nothrow void* mi_calloc_aligned(size_t count, size_t size, size_t alignment);
405     
406     /**
407      * Allocate zero-initialized count elements of size bytes aligned by alignment at a specified offset.
408      */
409     void* mi_calloc_aligned_at(size_t count, size_t size, size_t alignment, size_t offset);
410     
411     /**
412      * Re-allocate memory to newsize bytes aligned by alignment.
413      */
414     @nogc pure @system nothrow void* mi_realloc_aligned(void* p, size_t newsize, size_t alignment);
415     
416     /**
417      * Re-allocate memory to newsize bytes aligned by alignment at a specified offset.
418      */
419     @nogc pure @system nothrow void* mi_realloc_aligned_at(void* p, size_t newsize, size_t alignment, size_t offset);
420 
421     /**
422      * Create a new heap that can be used for allocation.
423      */
424     @nogc pure @system nothrow mi_heap_t* mi_heap_new();
425     
426     /**
427      * Delete a previously allocated heap.
428      *
429      * This will release resources and migrate any still allocated blocks in this heap (efficienty) to the default heap.
430      * 
431      * If heap is the default heap, the default heap is set to the backing heap.
432      */
433     @nogc pure @system nothrow void mi_heap_delete(mi_heap_t* heap);
434     
435     /**
436      * Destroy a heap, freeing all its still allocated blocks.
437      *
438      * Use with care as this will free all blocks still allocated in the heap. However, this can be a very efficient way to free all heap memory in one go.
439      * 
440      * If heap is the default heap, the default heap is set to the backing heap.
441      */
442     @nogc pure @system nothrow void mi_heap_destroy(mi_heap_t* heap);
443     
444     /**
445      * Set the default heap to use for mi_malloc() et al.
446      * 
447      * Params:
448      *      heap = The new default heap.
449      *
450      * Returns:
451      *      The previous default heap.
452      */
453     @nogc pure @system nothrow mi_heap_t* mi_heap_set_default(mi_heap_t* heap);
454     
455     /**
456      * Get the default heap that is used for mi_malloc() et al.
457      * 
458      * Returns:
459      *      The current default heap.
460      */
461     @nogc pure @system nothrow mi_heap_t* mi_heap_get_default();
462     
463     /**
464      * Get the backing heap.
465      *
466      * The backing heap is the initial default heap for a thread and always available for allocations. It cannot be destroyed or deleted except by exiting the thread.
467      */
468     @nogc pure @system nothrow mi_heap_t* mi_heap_get_backing();
469     
470     /**
471      * Eagerly free memory in specific heap.
472      */ 
473     @nogc pure @system nothrow void mi_heap_collect(mi_heap_t* heap, bool force);
474     
475     /**
476      * Allocate in a specific heap.
477      */
478     @nogc pure @system nothrow void* mi_heap_malloc(mi_heap_t* heap, size_t size);
479 
480     /**
481      * Allocate count elements in a specific heap.
482      */
483     @nogc pure @system nothrow void* mi_heap_mallocn(mi_heap_t* heap, size_t count, size_t size);
484 
485     /**
486      * Allocate zero-initialized in a specific heap.
487      */
488     @nogc pure @system nothrow void* mi_heap_zalloc(mi_heap_t* heap, size_t size);
489     
490     /**
491      * Allocate count zero-initialized elements in a specific heap.
492      */
493     @nogc pure @system nothrow void* mi_heap_calloc(mi_heap_t* heap, size_t count, size_t size);
494     
495     /**
496      * Allocate a small object in a specific heap.
497      */
498     @nogc pure @system nothrow void* mi_heap_malloc_small(mi_heap_t* heap, size_t size);
499     
500     /**
501      * Re-allocate memory to newsize bytes in a specific heap.
502      */
503     @nogc pure @system nothrow void* mi_heap_realloc(mi_heap_t* heap, void* p, size_t newsize);
504     
505     /**
506      * Re-allocate memory to count elements of size bytes in a specific heap.
507      */
508     @nogc pure @system nothrow  void* mi_heap_reallocn(mi_heap_t* heap, void* p, size_t count, size_t size);
509     
510     /**
511      * Re-allocate memory to newsize bytes in a specific heap.
512      */
513     @nogc pure @system nothrow  void* mi_heap_reallocf(mi_heap_t* heap, void* p, size_t newsize);
514 
515     /**
516      * Duplicate a string in a specific heap.
517      */
518     @nogc pure @system nothrow char* mi_heap_strdup(mi_heap_t* heap, const(char)* s);
519 
520     /**
521      * Duplicate a string of at most length n in a specific heap.
522      */
523     @nogc pure @system nothrow char* mi_heap_strndup(mi_heap_t* heap, const(char)* s, size_t n);
524     
525     /**
526      * Resolve a file path name using a specific heap to allocate the result.
527      */
528     @nogc pure @system nothrow char* mi_heap_realpath(mi_heap_t* heap, const(char)* fname, char* resolved_name);
529     
530     /**
531      * Allocate size bytes aligned by alignment in a specific heap.
532      */
533     @nogc pure @system nothrow void* mi_heap_malloc_aligned(mi_heap_t* heap, size_t size, size_t alignment);
534     
535     /**
536      * Allocate size bytes aligned by alignment at a specified offset in a specific heap.
537      */
538     @nogc pure @system nothrow void* mi_heap_malloc_aligned_at(mi_heap_t* heap, size_t size, size_t alignment, size_t offset);
539     
540     /**
541      * Allocate zero-initialized size bytes aligned by alignment in a specific heap.
542      */
543     @nogc pure @system nothrow void* mi_heap_zalloc_aligned(mi_heap_t* heap, size_t size, size_t alignment);
544     
545     /**
546      * Allocate zero-initialized size bytes aligned by alignment at a specified offset in a specific heap.
547      */
548     @nogc pure @system nothrow void* mi_heap_zalloc_aligned_at (mi_heap_t* heap, size_t size, size_t alignment, size_t offset);
549     
550     /**
551      * Allocate zero-initialized count elements of size bytes aligned by alignment in a specific heap.
552      */
553     @nogc pure @system nothrow void* mi_heap_calloc_aligned(mi_heap_t* heap, size_t count, size_t size, size_t alignment);
554     
555     /**
556      * Allocate zero-initialized count elements of size bytes aligned by alignment at a specified offset in a specific heap.
557      */
558     @nogc pure @system nothrow void* mi_heap_calloc_aligned_at(mi_heap_t* heap, size_t count, size_t size, size_t alignment, size_t offset);
559     
560     /**
561      * Re-allocate memory to newsize bytes aligned by alignment in a specific heap.
562      */
563     @nogc pure @system nothrow void* mi_heap_realloc_aligned(mi_heap_t* heap, void* p, size_t newsize, size_t alignment);
564     
565     /**
566      * Re-allocate memory to newsize bytes aligned by alignment at a specified offset in a specific heap.
567      */
568     @nogc pure @system nothrow void* mi_heap_realloc_aligned_at(mi_heap_t* heap, void* p, size_t newsize, size_t alignment, size_t offset);
569 
570     /**
571      * Does a heap contain a pointer to a previously allocated block?
572      * 
573      * Params:
574      *      heap = The heap.
575      *      p = Pointer to a previously allocated block (in any heap)– cannot be some random pointer!
576      *
577      * Returns:
578      *      true if the block pointed to by p is in the heap.
579      */
580     @nogc pure @system nothrow bool mi_heap_contains_block(mi_heap_t* heap, const(void)* p);
581     
582     /**
583      * Check safely if any pointer is part of a heap.
584      * 
585      * Params:
586      *      heap = The heap.
587      *      p = Any pointer – not required to be previously allocated by us.
588      *
589      * Returns:
590      *      true if p points to a block in heap.
591      *
592      * Note: expensive function, linear in the pages in the heap.
593      */
594     @nogc pure @system nothrow bool mi_heap_check_owned(mi_heap_t* heap, const(void)* p);
595     
596     /**
597      * Check safely if any pointer is part of the default heap of this thread.
598      * 
599      * Params:
600      *      p = Any pointer – not required to be previously allocated by us.
601      *
602      * Returns:
603      *      true if p points to a block in default heap of this thread.
604      *
605      * Note: expensive function, linear in the pages in the heap.
606      */
607     @nogc pure @system nothrow bool mi_check_owned(const(void)* p);
608 
609     /**
610      * Visit all areas and blocks in a heap.
611      * 
612      * Params:
613      *      heap = The heap to visit.
614      *      visit_all_blocks = If true visits all allocated blocks, otherwise visitor is only called for every heap area.
615      *      visitor = This function is called for every area in the heap (with block as NULL). If visit_all_blocks is true, visitor is also called for every allocated block in every area (with block!=NULL). return false from this function to stop visiting early.
616      *      arg = 	Extra argument passed to visitor.
617      *
618      * Returns:
619      *      true if all areas and blocks were visited.
620      */
621     @nogc pure @system nothrow bool mi_heap_visit_blocks(const(mi_heap_t)* heap, bool visit_all_blocks, mi_block_visit_fun visitor, const(void)* arg);
622 
623     /**
624      * Inspect the heap at runtime.
625      */
626     @nogc pure @system nothrow bool mi_is_in_heap_region(const(void)* p);
627     
628     /**
629      * Set runtime behavior.
630      */
631     @nogc pure @system nothrow bool mi_option_is_enabled(mi_option_t option);
632 
633     /**
634      * Set runtime behavior.
635      */
636     @nogc @system nothrow void mi_option_enable(mi_option_t option, bool enable);
637 
638     /**
639      * Set runtime behavior.
640      */
641     @nogc @system nothrow void mi_option_enable_default(mi_option_t option, bool enable);
642 
643     /**
644      * Set runtime behavior.
645      */
646     @nogc pure @system nothrow c_long mi_option_get(mi_option_t option);
647 
648     /**
649      * Set runtime behavior.
650      */
651     @nogc @system nothrow void mi_option_set(mi_option_t option, c_long value);
652 
653     /**
654      * Set runtime behavior.
655      */
656     @nogc @system nothrow void mi_option_set_default(mi_option_t option, c_long value);
657     
658     /**
659      * Re-allocate memory to newsize bytes.
660      * 
661      * Params:
662      *      p = pointer to previously allocated memory (or NULL).
663      *      newsize = the new required size in bytes.
664      *
665      * Returns:
666      *      pointer to the re-allocated memory of newsize bytes, or NULL if out of memory. If NULL is returned, the pointer p is not freed. Otherwise the original pointer is either freed or returned as the reallocated result (in case it fits in-place with the new size). If the pointer p is NULL, it behaves as mi_malloc(newsize). If newsize is larger than the original size allocated for p, the bytes after size are uninitialized.
667      */
668     @nogc pure @system nothrow void* mi_recalloc(void* p, size_t count, size_t size);
669     
670     /**
671      * mi prefixed implementations of various posix, unix, and C++ allocation functions
672      */
673     @nogc pure @system nothrow size_t mi_malloc_size(const(void)* p);
674     
675     /**
676      * mi prefixed implementations of various posix, unix, and C++ allocation functions
677      */
678     @nogc pure @system nothrow size_t mi_malloc_usable_size(const(void)* p);
679     
680     /**
681      * mi prefixed implementations of various posix, unix, and C++ allocation functions
682      */
683     @nogc pure @system nothrow size_t mi_cfree(void* p);
684     
685     /**
686      * mi prefixed implementations of various posix, unix, and C++ allocation functions
687      */
688     @nogc pure @system nothrow int mi_posix_memalign(void** p, size_t alignment, size_t size);
689     
690     /**
691      * mi prefixed implementations of various posix, unix, and C++ allocation functions
692      */
693     @nogc pure @system nothrow int mi__posix_memalign(void** p, size_t alignment, size_t size);
694     
695     /**
696      * mi prefixed implementations of various posix, unix, and C++ allocation functions
697      */
698     @nogc pure @system nothrow void* mi_memalign(size_t alignment, size_t size);
699     
700     /**
701      * mi prefixed implementations of various posix, unix, and C++ allocation functions
702      */
703     @nogc pure @system nothrow void* mi_valloc(size_t size);
704     
705     /**
706      * mi prefixed implementations of various posix, unix, and C++ allocation functions
707      */
708     @nogc pure @system nothrow void* mi_pvalloc(size_t size);
709     
710     /**
711      * mi prefixed implementations of various posix, unix, and C++ allocation functions
712      */
713     @nogc pure @system nothrow void* mi_aligned_alloc(size_t alignment, size_t size);
714     
715     /**
716      * mi prefixed implementations of various posix, unix, and C++ allocation functions
717      */
718     @nogc pure @system nothrow void* mi_reallocarray(void* p, size_t count, size_t size);
719     
720     /**
721      * mi prefixed implementations of various posix, unix, and C++ allocation functions
722      */
723     @nogc pure @system nothrow void mi_free_size(void* p, size_t size);
724     
725     /**
726      * mi prefixed implementations of various posix, unix, and C++ allocation functions
727      */
728     @nogc pure @system nothrow void mi_free_size_aligned(void* p, size_t size, size_t alignment);
729     
730     /**
731      * mi prefixed implementations of various posix, unix, and C++ allocation functions
732      */
733     @nogc pure @system nothrow void mi_free_aligned(void* p, size_t alignment);
734     
735     /**
736      * mi prefixed implementations of various posix, unix, and C++ allocation functions
737      */
738     @nogc pure @system void* mi_new(size_t n);
739     
740     /**
741      * mi prefixed implementations of various posix, unix, and C++ allocation functions
742      */
743     @nogc pure @system void* mi_new_aligned(size_t n, size_t alignment);
744     
745     /**
746      * mi prefixed implementations of various posix, unix, and C++ allocation functions
747      */
748     @nogc pure @system nothrow void* mi_new_nothrow(size_t n);
749     
750     /**
751      * mi prefixed implementations of various posix, unix, and C++ allocation functions
752      */
753     @nogc pure @system nothrow void* mi_new_aligned_nothrow(size_t n, size_t alignment);
754 }