From d5475a58a1a3cb7f0e5154e49cd7f94d1038a7d0 Mon Sep 17 00:00:00 2001 From: Wanja Vogel Date: Wed, 10 Jun 2020 07:47:50 +0200 Subject: [PATCH 01/13] fix: avoid warning warning C26451: Arithmetic overflow: Using operator '+' on a 4 byte value and then casting the result to a 8 byte value. Cast the value to the wider type before calling operator '+' to avoid overflow (io.2). --- src/os.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/os.c b/src/os.c index f33cfbc3..f7d5f7b1 100644 --- a/src/os.c +++ b/src/os.c @@ -1036,7 +1036,7 @@ static size_t mi_os_numa_nodex() { 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 From 2599512e8f60a5d3bdd81e6590e5a2402a8aaff1 Mon Sep 17 00:00:00 2001 From: Wanja Vogel Date: Thu, 18 Jun 2020 18:20:26 +0200 Subject: [PATCH 02/13] use stored pointer #257 --- src/init.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/init.c b/src/init.c index 622a5eb0..602a2f7a 100644 --- a/src/init.c +++ b/src/init.c @@ -346,8 +346,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()); } From 7e48eb033cccccab87c3ee6e23841a75a3108936 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Sun, 28 Jun 2020 13:53:45 +0000 Subject: [PATCH 03/13] haiku support. TLS unsupported thus disabled. --- CMakeLists.txt | 2 +- src/os.c | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e37efcb0..43ceb7fa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -145,7 +145,7 @@ if(CMAKE_C_COMPILER_ID MATCHES "Intel") list(APPEND mi_cflags -Wall -fvisibility=hidden) endif() -if(CMAKE_C_COMPILER_ID MATCHES "AppleClang|Clang|GNU|Intel") +if(CMAKE_C_COMPILER_ID MATCHES "AppleClang|Clang|GNU|Intel" AND NOT CMAKE_SYSTEM_NAME MATCHES "Haiku") if(MI_LOCAL_DYNAMIC_TLS MATCHES "ON") list(APPEND mi_cflags -ftls-model=local-dynamic) else() diff --git a/src/os.c b/src/os.c index 1d6df907..86ea6cd1 100644 --- a/src/os.c +++ b/src/os.c @@ -31,6 +31,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 /* ----------------------------------------------------------- @@ -882,7 +886,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 From 82f4e5c48e7c73a36abef8f487aaf6b8440d2c02 Mon Sep 17 00:00:00 2001 From: Wanja Vogel Date: Wed, 8 Jul 2020 21:45:43 +0200 Subject: [PATCH 04/13] Update documentation-header to current source code after 03d9946 --- doc/mimalloc-doc.h | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/doc/mimalloc-doc.h b/doc/mimalloc-doc.h index 67f4fe95..2e74fb02 100644 --- a/doc/mimalloc-doc.h +++ b/doc/mimalloc-doc.h @@ -752,8 +752,8 @@ bool mi_heap_visit_blocks(const mi_heap_t* heap, bool visit_all_blocks, mi_block /// Runtime options. typedef enum mi_option_e { // stable options - mi_option_show_stats, ///< Print statistics to `stderr` when the program is done. mi_option_show_errors, ///< Print error messages to `stderr`. + mi_option_show_stats, ///< Print statistics to `stderr` when the program is done. mi_option_verbose, ///< Print verbose messages to `stderr`. // the following options are experimental mi_option_eager_commit, ///< Eagerly commit segments (4MiB) (enabled by default). @@ -772,9 +772,11 @@ typedef enum mi_option_e { } mi_option_t; -bool mi_option_enabled(mi_option_t option); -void mi_option_enable(mi_option_t option, bool enable); -void mi_option_enable_default(mi_option_t option, bool enable); +bool mi_option_is_enabled(mi_option_t option); +void mi_option_enable(mi_option_t option); +void mi_option_disable(mi_option_t option); +void mi_option_set_enabled(mi_option_t option, bool enable); +void mi_option_set_enabled_default(mi_option_t option, bool enable); long mi_option_get(mi_option_t option); void mi_option_set(mi_option_t option, long value); From a60824190092741ad7c82504d0c9655340d74bcc Mon Sep 17 00:00:00 2001 From: Wanja Vogel Date: Wed, 8 Jul 2020 21:45:43 +0200 Subject: [PATCH 05/13] Update documentation-header to current source code after 03d9946 fix #266 --- doc/mimalloc-doc.h | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/doc/mimalloc-doc.h b/doc/mimalloc-doc.h index 67f4fe95..2e74fb02 100644 --- a/doc/mimalloc-doc.h +++ b/doc/mimalloc-doc.h @@ -752,8 +752,8 @@ bool mi_heap_visit_blocks(const mi_heap_t* heap, bool visit_all_blocks, mi_block /// Runtime options. typedef enum mi_option_e { // stable options - mi_option_show_stats, ///< Print statistics to `stderr` when the program is done. mi_option_show_errors, ///< Print error messages to `stderr`. + mi_option_show_stats, ///< Print statistics to `stderr` when the program is done. mi_option_verbose, ///< Print verbose messages to `stderr`. // the following options are experimental mi_option_eager_commit, ///< Eagerly commit segments (4MiB) (enabled by default). @@ -772,9 +772,11 @@ typedef enum mi_option_e { } mi_option_t; -bool mi_option_enabled(mi_option_t option); -void mi_option_enable(mi_option_t option, bool enable); -void mi_option_enable_default(mi_option_t option, bool enable); +bool mi_option_is_enabled(mi_option_t option); +void mi_option_enable(mi_option_t option); +void mi_option_disable(mi_option_t option); +void mi_option_set_enabled(mi_option_t option, bool enable); +void mi_option_set_enabled_default(mi_option_t option, bool enable); long mi_option_get(mi_option_t option); void mi_option_set(mi_option_t option, long value); From b9a7f5cfaed087cc6a5b5fc02862234fa771eebf Mon Sep 17 00:00:00 2001 From: Tyler Young Date: Thu, 9 Jul 2020 10:58:47 -0400 Subject: [PATCH 06/13] fix mman.h ref --- src/os.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/os.c b/src/os.c index f7d5f7b1..3c14bb74 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 From 0c550d1626e2282a7dbd211342699abd6e4178f0 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Fri, 10 Jul 2020 03:23:20 +0100 Subject: [PATCH 07/13] illumos support/build fix and large page support --- include/mimalloc-internal.h | 4 ++++ src/os.c | 10 ++++++++++ src/random.c | 2 +- 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/include/mimalloc-internal.h b/include/mimalloc-internal.h index 35413315..c0a084c2 100644 --- a/include/mimalloc-internal.h +++ b/include/mimalloc-internal.h @@ -241,6 +241,10 @@ static inline bool mi_malloc_satisfies_alignment(size_t alignment, size_t size) 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 defined(_CLOCK_T) +#undef _CLOCK_T +#endif + #if (SIZE_MAX == UINT_MAX) return __builtin_umul_overflow(count, size, total); #elif (SIZE_MAX == ULONG_MAX) diff --git a/src/os.c b/src/os.c index 1d6df907..08283ef5 100644 --- a/src/os.c +++ b/src/os.c @@ -401,6 +401,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); 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); From 892ec12611bdcc9444eb814d232bdf8546845261 Mon Sep 17 00:00:00 2001 From: daan Date: Mon, 20 Jul 2020 11:10:45 -0700 Subject: [PATCH 08/13] Support Windows Vista and XP for NUMA aware alloction (issue #277) --- src/os.c | 43 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 34 insertions(+), 9 deletions(-) diff --git a/src/os.c b/src/os.c index 1d6df907..83dce34b 100644 --- a/src/os.c +++ b/src/os.c @@ -93,6 +93,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 +101,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 +160,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(); } @@ -1025,17 +1043,24 @@ 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; } From 5f51c97fbd438ad48dfd8bdf4b9b6166a864da22 Mon Sep 17 00:00:00 2001 From: daan Date: Mon, 20 Jul 2020 11:27:42 -0700 Subject: [PATCH 09/13] override aligned_alloc always if using C compilation (issue #276) --- src/alloc-override.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/alloc-override.c b/src/alloc-override.c index a09153c5..ae7ad7dd 100644 --- a/src/alloc-override.c +++ b/src/alloc-override.c @@ -183,7 +183,8 @@ void* _aligned_malloc(size_t alignment, size_t size) { return mi_aligne // 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_aligned_alloc(alignment, size); } #endif From 8769082d63e2b7caf392c62e25fda75f36604f90 Mon Sep 17 00:00:00 2001 From: daan Date: Mon, 20 Jul 2020 14:33:03 -0700 Subject: [PATCH 10/13] add pointer validity check in debug mode for mi_usable_size/mi_realloc/mi_expand. Issue #269 --- src/alloc.c | 77 ++++++++++++++++++++++--------------- test/main-override-static.c | 9 ++++- 2 files changed, 54 insertions(+), 32 deletions(-) diff --git a/src/alloc.c b/src/alloc.c index 607d15b6..57034522 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -387,34 +387,45 @@ static void mi_decl_noinline mi_free_generic(const mi_segment_t* segment, bool l _mi_free_block(page, local, block); } +// 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, "%s: invalid (unaligned) pointer: %p\n", msg, p); + return NULL; + } +#endif + + 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_unlikely(!mi_is_in_heap_region(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_unlikely(_mi_ptr_cookie(segment) != segment->cookie)) { + _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 { -#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; - } -#endif - - const mi_segment_t* const segment = _mi_ptr_segment(p); - if (mi_unlikely(segment == NULL)) return; // checks for (p==NULL) - -#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); - 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_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; - } -#endif + 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); @@ -473,9 +484,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))) { @@ -490,6 +501,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! @@ -513,7 +528,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); } @@ -553,14 +568,14 @@ mi_decl_restrict void* mi_mallocn(size_t count, size_t size) mi_attr_noexcept { // Expand in place or fail void* mi_expand(void* p, size_t newsize) mi_attr_noexcept { 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_heap_realloc_zero(mi_heap_t* heap, void* p, size_t newsize, bool zero) { if (p == NULL) return _mi_heap_malloc_zero(heap,newsize,zero); - 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/test/main-override-static.c b/test/main-override-static.c index 9243fd21..f738c517 100644 --- a/test/main-override-static.c +++ b/test/main-override-static.c @@ -11,6 +11,7 @@ static void double_free1(); static void double_free2(); static void corrupt_free(); static void block_overflow1(); +static void invalid_free(); int main() { mi_version(); @@ -19,7 +20,8 @@ int main() { // double_free1(); // double_free2(); // corrupt_free(); - block_overflow1(); + // block_overflow1(); + invalid_free(); void* p1 = malloc(78); void* p2 = malloc(24); @@ -43,6 +45,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; From 01da02631456f659101875d34812bc8a08ec0690 Mon Sep 17 00:00:00 2001 From: daan Date: Tue, 21 Jul 2020 09:10:45 -0700 Subject: [PATCH 11/13] add option to build with thread sanitizer --- CMakeLists.txt | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index e37efcb0..4eeaccf3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,6 +19,7 @@ option(MI_BUILD_SHARED "Build shared library" ON) option(MI_BUILD_STATIC "Build static library" ON) option(MI_BUILD_OBJECT "Build object library" ON) option(MI_BUILD_TESTS "Build test executables" ON) +option(MI_DEBUG_TSAN "Build with thread sanitizer (needs clang)" OFF) option(MI_CHECK_FULL "Use full internal invariant checking in DEBUG mode (deprecated, use MI_DEBUG_FULL instead)" OFF) include("cmake/mimalloc-config-version.cmake") @@ -133,6 +134,16 @@ if(MI_USE_CXX MATCHES "ON") endif() endif() +if(MI_DEBUG_TSAN MATCHES "ON") + if(CMAKE_C_COMPILER_ID MATCHES "Clang") + message(STATUS "Build with thread sanitizer (MI_DEBUG_TSAN=ON)") + list(APPEND mi_cflags -fsanitize=thread -g) + list(APPEND CMAKE_EXE_LINKER_FLAGS -fsanitize=thread) + else() + message(WARNING "Can only use thread sanitizer with clang (MI_DEBUG_TSAN=ON but ignored)") + endif() +endif() + # Compiler flags if(CMAKE_C_COMPILER_ID MATCHES "AppleClang|Clang|GNU") list(APPEND mi_cflags -Wall -Wextra -Wno-unknown-pragmas -fvisibility=hidden) From 76756ad63c30e04ccb361809026242f38a2d24d7 Mon Sep 17 00:00:00 2001 From: daan Date: Tue, 21 Jul 2020 18:27:54 -0700 Subject: [PATCH 12/13] update documentation --- doc/mimalloc-doc.h | 4 +- docs/group__extended.html | 18 ++-- docs/group__extended.js | 2 +- docs/group__options.html | 176 +++++++++++++++++++------------ docs/group__options.js | 12 ++- docs/mimalloc-doc_8h_source.html | 19 ++-- docs/navtreeindex0.js | 16 +-- docs/search/all_6.js | 11 +- docs/search/functions_0.js | 11 +- 9 files changed, 161 insertions(+), 108 deletions(-) diff --git a/doc/mimalloc-doc.h b/doc/mimalloc-doc.h index 2e74fb02..f11a97b0 100644 --- a/doc/mimalloc-doc.h +++ b/doc/mimalloc-doc.h @@ -298,7 +298,7 @@ size_t mi_good_size(size_t size); /// resource usage by calling this every once in a while. void mi_collect(bool force); -/// Print the main statistics. +/// Deprecated /// @param out Ignored, outputs to the registered output function or stderr by default. /// /// Most detailed when using a debug build. @@ -309,7 +309,7 @@ void mi_stats_print(void* out); /// @param arg Optional argument passed to \a out (if not \a NULL) /// /// Most detailed when using a debug build. -void mi_stats_print(mi_output_fun* out, void* arg); +void mi_stats_print_out(mi_output_fun* out, void* arg); /// Reset statistics. void mi_stats_reset(void); diff --git a/docs/group__extended.html b/docs/group__extended.html index 325d62bf..575288ab 100644 --- a/docs/group__extended.html +++ b/docs/group__extended.html @@ -146,11 +146,11 @@ Functions  Eagerly free memory. More...
  void mi_stats_print (void *out) - Print the main statistics. More...
+ Deprecated. More...
  -void mi_stats_print (mi_output_fun *out, void *arg) - Print the main statistics. More...
-  +void mi_stats_print_out (mi_output_fun *out, void *arg) + Print the main statistics. More...
+  void mi_stats_reset (void)  Reset statistics. More...
  @@ -646,7 +646,7 @@ Functions -

◆ mi_stats_print() [1/2]

+

◆ mi_stats_print()

@@ -661,7 +661,7 @@ Functions
-

Print the main statistics.

+

Deprecated.

Parameters
@@ -672,14 +672,14 @@ Functions - -

◆ mi_stats_print() [2/2]

+ +

◆ mi_stats_print_out()

outIgnored, outputs to the registered output function or stderr by default.
- + diff --git a/docs/group__extended.js b/docs/group__extended.js index ff8891b2..594cadb9 100644 --- a/docs/group__extended.js +++ b/docs/group__extended.js @@ -16,7 +16,7 @@ var group__extended = [ "mi_reserve_huge_os_pages_interleave", "group__extended.html#ga3132f521fb756fc0e8ec0b74fb58df50", null ], [ "mi_stats_merge", "group__extended.html#ga854b1de8cb067c7316286c28b2fcd3d1", null ], [ "mi_stats_print", "group__extended.html#ga2d126e5c62d3badc35445e5d84166df2", null ], - [ "mi_stats_print", "group__extended.html#ga256cc6f13a142deabbadd954a217e228", null ], + [ "mi_stats_print_out", "group__extended.html#ga537f13b299ddf801e49a5a94fde02c79", null ], [ "mi_stats_reset", "group__extended.html#ga3bb8468b8cfcc6e2a61d98aee85c5f99", null ], [ "mi_thread_done", "group__extended.html#ga0ae4581e85453456a0d658b2b98bf7bf", null ], [ "mi_thread_init", "group__extended.html#gaf8e73efc2cbca9ebfdfb166983a04c17", null ], diff --git a/docs/group__options.html b/docs/group__options.html index 5e45d7bd..9425765e 100644 --- a/docs/group__options.html +++ b/docs/group__options.html @@ -112,8 +112,8 @@ $(document).ready(function(){initNavTree('group__options.html','');});
void mi_stats_print void mi_stats_print_out ( mi_output_fun out,

Enumerations

enum  mi_option_t {
-  mi_option_show_stats, -mi_option_show_errors, +  mi_option_show_errors, +mi_option_show_stats, mi_option_verbose, mi_option_eager_commit,
@@ -138,12 +138,16 @@ Enumerations
- - - - - - + + + + + + + + + + @@ -168,9 +172,9 @@ Functions

Runtime options.

Functions

bool mi_option_enabled (mi_option_t option)
 
void mi_option_enable (mi_option_t option, bool enable)
 
void mi_option_enable_default (mi_option_t option, bool enable)
 
bool mi_option_is_enabled (mi_option_t option)
 
void mi_option_enable (mi_option_t option)
 
void mi_option_disable (mi_option_t option)
 
void mi_option_set_enabled (mi_option_t option, bool enable)
 
void mi_option_set_enabled_default (mi_option_t option, bool enable)
 
long mi_option_get (mi_option_t option)
 
void mi_option_set (mi_option_t option, long value)
- - @@ -204,8 +208,26 @@ Functions

Function Documentation

- -

◆ mi_option_enable()

+ +

◆ mi_option_disable()

+ +
+
+
Enumerator
mi_option_show_stats 

Print statistics to stderr when the program is done.

+
Enumerator
mi_option_show_errors 

Print error messages to stderr.

mi_option_show_errors 

Print error messages to stderr.

+
mi_option_show_stats 

Print statistics to stderr when the program is done.

mi_option_verbose 

Print verbose messages to stderr.

+ + + + + + + +
void mi_option_disable (mi_option_t option)
+
+ +
+
+ +

◆ mi_option_enable()

@@ -214,62 +236,6 @@ Functions void mi_option_enable ( mi_option_t  - option, - - - - - bool  - enable  - - - - ) - - - -
- -
-
- -

◆ mi_option_enable_default()

- -
-
- - - - - - - - - - - - - - - - - - -
void mi_option_enable_default (mi_option_t option,
bool enable 
)
-
- -
-
- -

◆ mi_option_enabled()

- -
-
- - - - - @@ -294,6 +260,24 @@ Functions
bool mi_option_enabled (mi_option_t  option)
+
+
+ +

◆ mi_option_is_enabled()

+ +
+
+ + + + + + + + +
bool mi_option_is_enabled (mi_option_t option)
+
+
@@ -350,6 +334,62 @@ Functions
+
+ + +

◆ mi_option_set_enabled()

+ +
+
+ + + + + + + + + + + + + + + + + + +
void mi_option_set_enabled (mi_option_t option,
bool enable 
)
+
+ +
+
+ +

◆ mi_option_set_enabled_default()

+ +
+
+ + + + + + + + + + + + + + + + + + +
void mi_option_set_enabled_default (mi_option_t option,
bool enable 
)
+
+
diff --git a/docs/group__options.js b/docs/group__options.js index 1d84ea8b..9aaf2318 100644 --- a/docs/group__options.js +++ b/docs/group__options.js @@ -1,8 +1,8 @@ var group__options = [ [ "mi_option_t", "group__options.html#gafebf7ed116adb38ae5218bc3ce06884c", [ - [ "mi_option_show_stats", "group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca0957ef73b2550764b4840edf48422fda", null ], [ "mi_option_show_errors", "group__options.html#ggafebf7ed116adb38ae5218bc3ce06884cafbf4822e5c00732c5984b32a032837f0", null ], + [ "mi_option_show_stats", "group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca0957ef73b2550764b4840edf48422fda", null ], [ "mi_option_verbose", "group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca7c8b7bf5281c581bad64f5daa6442777", null ], [ "mi_option_eager_commit", "group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca1e8de72c93da7ff22d91e1e27b52ac2b", null ], [ "mi_option_eager_region_commit", "group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca32ce97ece29f69e82579679cf8a307ad", null ], @@ -18,10 +18,12 @@ var group__options = [ "mi_option_os_tag", "group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca4b74ae2a69e445de6c2361b73c1d14bf", null ], [ "_mi_option_last", "group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca5b4357b74be0d87568036c32eb1a2e4a", null ] ] ], - [ "mi_option_enable", "group__options.html#ga6d45a20a3131f18bc351b69763b38ce4", null ], - [ "mi_option_enable_default", "group__options.html#ga37988264b915a7db92530cc02d5494cb", null ], - [ "mi_option_enabled", "group__options.html#gacebe3f6d91b4a50b54eb84e2a1da1b30", null ], + [ "mi_option_disable", "group__options.html#gaebf6ff707a2e688ebb1a2296ca564054", null ], + [ "mi_option_enable", "group__options.html#ga04180ae41b0d601421dd62ced40ca050", null ], [ "mi_option_get", "group__options.html#ga7e8af195cc81d3fa64ccf2662caa565a", null ], + [ "mi_option_is_enabled", "group__options.html#ga459ad98f18b3fc9275474807fe0ca188", null ], [ "mi_option_set", "group__options.html#gaf84921c32375e25754dc2ee6a911fa60", null ], - [ "mi_option_set_default", "group__options.html#ga7ef623e440e6e5545cb08c94e71e4b90", null ] + [ "mi_option_set_default", "group__options.html#ga7ef623e440e6e5545cb08c94e71e4b90", null ], + [ "mi_option_set_enabled", "group__options.html#ga9a13d05fcb77489cb06d4d017ebd8bed", null ], + [ "mi_option_set_enabled_default", "group__options.html#ga65518b69ec5d32336b50e07f74b3f629", null ] ]; \ No newline at end of file diff --git a/docs/mimalloc-doc_8h_source.html b/docs/mimalloc-doc_8h_source.html index 09c03b9b..c4637bad 100644 --- a/docs/mimalloc-doc_8h_source.html +++ b/docs/mimalloc-doc_8h_source.html @@ -102,22 +102,24 @@ $(document).ready(function(){initNavTree('mimalloc-doc_8h_source.html','');});
mimalloc-doc.h
-
1 /* ----------------------------------------------------------------------------
2 Copyright (c) 2018, Microsoft Research, Daan Leijen
3 This is free software; you can redistribute it and/or modify it under the
4 terms of the MIT license. A copy of the license can be found in the file
5 "LICENSE" at the root of this distribution.
6 -----------------------------------------------------------------------------*/
7 
8 #error "documentation file only!"
9 
10 
83 
87 
91 void mi_free(void* p);
92 
97 void* mi_malloc(size_t size);
98 
103 void* mi_zalloc(size_t size);
104 
114 void* mi_calloc(size_t count, size_t size);
115 
128 void* mi_realloc(void* p, size_t newsize);
129 
140 void* mi_recalloc(void* p, size_t count, size_t size);
141 
155 void* mi_expand(void* p, size_t newsize);
156 
166 void* mi_mallocn(size_t count, size_t size);
167 
177 void* mi_reallocn(void* p, size_t count, size_t size);
178 
195 void* mi_reallocf(void* p, size_t newsize);
196 
197 
206 char* mi_strdup(const char* s);
207 
217 char* mi_strndup(const char* s, size_t n);
218 
231 char* mi_realpath(const char* fname, char* resolved_name);
232 
234 
235 // ------------------------------------------------------
236 // Extended functionality
237 // ------------------------------------------------------
238 
242 
245 #define MI_SMALL_SIZE_MAX (128*sizeof(void*))
246 
254 void* mi_malloc_small(size_t size);
255 
263 void* mi_zalloc_small(size_t size);
264 
279 size_t mi_usable_size(void* p);
280 
290 size_t mi_good_size(size_t size);
291 
299 void mi_collect(bool force);
300 
305 void mi_stats_print(void* out);
306 
312 void mi_stats_print(mi_output_fun* out, void* arg);
313 
315 void mi_stats_reset(void);
316 
318 void mi_stats_merge(void);
319 
323 void mi_thread_init(void);
324 
329 void mi_thread_done(void);
330 
336 void mi_thread_stats_print_out(mi_output_fun* out, void* arg);
337 
344 typedef void (mi_deferred_free_fun)(bool force, unsigned long long heartbeat, void* arg);
345 
361 void mi_register_deferred_free(mi_deferred_free_fun* deferred_free, void* arg);
362 
368 typedef void (mi_output_fun)(const char* msg, void* arg);
369 
376 void mi_register_output(mi_output_fun* out, void* arg);
377 
383 typedef void (mi_error_fun)(int err, void* arg);
384 
400 void mi_register_error(mi_error_fun* errfun, void* arg);
401 
406 bool mi_is_in_heap_region(const void* p);
407 
408 
421 int mi_reserve_huge_os_pages_interleave(size_t pages, size_t numa_nodes, size_t timeout_msecs);
422 
435 int mi_reserve_huge_os_pages_at(size_t pages, int numa_node, size_t timeout_msecs);
436 
437 
442 bool mi_is_redirected();
443 
444 
446 
447 // ------------------------------------------------------
448 // Aligned allocation
449 // ------------------------------------------------------
450 
456 
469 void* mi_malloc_aligned(size_t size, size_t alignment);
470 void* mi_zalloc_aligned(size_t size, size_t alignment);
471 void* mi_calloc_aligned(size_t count, size_t size, size_t alignment);
472 void* mi_realloc_aligned(void* p, size_t newsize, size_t alignment);
473 
484 void* mi_malloc_aligned_at(size_t size, size_t alignment, size_t offset);
485 void* mi_zalloc_aligned_at(size_t size, size_t alignment, size_t offset);
486 void* mi_calloc_aligned_at(size_t count, size_t size, size_t alignment, size_t offset);
487 void* mi_realloc_aligned_at(void* p, size_t newsize, size_t alignment, size_t offset);
488 
490 
496 
501 struct mi_heap_s;
502 
507 typedef struct mi_heap_s mi_heap_t;
508 
511 
519 void mi_heap_delete(mi_heap_t* heap);
520 
528 void mi_heap_destroy(mi_heap_t* heap);
529 
534 
538 
545 
547 void mi_heap_collect(mi_heap_t* heap, bool force);
548 
551 void* mi_heap_malloc(mi_heap_t* heap, size_t size);
552 
556 void* mi_heap_malloc_small(mi_heap_t* heap, size_t size);
557 
560 void* mi_heap_zalloc(mi_heap_t* heap, size_t size);
561 
564 void* mi_heap_calloc(mi_heap_t* heap, size_t count, size_t size);
565 
568 void* mi_heap_mallocn(mi_heap_t* heap, size_t count, size_t size);
569 
572 char* mi_heap_strdup(mi_heap_t* heap, const char* s);
573 
576 char* mi_heap_strndup(mi_heap_t* heap, const char* s, size_t n);
577 
580 char* mi_heap_realpath(mi_heap_t* heap, const char* fname, char* resolved_name);
581 
582 void* mi_heap_realloc(mi_heap_t* heap, void* p, size_t newsize);
583 void* mi_heap_reallocn(mi_heap_t* heap, void* p, size_t count, size_t size);
584 void* mi_heap_reallocf(mi_heap_t* heap, void* p, size_t newsize);
585 
586 void* mi_heap_malloc_aligned(mi_heap_t* heap, size_t size, size_t alignment);
587 void* mi_heap_malloc_aligned_at(mi_heap_t* heap, size_t size, size_t alignment, size_t offset);
588 void* mi_heap_zalloc_aligned(mi_heap_t* heap, size_t size, size_t alignment);
589 void* mi_heap_zalloc_aligned_at(mi_heap_t* heap, size_t size, size_t alignment, size_t offset);
590 void* mi_heap_calloc_aligned(mi_heap_t* heap, size_t count, size_t size, size_t alignment);
591 void* mi_heap_calloc_aligned_at(mi_heap_t* heap, size_t count, size_t size, size_t alignment, size_t offset);
592 void* mi_heap_realloc_aligned(mi_heap_t* heap, void* p, size_t newsize, size_t alignment);
593 void* mi_heap_realloc_aligned_at(mi_heap_t* heap, void* p, size_t newsize, size_t alignment, size_t offset);
594 
596 
597 
606 
607 void* mi_rezalloc(void* p, size_t newsize);
608 void* mi_recalloc(void* p, size_t newcount, size_t size) ;
609 
610 void* mi_rezalloc_aligned(void* p, size_t newsize, size_t alignment);
611 void* mi_rezalloc_aligned_at(void* p, size_t newsize, size_t alignment, size_t offset);
612 void* mi_recalloc_aligned(void* p, size_t newcount, size_t size, size_t alignment);
613 void* mi_recalloc_aligned_at(void* p, size_t newcount, size_t size, size_t alignment, size_t offset);
614 
615 void* mi_heap_rezalloc(mi_heap_t* heap, void* p, size_t newsize);
616 void* mi_heap_recalloc(mi_heap_t* heap, void* p, size_t newcount, size_t size);
617 
618 void* mi_heap_rezalloc_aligned(mi_heap_t* heap, void* p, size_t newsize, size_t alignment);
619 void* mi_heap_rezalloc_aligned_at(mi_heap_t* heap, void* p, size_t newsize, size_t alignment, size_t offset);
620 void* mi_heap_recalloc_aligned(mi_heap_t* heap, void* p, size_t newcount, size_t size, size_t alignment);
621 void* mi_heap_recalloc_aligned_at(mi_heap_t* heap, void* p, size_t newcount, size_t size, size_t alignment, size_t offset);
622 
624 
633 
645 #define mi_malloc_tp(tp) ((tp*)mi_malloc(sizeof(tp)))
646 
648 #define mi_zalloc_tp(tp) ((tp*)mi_zalloc(sizeof(tp)))
649 
651 #define mi_calloc_tp(tp,count) ((tp*)mi_calloc(count,sizeof(tp)))
652 
654 #define mi_mallocn_tp(tp,count) ((tp*)mi_mallocn(count,sizeof(tp)))
655 
657 #define mi_reallocn_tp(p,tp,count) ((tp*)mi_reallocn(p,count,sizeof(tp)))
658 
660 #define mi_heap_malloc_tp(hp,tp) ((tp*)mi_heap_malloc(hp,sizeof(tp)))
661 
663 #define mi_heap_zalloc_tp(hp,tp) ((tp*)mi_heap_zalloc(hp,sizeof(tp)))
664 
666 #define mi_heap_calloc_tp(hp,tp,count) ((tp*)mi_heap_calloc(hp,count,sizeof(tp)))
667 
669 #define mi_heap_mallocn_tp(hp,tp,count) ((tp*)mi_heap_mallocn(hp,count,sizeof(tp)))
670 
672 #define mi_heap_reallocn_tp(hp,p,tp,count) ((tp*)mi_heap_reallocn(p,count,sizeof(tp)))
673 
675 #define mi_heap_recalloc_tp(hp,p,tp,count) ((tp*)mi_heap_recalloc(p,count,sizeof(tp)))
676 
678 
684 
691 bool mi_heap_contains_block(mi_heap_t* heap, const void* p);
692 
701 bool mi_heap_check_owned(mi_heap_t* heap, const void* p);
702 
710 bool mi_check_owned(const void* p);
711 
714 typedef struct mi_heap_area_s {
715  void* blocks;
716  size_t reserved;
717  size_t committed;
718  size_t used;
719  size_t block_size;
721 
729 typedef bool (mi_block_visit_fun)(const mi_heap_t* heap, const mi_heap_area_t* area, void* block, size_t block_size, void* arg);
730 
742 bool mi_heap_visit_blocks(const mi_heap_t* heap, bool visit_all_blocks, mi_block_visit_fun* visitor, void* arg);
743 
745 
751 
753 typedef enum mi_option_e {
754  // stable options
758  // the following options are experimental
772 } mi_option_t;
773 
774 
775 bool mi_option_enabled(mi_option_t option);
776 void mi_option_enable(mi_option_t option, bool enable);
777 void mi_option_enable_default(mi_option_t option, bool enable);
778 
779 long mi_option_get(mi_option_t option);
780 void mi_option_set(mi_option_t option, long value);
781 void mi_option_set_default(mi_option_t option, long value);
782 
783 
785 
792 
793 void* mi_recalloc(void* p, size_t count, size_t size);
794 size_t mi_malloc_size(const void* p);
795 size_t mi_malloc_usable_size(const void *p);
796 
798 void mi_cfree(void* p);
799 
800 int mi_posix_memalign(void** p, size_t alignment, size_t size);
801 int mi__posix_memalign(void** p, size_t alignment, size_t size);
802 void* mi_memalign(size_t alignment, size_t size);
803 void* mi_valloc(size_t size);
804 
805 void* mi_pvalloc(size_t size);
806 void* mi_aligned_alloc(size_t alignment, size_t size);
807 void* mi_reallocarray(void* p, size_t count, size_t size);
808 
809 void mi_free_size(void* p, size_t size);
810 void mi_free_size_aligned(void* p, size_t size, size_t alignment);
811 void mi_free_aligned(void* p, size_t alignment);
812 
814 
827 
829 void* mi_new(std::size_t n) noexcept(false);
830 
832 void* mi_new_n(size_t count, size_t size) noexcept(false);
833 
835 void* mi_new_aligned(std::size_t n, std::align_val_t alignment) noexcept(false);
836 
838 void* mi_new_nothrow(size_t n);
839 
841 void* mi_new_aligned_nothrow(size_t n, size_t alignment);
842 
844 void* mi_new_realloc(void* p, size_t newsize);
845 
847 void* mi_new_reallocn(void* p, size_t newcount, size_t size);
848 
856 template<class T> struct mi_stl_allocator { }
857 
859 
void mi_option_enable_default(mi_option_t option, bool enable)
-
size_t mi_usable_size(void *p)
Return the available bytes in a memory block.
+
1 /* ----------------------------------------------------------------------------
2 Copyright (c) 2018, Microsoft Research, Daan Leijen
3 This is free software; you can redistribute it and/or modify it under the
4 terms of the MIT license. A copy of the license can be found in the file
5 "LICENSE" at the root of this distribution.
6 -----------------------------------------------------------------------------*/
7 
8 #error "documentation file only!"
9 
10 
83 
87 
91 void mi_free(void* p);
92 
97 void* mi_malloc(size_t size);
98 
103 void* mi_zalloc(size_t size);
104 
114 void* mi_calloc(size_t count, size_t size);
115 
128 void* mi_realloc(void* p, size_t newsize);
129 
140 void* mi_recalloc(void* p, size_t count, size_t size);
141 
155 void* mi_expand(void* p, size_t newsize);
156 
166 void* mi_mallocn(size_t count, size_t size);
167 
177 void* mi_reallocn(void* p, size_t count, size_t size);
178 
195 void* mi_reallocf(void* p, size_t newsize);
196 
197 
206 char* mi_strdup(const char* s);
207 
217 char* mi_strndup(const char* s, size_t n);
218 
231 char* mi_realpath(const char* fname, char* resolved_name);
232 
234 
235 // ------------------------------------------------------
236 // Extended functionality
237 // ------------------------------------------------------
238 
242 
245 #define MI_SMALL_SIZE_MAX (128*sizeof(void*))
246 
254 void* mi_malloc_small(size_t size);
255 
263 void* mi_zalloc_small(size_t size);
264 
279 size_t mi_usable_size(void* p);
280 
290 size_t mi_good_size(size_t size);
291 
299 void mi_collect(bool force);
300 
305 void mi_stats_print(void* out);
306 
312 void mi_stats_print_out(mi_output_fun* out, void* arg);
313 
315 void mi_stats_reset(void);
316 
318 void mi_stats_merge(void);
319 
323 void mi_thread_init(void);
324 
329 void mi_thread_done(void);
330 
336 void mi_thread_stats_print_out(mi_output_fun* out, void* arg);
337 
344 typedef void (mi_deferred_free_fun)(bool force, unsigned long long heartbeat, void* arg);
345 
361 void mi_register_deferred_free(mi_deferred_free_fun* deferred_free, void* arg);
362 
368 typedef void (mi_output_fun)(const char* msg, void* arg);
369 
376 void mi_register_output(mi_output_fun* out, void* arg);
377 
383 typedef void (mi_error_fun)(int err, void* arg);
384 
400 void mi_register_error(mi_error_fun* errfun, void* arg);
401 
406 bool mi_is_in_heap_region(const void* p);
407 
408 
421 int mi_reserve_huge_os_pages_interleave(size_t pages, size_t numa_nodes, size_t timeout_msecs);
422 
435 int mi_reserve_huge_os_pages_at(size_t pages, int numa_node, size_t timeout_msecs);
436 
437 
442 bool mi_is_redirected();
443 
444 
446 
447 // ------------------------------------------------------
448 // Aligned allocation
449 // ------------------------------------------------------
450 
456 
469 void* mi_malloc_aligned(size_t size, size_t alignment);
470 void* mi_zalloc_aligned(size_t size, size_t alignment);
471 void* mi_calloc_aligned(size_t count, size_t size, size_t alignment);
472 void* mi_realloc_aligned(void* p, size_t newsize, size_t alignment);
473 
484 void* mi_malloc_aligned_at(size_t size, size_t alignment, size_t offset);
485 void* mi_zalloc_aligned_at(size_t size, size_t alignment, size_t offset);
486 void* mi_calloc_aligned_at(size_t count, size_t size, size_t alignment, size_t offset);
487 void* mi_realloc_aligned_at(void* p, size_t newsize, size_t alignment, size_t offset);
488 
490 
496 
501 struct mi_heap_s;
502 
507 typedef struct mi_heap_s mi_heap_t;
508 
511 
519 void mi_heap_delete(mi_heap_t* heap);
520 
528 void mi_heap_destroy(mi_heap_t* heap);
529 
534 
538 
545 
547 void mi_heap_collect(mi_heap_t* heap, bool force);
548 
551 void* mi_heap_malloc(mi_heap_t* heap, size_t size);
552 
556 void* mi_heap_malloc_small(mi_heap_t* heap, size_t size);
557 
560 void* mi_heap_zalloc(mi_heap_t* heap, size_t size);
561 
564 void* mi_heap_calloc(mi_heap_t* heap, size_t count, size_t size);
565 
568 void* mi_heap_mallocn(mi_heap_t* heap, size_t count, size_t size);
569 
572 char* mi_heap_strdup(mi_heap_t* heap, const char* s);
573 
576 char* mi_heap_strndup(mi_heap_t* heap, const char* s, size_t n);
577 
580 char* mi_heap_realpath(mi_heap_t* heap, const char* fname, char* resolved_name);
581 
582 void* mi_heap_realloc(mi_heap_t* heap, void* p, size_t newsize);
583 void* mi_heap_reallocn(mi_heap_t* heap, void* p, size_t count, size_t size);
584 void* mi_heap_reallocf(mi_heap_t* heap, void* p, size_t newsize);
585 
586 void* mi_heap_malloc_aligned(mi_heap_t* heap, size_t size, size_t alignment);
587 void* mi_heap_malloc_aligned_at(mi_heap_t* heap, size_t size, size_t alignment, size_t offset);
588 void* mi_heap_zalloc_aligned(mi_heap_t* heap, size_t size, size_t alignment);
589 void* mi_heap_zalloc_aligned_at(mi_heap_t* heap, size_t size, size_t alignment, size_t offset);
590 void* mi_heap_calloc_aligned(mi_heap_t* heap, size_t count, size_t size, size_t alignment);
591 void* mi_heap_calloc_aligned_at(mi_heap_t* heap, size_t count, size_t size, size_t alignment, size_t offset);
592 void* mi_heap_realloc_aligned(mi_heap_t* heap, void* p, size_t newsize, size_t alignment);
593 void* mi_heap_realloc_aligned_at(mi_heap_t* heap, void* p, size_t newsize, size_t alignment, size_t offset);
594 
596 
597 
606 
607 void* mi_rezalloc(void* p, size_t newsize);
608 void* mi_recalloc(void* p, size_t newcount, size_t size) ;
609 
610 void* mi_rezalloc_aligned(void* p, size_t newsize, size_t alignment);
611 void* mi_rezalloc_aligned_at(void* p, size_t newsize, size_t alignment, size_t offset);
612 void* mi_recalloc_aligned(void* p, size_t newcount, size_t size, size_t alignment);
613 void* mi_recalloc_aligned_at(void* p, size_t newcount, size_t size, size_t alignment, size_t offset);
614 
615 void* mi_heap_rezalloc(mi_heap_t* heap, void* p, size_t newsize);
616 void* mi_heap_recalloc(mi_heap_t* heap, void* p, size_t newcount, size_t size);
617 
618 void* mi_heap_rezalloc_aligned(mi_heap_t* heap, void* p, size_t newsize, size_t alignment);
619 void* mi_heap_rezalloc_aligned_at(mi_heap_t* heap, void* p, size_t newsize, size_t alignment, size_t offset);
620 void* mi_heap_recalloc_aligned(mi_heap_t* heap, void* p, size_t newcount, size_t size, size_t alignment);
621 void* mi_heap_recalloc_aligned_at(mi_heap_t* heap, void* p, size_t newcount, size_t size, size_t alignment, size_t offset);
622 
624 
633 
645 #define mi_malloc_tp(tp) ((tp*)mi_malloc(sizeof(tp)))
646 
648 #define mi_zalloc_tp(tp) ((tp*)mi_zalloc(sizeof(tp)))
649 
651 #define mi_calloc_tp(tp,count) ((tp*)mi_calloc(count,sizeof(tp)))
652 
654 #define mi_mallocn_tp(tp,count) ((tp*)mi_mallocn(count,sizeof(tp)))
655 
657 #define mi_reallocn_tp(p,tp,count) ((tp*)mi_reallocn(p,count,sizeof(tp)))
658 
660 #define mi_heap_malloc_tp(hp,tp) ((tp*)mi_heap_malloc(hp,sizeof(tp)))
661 
663 #define mi_heap_zalloc_tp(hp,tp) ((tp*)mi_heap_zalloc(hp,sizeof(tp)))
664 
666 #define mi_heap_calloc_tp(hp,tp,count) ((tp*)mi_heap_calloc(hp,count,sizeof(tp)))
667 
669 #define mi_heap_mallocn_tp(hp,tp,count) ((tp*)mi_heap_mallocn(hp,count,sizeof(tp)))
670 
672 #define mi_heap_reallocn_tp(hp,p,tp,count) ((tp*)mi_heap_reallocn(p,count,sizeof(tp)))
673 
675 #define mi_heap_recalloc_tp(hp,p,tp,count) ((tp*)mi_heap_recalloc(p,count,sizeof(tp)))
676 
678 
684 
691 bool mi_heap_contains_block(mi_heap_t* heap, const void* p);
692 
701 bool mi_heap_check_owned(mi_heap_t* heap, const void* p);
702 
710 bool mi_check_owned(const void* p);
711 
714 typedef struct mi_heap_area_s {
715  void* blocks;
716  size_t reserved;
717  size_t committed;
718  size_t used;
719  size_t block_size;
721 
729 typedef bool (mi_block_visit_fun)(const mi_heap_t* heap, const mi_heap_area_t* area, void* block, size_t block_size, void* arg);
730 
742 bool mi_heap_visit_blocks(const mi_heap_t* heap, bool visit_all_blocks, mi_block_visit_fun* visitor, void* arg);
743 
745 
751 
753 typedef enum mi_option_e {
754  // stable options
758  // the following options are experimental
772 } mi_option_t;
773 
774 
775 bool mi_option_is_enabled(mi_option_t option);
776 void mi_option_enable(mi_option_t option);
777 void mi_option_disable(mi_option_t option);
778 void mi_option_set_enabled(mi_option_t option, bool enable);
779 void mi_option_set_enabled_default(mi_option_t option, bool enable);
780 
781 long mi_option_get(mi_option_t option);
782 void mi_option_set(mi_option_t option, long value);
783 void mi_option_set_default(mi_option_t option, long value);
784 
785 
787 
794 
795 void* mi_recalloc(void* p, size_t count, size_t size);
796 size_t mi_malloc_size(const void* p);
797 size_t mi_malloc_usable_size(const void *p);
798 
800 void mi_cfree(void* p);
801 
802 int mi_posix_memalign(void** p, size_t alignment, size_t size);
803 int mi__posix_memalign(void** p, size_t alignment, size_t size);
804 void* mi_memalign(size_t alignment, size_t size);
805 void* mi_valloc(size_t size);
806 
807 void* mi_pvalloc(size_t size);
808 void* mi_aligned_alloc(size_t alignment, size_t size);
809 void* mi_reallocarray(void* p, size_t count, size_t size);
810 
811 void mi_free_size(void* p, size_t size);
812 void mi_free_size_aligned(void* p, size_t size, size_t alignment);
813 void mi_free_aligned(void* p, size_t alignment);
814 
816 
829 
831 void* mi_new(std::size_t n) noexcept(false);
832 
834 void* mi_new_n(size_t count, size_t size) noexcept(false);
835 
837 void* mi_new_aligned(std::size_t n, std::align_val_t alignment) noexcept(false);
838 
840 void* mi_new_nothrow(size_t n);
841 
843 void* mi_new_aligned_nothrow(size_t n, size_t alignment);
844 
846 void* mi_new_realloc(void* p, size_t newsize);
847 
849 void* mi_new_reallocn(void* p, size_t newcount, size_t size);
850 
858 template<class T> struct mi_stl_allocator { }
859 
861 
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']]], From c5406f327e3742b24e451da36b651b8400ea19da Mon Sep 17 00:00:00 2001 From: daan Date: Tue, 21 Jul 2020 18:51:25 -0700 Subject: [PATCH 13/13] move include 'limits.h' outside of definition --- include/mimalloc-internal.h | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/include/mimalloc-internal.h b/include/mimalloc-internal.h index c0a084c2..ba322feb 100644 --- a/include/mimalloc-internal.h +++ b/include/mimalloc-internal.h @@ -238,27 +238,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 defined(_CLOCK_T) +#include // UINT_MAX, ULONG_MAX +#if defined(_CLOCK_T) // for Illumos #undef _CLOCK_T #endif - -#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 +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) {