8 #error "documentation file only!" 114 void*
mi_calloc(
size_t count,
size_t size);
140 void*
mi_recalloc(
void* p,
size_t count,
size_t size);
155 void*
mi_expand(
void* p,
size_t newsize);
177 void*
mi_reallocn(
void* p,
size_t count,
size_t size);
231 char*
mi_realpath(
const char* fname,
char* resolved_name);
245 #define MI_SMALL_SIZE_MAX (128*sizeof(void*)) 608 void*
mi_recalloc(
void* p,
size_t newcount,
size_t size) ;
645 #define mi_malloc_tp(tp) ((tp*)mi_malloc(sizeof(tp))) 648 #define mi_zalloc_tp(tp) ((tp*)mi_zalloc(sizeof(tp))) 651 #define mi_calloc_tp(tp,count) ((tp*)mi_calloc(count,sizeof(tp))) 654 #define mi_mallocn_tp(tp,count) ((tp*)mi_mallocn(count,sizeof(tp))) 657 #define mi_reallocn_tp(p,tp,count) ((tp*)mi_reallocn(p,count,sizeof(tp))) 660 #define mi_heap_malloc_tp(hp,tp) ((tp*)mi_heap_malloc(hp,sizeof(tp))) 663 #define mi_heap_zalloc_tp(hp,tp) ((tp*)mi_heap_zalloc(hp,sizeof(tp))) 666 #define mi_heap_calloc_tp(hp,tp,count) ((tp*)mi_heap_calloc(hp,count,sizeof(tp))) 669 #define mi_heap_mallocn_tp(hp,tp,count) ((tp*)mi_heap_mallocn(hp,count,sizeof(tp))) 672 #define mi_heap_reallocn_tp(hp,p,tp,count) ((tp*)mi_heap_reallocn(p,count,sizeof(tp))) 675 #define mi_heap_recalloc_tp(hp,p,tp,count) ((tp*)mi_heap_recalloc(p,count,sizeof(tp))) 714 typedef struct mi_heap_area_s {
753 typedef enum mi_option_e {
795 void*
mi_recalloc(
void* p,
size_t count,
size_t size);
831 void*
mi_new(std::size_t n) noexcept(
false);
834 void*
mi_new_n(
size_t count,
size_t size) noexcept(
false);
837 void*
mi_new_aligned(std::size_t n, std::align_val_t alignment) noexcept(
false);
size_t mi_usable_size(void *p)
Return the available bytes in a memory block.
void * mi_new_nothrow(size_t n)
like mi_malloc, but when out of memory, use std::get_new_handler but return NULL on failure.
void * mi_reallocn(void *p, size_t count, size_t size)
Re-allocate memory to count elements of size bytes.
void * mi_malloc_aligned(size_t size, size_t alignment)
Allocate size bytes aligned by alignment.
void * mi_recalloc_aligned_at(void *p, size_t newcount, size_t size, size_t alignment, size_t offset)
void mi_stats_reset(void)
Reset statistics.
void * mi_heap_realloc_aligned(mi_heap_t *heap, void *p, size_t newsize, size_t alignment)
+
bool mi_option_is_enabled(mi_option_t option)
void * mi_new_realloc(void *p, size_t newsize)
like mi_realloc(), but when out of memory, use std::get_new_handler and raise std::bad_alloc exceptio...
void * mi_recalloc(void *p, size_t count, size_t size)
Re-allocate memory to count elements of size bytes, with extra memory initialized to zero.
void * mi_mallocn(size_t count, size_t size)
Allocate count elements of size bytes.
size_t mi_malloc_size(const void *p)
+
void mi_option_set_enabled(mi_option_t option, bool enable)
int mi_posix_memalign(void **p, size_t alignment, size_t size)
void mi_stats_merge(void)
Merge thread local statistics with the main statistics and reset.
void * mi_new_n(size_t count, size_t size) noexcept(false)
like mi_mallocn(), but when out of memory, use std::get_new_handler and raise std::bad_alloc exceptio...
void mi_option_set_default(mi_option_t option, long value)
+
void mi_stats_print_out(mi_output_fun *out, void *arg)
Print the main statistics.
void() mi_error_fun(int err, void *arg)
Type of error callback functions.
Definition: mimalloc-doc.h:383
void * mi_rezalloc(void *p, size_t newsize)
Eagerly commit segments (4MiB) (enabled by default).
Definition: mimalloc-doc.h:759
@@ -130,6 +132,7 @@ $(document).ready(function(){initNavTree('mimalloc-doc_8h_source.html','');});
void * mi_realloc_aligned_at(void *p, size_t newsize, size_t alignment, size_t offset)
void * blocks
start of the area containing heap blocks
Definition: mimalloc-doc.h:715
void * mi_realloc_aligned(void *p, size_t newsize, size_t alignment)
+
void mi_option_enable(mi_option_t option)
int mi__posix_memalign(void **p, size_t alignment, size_t size)
void mi_free(void *p)
Free previously allocated memory.
char * mi_heap_strdup(mi_heap_t *heap, const char *s)
Duplicate a string in a specific heap.
@@ -141,6 +144,7 @@ $(document).ready(function(){initNavTree('mimalloc-doc_8h_source.html','');});
char * mi_strndup(const char *s, size_t n)
Allocate and duplicate a string up to n bytes.
void * mi_expand(void *p, size_t newsize)
Try to re-allocate memory to newsize bytes in place.
void * mi_pvalloc(size_t size)
+
void mi_option_set_enabled_default(mi_option_t option, bool enable)
void * mi_heap_rezalloc_aligned_at(mi_heap_t *heap, void *p, size_t newsize, size_t alignment, size_t offset)
void * mi_zalloc(size_t size)
Allocate zero-initialized size bytes.
void * mi_heap_rezalloc(mi_heap_t *heap, void *p, size_t newsize)
@@ -153,7 +157,6 @@ $(document).ready(function(){initNavTree('mimalloc-doc_8h_source.html','');});
int mi_reserve_huge_os_pages_interleave(size_t pages, size_t numa_nodes, size_t timeout_msecs)
Reserve pages of huge OS pages (1GiB) evenly divided over numa_nodes nodes, but stops after at most t...
void() mi_deferred_free_fun(bool force, unsigned long long heartbeat, void *arg)
Type of deferred free functions.
Definition: mimalloc-doc.h:344
bool mi_is_in_heap_region(const void *p)
Is a pointer part of our heap?
-
void mi_option_enable(mi_option_t option, bool enable)
void * mi_new_aligned(std::size_t n, std::align_val_t alignment) noexcept(false)
like mi_malloc_aligned(), but when out of memory, use std::get_new_handler and raise std::bad_alloc e...
void * mi_realloc(void *p, size_t newsize)
Re-allocate memory to newsize bytes.
The number of huge OS pages (1GiB in size) to reserve at the start of the program.
Definition: mimalloc-doc.h:762
@@ -165,7 +168,6 @@ $(document).ready(function(){initNavTree('mimalloc-doc_8h_source.html','');});
bool mi_heap_visit_blocks(const mi_heap_t *heap, bool visit_all_blocks, mi_block_visit_fun *visitor, void *arg)
Visit all areas and blocks in a heap.
Pretend there are at most N NUMA nodes.
Definition: mimalloc-doc.h:767
void * mi_malloc(size_t size)
Allocate size bytes.
-
bool mi_option_enabled(mi_option_t option)
void mi_register_error(mi_error_fun *errfun, void *arg)
Register an error callback function.
Experimental.
Definition: mimalloc-doc.h:768
char * mi_heap_strndup(mi_heap_t *heap, const char *s, size_t n)
Duplicate a string of at most length n in a specific heap.
@@ -173,7 +175,7 @@ $(document).ready(function(){initNavTree('mimalloc-doc_8h_source.html','');});
void * mi_heap_recalloc(mi_heap_t *heap, void *p, size_t newcount, size_t size)
void * mi_heap_malloc_aligned_at(mi_heap_t *heap, size_t size, size_t alignment, size_t offset)
char * mi_realpath(const char *fname, char *resolved_name)
Resolve a file path name.
-
Print error messages to stderr.
Definition: mimalloc-doc.h:756
+
Print error messages to stderr.
Definition: mimalloc-doc.h:755
Experimental.
Definition: mimalloc-doc.h:765
void * mi_heap_rezalloc_aligned(mi_heap_t *heap, void *p, size_t newsize, size_t alignment)
void * mi_new_aligned_nothrow(size_t n, size_t alignment)
like mi_malloc_aligned, but when out of memory, use std::get_new_handler but return NULL on failure.
@@ -189,17 +191,18 @@ $(document).ready(function(){initNavTree('mimalloc-doc_8h_source.html','');});
OS tag to assign to mimalloc'd memory.
Definition: mimalloc-doc.h:770
mi_heap_t * mi_heap_get_default()
Get the default heap that is used for mi_malloc() et al.
int mi_reserve_huge_os_pages_at(size_t pages, int numa_node, size_t timeout_msecs)
Reserve pages of huge OS pages (1GiB) at a specific numa_node, but stops after at most timeout_msecs ...
+
void mi_option_disable(mi_option_t option)
void * mi_aligned_alloc(size_t alignment, size_t size)
void * mi_valloc(size_t size)
void mi_thread_init(void)
Initialize mimalloc on a thread.
size_t mi_good_size(size_t size)
Return the used allocation size.
-
void mi_stats_print(void *out)
Print the main statistics.
+
void mi_stats_print(void *out)
Deprecated.
Experimental.
Definition: mimalloc-doc.h:769
void * mi_heap_recalloc_aligned(mi_heap_t *heap, void *p, size_t newcount, size_t size, size_t alignment)
void * mi_heap_mallocn(mi_heap_t *heap, size_t count, size_t size)
Allocate count elements in a specific heap.
An area of heap space contains blocks of a single size.
Definition: mimalloc-doc.h:714
void mi_thread_stats_print_out(mi_output_fun *out, void *arg)
Print out heap statistics for this thread.
-
Print statistics to stderr when the program is done.
Definition: mimalloc-doc.h:755
+
Print statistics to stderr when the program is done.
Definition: mimalloc-doc.h:756
void * mi_zalloc_aligned(size_t size, size_t alignment)
size_t reserved
bytes reserved for this area
Definition: mimalloc-doc.h:716
struct mi_heap_s mi_heap_t
Type of first-class heaps.
Definition: mimalloc-doc.h:507
@@ -213,7 +216,7 @@ $(document).ready(function(){initNavTree('mimalloc-doc_8h_source.html','');});
Use large OS pages (2MiB in size) if possible.
Definition: mimalloc-doc.h:761
void * mi_heap_reallocn(mi_heap_t *heap, void *p, size_t count, size_t size)
void mi_register_output(mi_output_fun *out, void *arg)
Register an output function.
-
std::allocator implementation for mimalloc for use in STL containers.
Definition: mimalloc-doc.h:856
+
std::allocator implementation for mimalloc for use in STL containers.
Definition: mimalloc-doc.h:858
void * mi_heap_malloc_small(mi_heap_t *heap, size_t size)
Allocate a small object in a specific heap.
void * mi_heap_realloc(mi_heap_t *heap, void *p, size_t newsize)
size_t mi_malloc_usable_size(const void *p)
diff --git a/docs/navtreeindex0.js b/docs/navtreeindex0.js
index 047d6dbc..51be8fb7 100644
--- a/docs/navtreeindex0.js
+++ b/docs/navtreeindex0.js
@@ -43,13 +43,13 @@ var NAVTREEINDEX0 =
"group__extended.html#ga1ea64283508718d9d645c38efc2f4305":[5,1,0],
"group__extended.html#ga220f29f40a44404b0061c15bc1c31152":[5,1,22],
"group__extended.html#ga251d369cda3f1c2a955c555486ed90e5":[5,1,2],
-"group__extended.html#ga256cc6f13a142deabbadd954a217e228":[5,1,16],
"group__extended.html#ga299dae78d25ce112e384a98b7309c5be":[5,1,1],
"group__extended.html#ga2d126e5c62d3badc35445e5d84166df2":[5,1,15],
"group__extended.html#ga3132f521fb756fc0e8ec0b74fb58df50":[5,1,13],
"group__extended.html#ga3460a6ca91af97be4058f523d3cb8ece":[5,1,9],
"group__extended.html#ga3bb8468b8cfcc6e2a61d98aee85c5f99":[5,1,17],
"group__extended.html#ga421430e2226d7d468529cec457396756":[5,1,4],
+"group__extended.html#ga537f13b299ddf801e49a5a94fde02c79":[5,1,16],
"group__extended.html#ga5f071b10d4df1c3658e04e7fd67a94e6":[5,1,6],
"group__extended.html#ga7136c2e55cb22c98ecf95d08d6debb99":[5,1,8],
"group__extended.html#ga7795a13d20087447281858d2c771cca1":[5,1,12],
@@ -104,14 +104,16 @@ var NAVTREEINDEX0 =
"group__malloc.html#gafdd9d8bb2986e668ba9884f28af38000":[5,0,12],
"group__malloc.html#gafe68ac7c5e24a65cd55c9d6b152211a0":[5,0,6],
"group__options.html":[5,7],
-"group__options.html#ga37988264b915a7db92530cc02d5494cb":[5,7,2],
-"group__options.html#ga6d45a20a3131f18bc351b69763b38ce4":[5,7,1],
-"group__options.html#ga7e8af195cc81d3fa64ccf2662caa565a":[5,7,4],
+"group__options.html#ga04180ae41b0d601421dd62ced40ca050":[5,7,2],
+"group__options.html#ga459ad98f18b3fc9275474807fe0ca188":[5,7,4],
+"group__options.html#ga65518b69ec5d32336b50e07f74b3f629":[5,7,8],
+"group__options.html#ga7e8af195cc81d3fa64ccf2662caa565a":[5,7,3],
"group__options.html#ga7ef623e440e6e5545cb08c94e71e4b90":[5,7,6],
-"group__options.html#gacebe3f6d91b4a50b54eb84e2a1da1b30":[5,7,3],
+"group__options.html#ga9a13d05fcb77489cb06d4d017ebd8bed":[5,7,7],
+"group__options.html#gaebf6ff707a2e688ebb1a2296ca564054":[5,7,1],
"group__options.html#gaf84921c32375e25754dc2ee6a911fa60":[5,7,5],
"group__options.html#gafebf7ed116adb38ae5218bc3ce06884c":[5,7,0],
-"group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca0957ef73b2550764b4840edf48422fda":[5,7,0,0],
+"group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca0957ef73b2550764b4840edf48422fda":[5,7,0,1],
"group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca0ac33a18f6b659fcfaf44efb0bab1b74":[5,7,0,11],
"group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca154fe170131d5212cff57e22b99523c5":[5,7,0,10],
"group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca17a190c25be381142d87e0468c4c068c":[5,7,0,13],
@@ -126,7 +128,7 @@ var NAVTREEINDEX0 =
"group__options.html#ggafebf7ed116adb38ae5218bc3ce06884caca7ed041be3b0b9d0b82432c7bf41af2":[5,7,0,6],
"group__options.html#ggafebf7ed116adb38ae5218bc3ce06884cada854dd272c66342f18a93ee254a2968":[5,7,0,8],
"group__options.html#ggafebf7ed116adb38ae5218bc3ce06884cafb121d30d87591850d5410ccc3a95c6d":[5,7,0,9],
-"group__options.html#ggafebf7ed116adb38ae5218bc3ce06884cafbf4822e5c00732c5984b32a032837f0":[5,7,0,1],
+"group__options.html#ggafebf7ed116adb38ae5218bc3ce06884cafbf4822e5c00732c5984b32a032837f0":[5,7,0,0],
"group__posix.html":[5,8],
"group__posix.html#ga06d07cf357bbac5c73ba5d0c0c421e17":[5,8,7],
"group__posix.html#ga0d28d5cf61e6bfbb18c63092939fe5c9":[5,8,3],
diff --git a/docs/search/all_6.js b/docs/search/all_6.js
index c757cbbf..5c2aa01e 100644
--- a/docs/search/all_6.js
+++ b/docs/search/all_6.js
@@ -80,13 +80,13 @@ var searchData=
['mi_5fnew_5fnothrow',['mi_new_nothrow',['../group__cpp.html#gaeaded64eda71ed6b1d569d3e723abc4a',1,'mimalloc-doc.h']]],
['mi_5fnew_5frealloc',['mi_new_realloc',['../group__cpp.html#gaab78a32f55149e9fbf432d5288e38e1e',1,'mimalloc-doc.h']]],
['mi_5fnew_5freallocn',['mi_new_reallocn',['../group__cpp.html#ga756f4b2bc6a7ecd0a90baea8e90c7907',1,'mimalloc-doc.h']]],
+ ['mi_5foption_5fdisable',['mi_option_disable',['../group__options.html#gaebf6ff707a2e688ebb1a2296ca564054',1,'mimalloc-doc.h']]],
['mi_5foption_5feager_5fcommit',['mi_option_eager_commit',['../group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca1e8de72c93da7ff22d91e1e27b52ac2b',1,'mimalloc-doc.h']]],
['mi_5foption_5feager_5fcommit_5fdelay',['mi_option_eager_commit_delay',['../group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca17a190c25be381142d87e0468c4c068c',1,'mimalloc-doc.h']]],
['mi_5foption_5feager_5fregion_5fcommit',['mi_option_eager_region_commit',['../group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca32ce97ece29f69e82579679cf8a307ad',1,'mimalloc-doc.h']]],
- ['mi_5foption_5fenable',['mi_option_enable',['../group__options.html#ga6d45a20a3131f18bc351b69763b38ce4',1,'mimalloc-doc.h']]],
- ['mi_5foption_5fenable_5fdefault',['mi_option_enable_default',['../group__options.html#ga37988264b915a7db92530cc02d5494cb',1,'mimalloc-doc.h']]],
- ['mi_5foption_5fenabled',['mi_option_enabled',['../group__options.html#gacebe3f6d91b4a50b54eb84e2a1da1b30',1,'mimalloc-doc.h']]],
+ ['mi_5foption_5fenable',['mi_option_enable',['../group__options.html#ga04180ae41b0d601421dd62ced40ca050',1,'mimalloc-doc.h']]],
['mi_5foption_5fget',['mi_option_get',['../group__options.html#ga7e8af195cc81d3fa64ccf2662caa565a',1,'mimalloc-doc.h']]],
+ ['mi_5foption_5fis_5fenabled',['mi_option_is_enabled',['../group__options.html#ga459ad98f18b3fc9275474807fe0ca188',1,'mimalloc-doc.h']]],
['mi_5foption_5flarge_5fos_5fpages',['mi_option_large_os_pages',['../group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca4192d491200d0055df0554d4cf65054e',1,'mimalloc-doc.h']]],
['mi_5foption_5fos_5ftag',['mi_option_os_tag',['../group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca4b74ae2a69e445de6c2361b73c1d14bf',1,'mimalloc-doc.h']]],
['mi_5foption_5fpage_5freset',['mi_option_page_reset',['../group__options.html#ggafebf7ed116adb38ae5218bc3ce06884cada854dd272c66342f18a93ee254a2968',1,'mimalloc-doc.h']]],
@@ -97,6 +97,8 @@ var searchData=
['mi_5foption_5fsegment_5freset',['mi_option_segment_reset',['../group__options.html#ggafebf7ed116adb38ae5218bc3ce06884cafb121d30d87591850d5410ccc3a95c6d',1,'mimalloc-doc.h']]],
['mi_5foption_5fset',['mi_option_set',['../group__options.html#gaf84921c32375e25754dc2ee6a911fa60',1,'mimalloc-doc.h']]],
['mi_5foption_5fset_5fdefault',['mi_option_set_default',['../group__options.html#ga7ef623e440e6e5545cb08c94e71e4b90',1,'mimalloc-doc.h']]],
+ ['mi_5foption_5fset_5fenabled',['mi_option_set_enabled',['../group__options.html#ga9a13d05fcb77489cb06d4d017ebd8bed',1,'mimalloc-doc.h']]],
+ ['mi_5foption_5fset_5fenabled_5fdefault',['mi_option_set_enabled_default',['../group__options.html#ga65518b69ec5d32336b50e07f74b3f629',1,'mimalloc-doc.h']]],
['mi_5foption_5fshow_5ferrors',['mi_option_show_errors',['../group__options.html#ggafebf7ed116adb38ae5218bc3ce06884cafbf4822e5c00732c5984b32a032837f0',1,'mimalloc-doc.h']]],
['mi_5foption_5fshow_5fstats',['mi_option_show_stats',['../group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca0957ef73b2550764b4840edf48422fda',1,'mimalloc-doc.h']]],
['mi_5foption_5ft',['mi_option_t',['../group__options.html#gafebf7ed116adb38ae5218bc3ce06884c',1,'mimalloc-doc.h']]],
@@ -126,7 +128,8 @@ var searchData=
['mi_5frezalloc_5faligned_5fat',['mi_rezalloc_aligned_at',['../group__zeroinit.html#gae8b358c417e61d5307da002702b0a8e1',1,'mimalloc-doc.h']]],
['mi_5fsmall_5fsize_5fmax',['MI_SMALL_SIZE_MAX',['../group__extended.html#ga1ea64283508718d9d645c38efc2f4305',1,'mimalloc-doc.h']]],
['mi_5fstats_5fmerge',['mi_stats_merge',['../group__extended.html#ga854b1de8cb067c7316286c28b2fcd3d1',1,'mimalloc-doc.h']]],
- ['mi_5fstats_5fprint',['mi_stats_print',['../group__extended.html#ga2d126e5c62d3badc35445e5d84166df2',1,'mi_stats_print(void *out): mimalloc-doc.h'],['../group__extended.html#ga256cc6f13a142deabbadd954a217e228',1,'mi_stats_print(mi_output_fun *out, void *arg): mimalloc-doc.h']]],
+ ['mi_5fstats_5fprint',['mi_stats_print',['../group__extended.html#ga2d126e5c62d3badc35445e5d84166df2',1,'mimalloc-doc.h']]],
+ ['mi_5fstats_5fprint_5fout',['mi_stats_print_out',['../group__extended.html#ga537f13b299ddf801e49a5a94fde02c79',1,'mimalloc-doc.h']]],
['mi_5fstats_5freset',['mi_stats_reset',['../group__extended.html#ga3bb8468b8cfcc6e2a61d98aee85c5f99',1,'mimalloc-doc.h']]],
['mi_5fstl_5fallocator',['mi_stl_allocator',['../group__cpp.html#structmi__stl__allocator',1,'']]],
['mi_5fstrdup',['mi_strdup',['../group__malloc.html#gac7cffe13f1f458ed16789488bf92b9b2',1,'mimalloc-doc.h']]],
diff --git a/docs/search/functions_0.js b/docs/search/functions_0.js
index 6271797a..f2b65c2d 100644
--- a/docs/search/functions_0.js
+++ b/docs/search/functions_0.js
@@ -66,12 +66,14 @@ var searchData=
['mi_5fnew_5fnothrow',['mi_new_nothrow',['../group__cpp.html#gaeaded64eda71ed6b1d569d3e723abc4a',1,'mimalloc-doc.h']]],
['mi_5fnew_5frealloc',['mi_new_realloc',['../group__cpp.html#gaab78a32f55149e9fbf432d5288e38e1e',1,'mimalloc-doc.h']]],
['mi_5fnew_5freallocn',['mi_new_reallocn',['../group__cpp.html#ga756f4b2bc6a7ecd0a90baea8e90c7907',1,'mimalloc-doc.h']]],
- ['mi_5foption_5fenable',['mi_option_enable',['../group__options.html#ga6d45a20a3131f18bc351b69763b38ce4',1,'mimalloc-doc.h']]],
- ['mi_5foption_5fenable_5fdefault',['mi_option_enable_default',['../group__options.html#ga37988264b915a7db92530cc02d5494cb',1,'mimalloc-doc.h']]],
- ['mi_5foption_5fenabled',['mi_option_enabled',['../group__options.html#gacebe3f6d91b4a50b54eb84e2a1da1b30',1,'mimalloc-doc.h']]],
+ ['mi_5foption_5fdisable',['mi_option_disable',['../group__options.html#gaebf6ff707a2e688ebb1a2296ca564054',1,'mimalloc-doc.h']]],
+ ['mi_5foption_5fenable',['mi_option_enable',['../group__options.html#ga04180ae41b0d601421dd62ced40ca050',1,'mimalloc-doc.h']]],
['mi_5foption_5fget',['mi_option_get',['../group__options.html#ga7e8af195cc81d3fa64ccf2662caa565a',1,'mimalloc-doc.h']]],
+ ['mi_5foption_5fis_5fenabled',['mi_option_is_enabled',['../group__options.html#ga459ad98f18b3fc9275474807fe0ca188',1,'mimalloc-doc.h']]],
['mi_5foption_5fset',['mi_option_set',['../group__options.html#gaf84921c32375e25754dc2ee6a911fa60',1,'mimalloc-doc.h']]],
['mi_5foption_5fset_5fdefault',['mi_option_set_default',['../group__options.html#ga7ef623e440e6e5545cb08c94e71e4b90',1,'mimalloc-doc.h']]],
+ ['mi_5foption_5fset_5fenabled',['mi_option_set_enabled',['../group__options.html#ga9a13d05fcb77489cb06d4d017ebd8bed',1,'mimalloc-doc.h']]],
+ ['mi_5foption_5fset_5fenabled_5fdefault',['mi_option_set_enabled_default',['../group__options.html#ga65518b69ec5d32336b50e07f74b3f629',1,'mimalloc-doc.h']]],
['mi_5fposix_5fmemalign',['mi_posix_memalign',['../group__posix.html#gacff84f226ba9feb2031b8992e5579447',1,'mimalloc-doc.h']]],
['mi_5fpvalloc',['mi_pvalloc',['../group__posix.html#gaeb325c39b887d3b90d85d1eb1712fb1e',1,'mimalloc-doc.h']]],
['mi_5frealloc',['mi_realloc',['../group__malloc.html#gaf11eb497da57bdfb2de65eb191c69db6',1,'mimalloc-doc.h']]],
@@ -93,7 +95,8 @@ var searchData=
['mi_5frezalloc_5faligned',['mi_rezalloc_aligned',['../group__zeroinit.html#gacd71a7bce96aab38ae6de17af2eb2cf0',1,'mimalloc-doc.h']]],
['mi_5frezalloc_5faligned_5fat',['mi_rezalloc_aligned_at',['../group__zeroinit.html#gae8b358c417e61d5307da002702b0a8e1',1,'mimalloc-doc.h']]],
['mi_5fstats_5fmerge',['mi_stats_merge',['../group__extended.html#ga854b1de8cb067c7316286c28b2fcd3d1',1,'mimalloc-doc.h']]],
- ['mi_5fstats_5fprint',['mi_stats_print',['../group__extended.html#ga2d126e5c62d3badc35445e5d84166df2',1,'mi_stats_print(void *out): mimalloc-doc.h'],['../group__extended.html#ga256cc6f13a142deabbadd954a217e228',1,'mi_stats_print(mi_output_fun *out, void *arg): mimalloc-doc.h']]],
+ ['mi_5fstats_5fprint',['mi_stats_print',['../group__extended.html#ga2d126e5c62d3badc35445e5d84166df2',1,'mimalloc-doc.h']]],
+ ['mi_5fstats_5fprint_5fout',['mi_stats_print_out',['../group__extended.html#ga537f13b299ddf801e49a5a94fde02c79',1,'mimalloc-doc.h']]],
['mi_5fstats_5freset',['mi_stats_reset',['../group__extended.html#ga3bb8468b8cfcc6e2a61d98aee85c5f99',1,'mimalloc-doc.h']]],
['mi_5fstrdup',['mi_strdup',['../group__malloc.html#gac7cffe13f1f458ed16789488bf92b9b2',1,'mimalloc-doc.h']]],
['mi_5fstrndup',['mi_strndup',['../group__malloc.html#gaaabf971c2571891433477e2d21a35266',1,'mimalloc-doc.h']]],
diff --git a/include/mimalloc-internal.h b/include/mimalloc-internal.h
index 4ecc08bc..3ad0dc31 100644
--- a/include/mimalloc-internal.h
+++ b/include/mimalloc-internal.h
@@ -257,23 +257,28 @@ static inline bool mi_malloc_satisfies_alignment(size_t alignment, size_t size)
}
// Overflow detecting multiply
-static inline bool mi_mul_overflow(size_t count, size_t size, size_t* total) {
#if __has_builtin(__builtin_umul_overflow) || __GNUC__ >= 5
-#include
// UINT_MAX, ULONG_MAX
-#if (SIZE_MAX == UINT_MAX)
- return __builtin_umul_overflow(count, size, total);
-#elif (SIZE_MAX == ULONG_MAX)
- return __builtin_umull_overflow(count, size, total);
-#else
- return __builtin_umulll_overflow(count, size, total);
+#include // UINT_MAX, ULONG_MAX
+#if defined(_CLOCK_T) // for Illumos
+#undef _CLOCK_T
#endif
+static inline bool mi_mul_overflow(size_t count, size_t size, size_t* total) {
+ #if (SIZE_MAX == UINT_MAX)
+ return __builtin_umul_overflow(count, size, total);
+ #elif (SIZE_MAX == ULONG_MAX)
+ return __builtin_umull_overflow(count, size, total);
+ #else
+ return __builtin_umulll_overflow(count, size, total);
+ #endif
+}
#else /* __builtin_umul_overflow is unavailable */
+static inline bool mi_mul_overflow(size_t count, size_t size, size_t* total) {
#define MI_MUL_NO_OVERFLOW ((size_t)1 << (4*sizeof(size_t))) // sqrt(SIZE_MAX)
*total = count * size;
return ((size >= MI_MUL_NO_OVERFLOW || count >= MI_MUL_NO_OVERFLOW)
- && size > 0 && (SIZE_MAX / size) < count);
-#endif
+ && size > 0 && (SIZE_MAX / size) < count);
}
+#endif
// Safe multiply `count*size` into `total`; return `true` on overflow.
static inline bool mi_count_size_overflow(size_t count, size_t size, size_t* total) {
diff --git a/src/alloc-override.c b/src/alloc-override.c
index e7e3fc48..347deb6a 100644
--- a/src/alloc-override.c
+++ b/src/alloc-override.c
@@ -182,7 +182,8 @@ void* _aligned_malloc(size_t alignment, size_t size) { return MI_SOURCE_R
// on some glibc `aligned_alloc` is declared `static inline` so we cannot override it (e.g. Conda). This happens
// when _GLIBCXX_HAVE_ALIGNED_ALLOC is not defined. However, in those cases it will use `memalign`, `posix_memalign`,
// or `_aligned_malloc` and we can avoid overriding it ourselves.
-#if _GLIBCXX_HAVE_ALIGNED_ALLOC
+// We should always override if using C compilation. (issue #276)
+#if _GLIBCXX_HAVE_ALIGNED_ALLOC || !defined(__cplusplus)
void* aligned_alloc(size_t alignment, size_t size) { return MI_SOURCE_RET(mi_aligned_alloc, alignment, size); }
#endif
diff --git a/src/alloc.c b/src/alloc.c
index 2ebde59f..58d208d5 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -454,34 +454,45 @@ static void mi_decl_noinline mi_free_generic(const mi_segment_t* segment, bool l
_mi_free_block(page, local, block);
}
-// Free a block
-void mi_free(void* p) mi_attr_noexcept
+// Get the segment data belonging to a pointer
+// This is just a single `and` in assembly but does further checks in debug mode
+// (and secure mode) if this was a valid pointer.
+static inline mi_segment_t* mi_checked_ptr_segment(const void* p, const char* msg)
{
+ UNUSED(msg);
#if (MI_DEBUG>0)
if (mi_unlikely(((uintptr_t)p & (MI_INTPTR_SIZE - 1)) != 0)) {
- _mi_error_message(EINVAL, "trying to free an invalid (unaligned) pointer: %p\n", p);
- return;
+ _mi_error_message(EINVAL, "%s: invalid (unaligned) pointer: %p\n", msg, p);
+ return NULL;
}
#endif
- const mi_segment_t* const segment = _mi_ptr_segment(p);
- if (mi_unlikely(segment == NULL)) return; // checks for (p==NULL)
+ mi_segment_t* const segment = _mi_ptr_segment(p);
+ if (mi_unlikely(segment == NULL)) return NULL; // checks also for (p==NULL)
-#if (MI_DEBUG!=0)
+#if (MI_DEBUG>0)
if (mi_unlikely(!mi_is_in_heap_region(p))) {
- _mi_warning_message("possibly trying to free a pointer that does not point to a valid heap region: %p\n"
- "(this may still be a valid very large allocation (over 64MiB))\n", p);
+ _mi_warning_message("%s: pointer might not point to a valid heap region: %p\n"
+ "(this may still be a valid very large allocation (over 64MiB))\n", msg, p);
if (mi_likely(_mi_ptr_cookie(segment) == segment->cookie)) {
_mi_warning_message("(yes, the previous pointer %p was valid after all)\n", p);
}
}
#endif
-#if (MI_DEBUG!=0 || MI_SECURE>=4)
+#if (MI_DEBUG>0 || MI_SECURE>=4)
if (mi_unlikely(_mi_ptr_cookie(segment) != segment->cookie)) {
- _mi_error_message(EINVAL, "trying to free a pointer that does not point to a valid heap space: %p\n", p);
- return;
+ _mi_error_message(EINVAL, "%s: pointer does not point to a valid heap space: %p\n", p);
}
#endif
+ return segment;
+}
+
+
+// Free a block
+void mi_free(void* p) mi_attr_noexcept
+{
+ const mi_segment_t* const segment = mi_checked_ptr_segment(p,"mi_free");
+ if (mi_unlikely(segment == NULL)) return;
const uintptr_t tid = _mi_thread_id();
mi_page_t* const page = _mi_segment_page_of(segment, p);
@@ -540,9 +551,9 @@ bool _mi_free_delayed_block(mi_block_t* block) {
}
// Bytes available in a block
-size_t mi_usable_size(const void* p) mi_attr_noexcept {
- if (p==NULL) return 0;
- const mi_segment_t* const segment = _mi_ptr_segment(p);
+static size_t _mi_usable_size(const void* p, const char* msg) mi_attr_noexcept {
+ const mi_segment_t* const segment = mi_checked_ptr_segment(p,msg);
+ if (segment==NULL) return 0;
const mi_page_t* const page = _mi_segment_page_of(segment, p);
const mi_block_t* block = (const mi_block_t*)p;
if (mi_unlikely(mi_page_has_aligned(page))) {
@@ -557,6 +568,10 @@ size_t mi_usable_size(const void* p) mi_attr_noexcept {
}
}
+size_t mi_usable_size(const void* p) mi_attr_noexcept {
+ return _mi_usable_size(p, "mi_usable_size");
+}
+
// ------------------------------------------------------
// ensure explicit external inline definitions are emitted!
@@ -581,7 +596,7 @@ void* _mi_externs[] = {
void mi_free_size(void* p, size_t size) mi_attr_noexcept {
UNUSED_RELEASE(size);
- mi_assert(p == NULL || size <= mi_usable_size(p));
+ mi_assert(p == NULL || size <= _mi_usable_size(p,"mi_free_size"));
mi_free(p);
}
@@ -621,14 +636,14 @@ MI_ALLOC_API2(void*, expand, mi_heap_t*, heap, void*, p, size_t, newsize)
UNUSED(__mi_source);
#endif
if (p == NULL) return NULL;
- size_t size = mi_usable_size(p);
+ size_t size = _mi_usable_size(p,"mi_expand");
if (newsize > size) return NULL;
return p; // it fits
}
void* _mi_base_realloc_zero(mi_heap_t* heap, void* p, size_t newsize, bool zero MI_SOURCE_XPARAM) {
if (p == NULL) return _mi_base_malloc_zero(heap,newsize,zero MI_SOURCE_XARG);
- size_t size = mi_usable_size(p);
+ size_t size = _mi_usable_size(p,"mi_realloc");
if (newsize <= size && newsize >= (size / 2)) {
return p; // reallocation still fits and not more than 50% waste
}
diff --git a/src/init.c b/src/init.c
index 1da7a264..de5f382c 100644
--- a/src/init.c
+++ b/src/init.c
@@ -350,8 +350,8 @@ void mi_thread_init(void) mi_attr_noexcept
// don't further initialize for the main thread
if (_mi_is_main_thread()) return;
- mi_heap_t* heap = mi_get_default_heap();
- if (mi_heap_is_initialized(heap)) { _mi_stat_increase(&mi_get_default_heap()->tld->stats.threads, 1); }
+ mi_heap_t* const heap = mi_get_default_heap();
+ if (mi_heap_is_initialized(heap)) { _mi_stat_increase(&heap->tld->stats.threads, 1); }
//_mi_verbose_message("thread init: 0x%zx\n", _mi_thread_id());
}
diff --git a/src/os.c b/src/os.c
index e079ca64..8079e5a0 100644
--- a/src/os.c
+++ b/src/os.c
@@ -23,7 +23,12 @@ terms of the MIT license. A copy of the license can be found in the file
#include // mmap
#include // sysconf
#if defined(__linux__)
+#include
+#if defined(__GLIBC__)
#include // linux mmap flags
+#else
+#include
+#endif
#endif
#if defined(__APPLE__)
#include
@@ -31,6 +36,10 @@ terms of the MIT license. A copy of the license can be found in the file
#include
#endif
#endif
+#if defined(__HAIKU__)
+#define madvise posix_madvise
+#define MADV_DONTNEED POSIX_MADV_DONTNEED
+#endif
#endif
/* -----------------------------------------------------------
@@ -93,6 +102,7 @@ size_t _mi_os_good_alloc_size(size_t size) {
// We use VirtualAlloc2 for aligned allocation, but it is only supported on Windows 10 and Windows Server 2016.
// So, we need to look it up dynamically to run on older systems. (use __stdcall for 32-bit compatibility)
// NtAllocateVirtualAllocEx is used for huge OS page allocation (1GiB)
+//
// We hide MEM_EXTENDED_PARAMETER to compile with older SDK's.
#include
typedef PVOID (__stdcall *PVirtualAlloc2)(HANDLE, PVOID, SIZE_T, ULONG, ULONG, /* MEM_EXTENDED_PARAMETER* */ void*, ULONG);
@@ -100,6 +110,15 @@ typedef NTSTATUS (__stdcall *PNtAllocateVirtualMemoryEx)(HANDLE, PVOID*, SIZE_T*
static PVirtualAlloc2 pVirtualAlloc2 = NULL;
static PNtAllocateVirtualMemoryEx pNtAllocateVirtualMemoryEx = NULL;
+// Similarly, GetNumaProcesorNodeEx is only supported since Windows 7
+#if (_WIN32_WINNT < 0x601) // before Win7
+typedef struct _PROCESSOR_NUMBER { WORD Group; BYTE Number; BYTE Reserved; } PROCESSOR_NUMBER, *PPROCESSOR_NUMBER;
+#endif
+typedef VOID (__stdcall *PGetCurrentProcessorNumberEx)(PPROCESSOR_NUMBER ProcNumber);
+typedef BOOL (__stdcall *PGetNumaProcessorNodeEx)(PPROCESSOR_NUMBER Processor, PUSHORT NodeNumber);
+static PGetCurrentProcessorNumberEx pGetCurrentProcessorNumberEx = NULL;
+static PGetNumaProcessorNodeEx pGetNumaProcessorNodeEx = NULL;
+
static bool mi_win_enable_large_os_pages()
{
if (large_os_page_size > 0) return true;
@@ -150,11 +169,19 @@ void _mi_os_init(void) {
if (pVirtualAlloc2==NULL) pVirtualAlloc2 = (PVirtualAlloc2)(void (*)(void))GetProcAddress(hDll, "VirtualAlloc2");
FreeLibrary(hDll);
}
+ // NtAllocateVirtualMemoryEx is used for huge page allocation
hDll = LoadLibrary(TEXT("ntdll.dll"));
if (hDll != NULL) {
pNtAllocateVirtualMemoryEx = (PNtAllocateVirtualMemoryEx)(void (*)(void))GetProcAddress(hDll, "NtAllocateVirtualMemoryEx");
FreeLibrary(hDll);
}
+ // Try to use Win7+ numa API
+ hDll = LoadLibrary(TEXT("kernel32.dll"));
+ if (hDll != NULL) {
+ pGetCurrentProcessorNumberEx = (PGetCurrentProcessorNumberEx)(void (*)(void))GetProcAddress(hDll, "GetCurrentProcessorNumberEx");
+ pGetNumaProcessorNodeEx = (PGetNumaProcessorNodeEx)(void (*)(void))GetProcAddress(hDll, "GetNumaProcessorNodeEx");
+ FreeLibrary(hDll);
+ }
if (mi_option_is_enabled(mi_option_large_os_pages) || mi_option_is_enabled(mi_option_reserve_huge_os_pages)) {
mi_win_enable_large_os_pages();
}
@@ -401,6 +428,16 @@ static void* mi_unix_mmap(void* addr, size_t size, size_t try_alignment, int pro
};
}
#endif
+ #if defined(__sun)
+ if (allow_large && use_large_os_page(size, try_alignment)) {
+ struct memcntl_mha cmd = {0};
+ cmd.mha_pagesize = large_os_page_size;
+ cmd.mha_cmd = MHA_MAPSIZE_VA;
+ if (memcntl(p, size, MC_HAT_ADVISE, (caddr_t)&cmd, 0, 0) == 0) {
+ *is_large = true;
+ }
+ }
+ #endif
}
if (p == NULL) {
_mi_warning_message("unable to allocate OS memory (%zu bytes, error code: %i, address: %p, large only: %d, allow large: %d)\n", size, errno, addr, large_only, allow_large);
@@ -882,7 +919,7 @@ static void* mi_os_alloc_huge_os_pagesx(void* addr, size_t size, int numa_node)
return VirtualAlloc(addr, size, flags, PAGE_READWRITE);
}
-#elif defined(MI_OS_USE_MMAP) && (MI_INTPTR_SIZE >= 8)
+#elif defined(MI_OS_USE_MMAP) && (MI_INTPTR_SIZE >= 8) && !defined(__HAIKU__)
#include
#ifndef MPOL_PREFERRED
#define MPOL_PREFERRED 1
@@ -1025,24 +1062,31 @@ void _mi_os_free_huge_pages(void* p, size_t size, mi_stats_t* stats) {
/* ----------------------------------------------------------------------------
Support NUMA aware allocation
-----------------------------------------------------------------------------*/
-#ifdef _WIN32
- #if (_WIN32_WINNT < 0x601) // before Win7
- typedef struct _PROCESSOR_NUMBER { WORD Group; BYTE Number; BYTE Reserved; } PROCESSOR_NUMBER, *PPROCESSOR_NUMBER;
- WINBASEAPI VOID WINAPI GetCurrentProcessorNumberEx(_Out_ PPROCESSOR_NUMBER ProcNumber);
- WINBASEAPI BOOL WINAPI GetNumaProcessorNodeEx(_In_ PPROCESSOR_NUMBER Processor, _Out_ PUSHORT NodeNumber);
- #endif
+#ifdef _WIN32
static size_t mi_os_numa_nodex() {
- PROCESSOR_NUMBER pnum;
USHORT numa_node = 0;
- GetCurrentProcessorNumberEx(&pnum);
- GetNumaProcessorNodeEx(&pnum,&numa_node);
+ if (pGetCurrentProcessorNumberEx != NULL && pGetNumaProcessorNodeEx != NULL) {
+ // Extended API is supported
+ PROCESSOR_NUMBER pnum;
+ (*pGetCurrentProcessorNumberEx)(&pnum);
+ USHORT nnode = 0;
+ BOOL ok = (*pGetNumaProcessorNodeEx)(&pnum, &nnode);
+ if (ok) numa_node = nnode;
+ }
+ else {
+ // Vista or earlier, use older API that is limited to 64 processors. Issue #277
+ DWORD pnum = GetCurrentProcessorNumber();
+ UCHAR nnode = 0;
+ BOOL ok = GetNumaProcessorNode((UCHAR)pnum, &nnode);
+ if (ok) numa_node = nnode;
+ }
return numa_node;
}
static size_t mi_os_numa_node_countx(void) {
ULONG numa_max = 0;
GetNumaHighestNodeNumber(&numa_max);
- return (numa_max + 1);
+ return ((size_t)numa_max + 1);
}
#elif defined(__linux__)
#include // getcpu
diff --git a/src/random.c b/src/random.c
index b3dbf4f8..2a96ccf6 100644
--- a/src/random.c
+++ b/src/random.c
@@ -178,7 +178,7 @@ static bool os_random_buf(void* buf, size_t buf_len) {
*/
#elif defined(ANDROID) || defined(XP_DARWIN) || defined(__APPLE__) || defined(__DragonFly__) || \
defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || \
- defined(__wasi__)
+ defined(__sun) || defined(__wasi__)
#include
static bool os_random_buf(void* buf, size_t buf_len) {
arc4random_buf(buf, buf_len);
diff --git a/test/main-override-static.c b/test/main-override-static.c
index 0e54892c..1dc5fbcf 100644
--- a/test/main-override-static.c
+++ b/test/main-override-static.c
@@ -13,6 +13,7 @@ static void corrupt_free();
static void block_overflow1();
static void block_overflow2();
static void dangling_ptr_write();
+static void invalid_free();
int main() {
mi_version();
@@ -24,6 +25,8 @@ int main() {
// block_overflow1();
// block_overflow2();
// dangling_ptr_write();
+ invalid_free();
+
void* (*fun_mimalloc)(size_t) = &mi_malloc;
void* p1 = malloc(78);
@@ -49,6 +52,11 @@ int main() {
return 0;
}
+static void invalid_free() {
+ free((void*)0xBADBEEF);
+ realloc((void*)0xBADBEEF,10);
+}
+
static void block_overflow1() {
uint8_t* p = (uint8_t*)mi_malloc(17);
p[18] = 0;