mirror of
https://github.com/microsoft/mimalloc.git
synced 2025-05-05 23:19:31 +03:00
Merge branch 'dev' into fix-const
This commit is contained in:
commit
51e2be6647
66 changed files with 893 additions and 787 deletions
|
@ -11,6 +11,7 @@ option(MI_OVERRIDE "Override the standard malloc interface (e.g. define
|
||||||
option(MI_XMALLOC "Enable abort() call on memory allocation failure by default" OFF)
|
option(MI_XMALLOC "Enable abort() call on memory allocation failure by default" OFF)
|
||||||
option(MI_SHOW_ERRORS "Show error and warning messages by default (only enabled by default in DEBUG mode)" OFF)
|
option(MI_SHOW_ERRORS "Show error and warning messages by default (only enabled by default in DEBUG mode)" OFF)
|
||||||
option(MI_VALGRIND "Compile with Valgrind support (adds a small overhead)" OFF)
|
option(MI_VALGRIND "Compile with Valgrind support (adds a small overhead)" OFF)
|
||||||
|
option(MI_ASAN "Compile with address sanitizer support (adds a small overhead)" OFF)
|
||||||
option(MI_USE_CXX "Use the C++ compiler to compile the library (instead of the C compiler)" OFF)
|
option(MI_USE_CXX "Use the C++ compiler to compile the library (instead of the C compiler)" OFF)
|
||||||
option(MI_SEE_ASM "Generate assembly files" OFF)
|
option(MI_SEE_ASM "Generate assembly files" OFF)
|
||||||
option(MI_OSX_INTERPOSE "Use interpose to override standard malloc on macOS" ON)
|
option(MI_OSX_INTERPOSE "Use interpose to override standard malloc on macOS" ON)
|
||||||
|
@ -139,6 +140,25 @@ if(MI_VALGRIND)
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(MI_ASAN)
|
||||||
|
if (MI_VALGRIND)
|
||||||
|
set(MI_ASAN OFF)
|
||||||
|
message(WARNING "Cannot enable address sanitizer support with also Valgrind support enabled (MI_ASAN=OFF)")
|
||||||
|
else()
|
||||||
|
CHECK_INCLUDE_FILES("sanitizer/asan_interface.h" MI_HAS_ASANH)
|
||||||
|
if (NOT MI_HAS_ASANH)
|
||||||
|
set(MI_ASAN OFF)
|
||||||
|
message(WARNING "Cannot find the 'sanitizer/asan_interface.h' -- install address sanitizer support first")
|
||||||
|
message(STATUS "Compile **without** address sanitizer support (MI_ASAN=OFF)")
|
||||||
|
else()
|
||||||
|
message(STATUS "Compile with address sanitizer support (MI_ASAN=ON)")
|
||||||
|
list(APPEND mi_defines MI_ASAN=1)
|
||||||
|
list(APPEND mi_cflags -fsanitize=address)
|
||||||
|
list(APPEND CMAKE_EXE_LINKER_FLAGS -fsanitize=address)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
if(MI_SEE_ASM)
|
if(MI_SEE_ASM)
|
||||||
message(STATUS "Generate assembly listings (MI_SEE_ASM=ON)")
|
message(STATUS "Generate assembly listings (MI_SEE_ASM=ON)")
|
||||||
list(APPEND mi_cflags -save-temps)
|
list(APPEND mi_cflags -save-temps)
|
||||||
|
@ -297,6 +317,9 @@ endif()
|
||||||
if(MI_VALGRIND)
|
if(MI_VALGRIND)
|
||||||
set(mi_basename "${mi_basename}-valgrind")
|
set(mi_basename "${mi_basename}-valgrind")
|
||||||
endif()
|
endif()
|
||||||
|
if(MI_ASAN)
|
||||||
|
set(mi_basename "${mi_basename}-asan")
|
||||||
|
endif()
|
||||||
string(TOLOWER "${CMAKE_BUILD_TYPE}" CMAKE_BUILD_TYPE_LC)
|
string(TOLOWER "${CMAKE_BUILD_TYPE}" CMAKE_BUILD_TYPE_LC)
|
||||||
if(NOT(CMAKE_BUILD_TYPE_LC MATCHES "^(release|relwithdebinfo|minsizerel|none)$"))
|
if(NOT(CMAKE_BUILD_TYPE_LC MATCHES "^(release|relwithdebinfo|minsizerel|none)$"))
|
||||||
set(mi_basename "${mi_basename}-${CMAKE_BUILD_TYPE_LC}") #append build type (e.g. -debug) if not a release version
|
set(mi_basename "${mi_basename}-${CMAKE_BUILD_TYPE_LC}") #append build type (e.g. -debug) if not a release version
|
||||||
|
|
|
@ -1790,4 +1790,3 @@ tt, code, kbd, samp
|
||||||
u {
|
u {
|
||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -143,4 +143,3 @@
|
||||||
#nav-tree { display: none; }
|
#nav-tree { display: none; }
|
||||||
div.ui-resizable-handle { display: none; position: relative; }
|
div.ui-resizable-handle { display: none; position: relative; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -270,4 +270,3 @@ DIV.searchresults {
|
||||||
.searchpages {
|
.searchpages {
|
||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,4 +36,3 @@ var indexSectionLabels =
|
||||||
7: "Modules",
|
7: "Modules",
|
||||||
8: "Pages"
|
8: "Pages"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -58,4 +58,3 @@
|
||||||
color: #fff;
|
color: #fff;
|
||||||
text-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0);
|
text-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,17 +22,26 @@ terms of the MIT license. A copy of the license can be found in the file
|
||||||
#include <new>
|
#include <new>
|
||||||
#include <mimalloc.h>
|
#include <mimalloc.h>
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) && defined(_Ret_notnull_) && defined(_Post_writable_byte_size_)
|
||||||
|
// stay consistent with VCRT definitions
|
||||||
|
#define mi_decl_new(n) mi_decl_nodiscard mi_decl_restrict _Ret_notnull_ _Post_writable_byte_size_(n)
|
||||||
|
#define mi_decl_new_nothrow(n) mi_decl_nodiscard mi_decl_restrict _Ret_maybenull_ _Success_(return != NULL) _Post_writable_byte_size_(n)
|
||||||
|
#else
|
||||||
|
#define mi_decl_new(n) mi_decl_nodiscard mi_decl_restrict
|
||||||
|
#define mi_decl_new_nothrow(n) mi_decl_nodiscard mi_decl_restrict
|
||||||
|
#endif
|
||||||
|
|
||||||
void operator delete(void* p) noexcept { mi_free(p); };
|
void operator delete(void* p) noexcept { mi_free(p); };
|
||||||
void operator delete[](void* p) noexcept { mi_free(p); };
|
void operator delete[](void* p) noexcept { mi_free(p); };
|
||||||
|
|
||||||
void operator delete (void* p, const std::nothrow_t&) noexcept { mi_free(p); }
|
void operator delete (void* p, const std::nothrow_t&) noexcept { mi_free(p); }
|
||||||
void operator delete[](void* p, const std::nothrow_t&) noexcept { mi_free(p); }
|
void operator delete[](void* p, const std::nothrow_t&) noexcept { mi_free(p); }
|
||||||
|
|
||||||
void* operator new(std::size_t n) noexcept(false) { return mi_new(n); }
|
mi_decl_new(n) void* operator new(std::size_t n) noexcept(false) { return mi_new(n); }
|
||||||
void* operator new[](std::size_t n) noexcept(false) { return mi_new(n); }
|
mi_decl_new(n) void* operator new[](std::size_t n) noexcept(false) { return mi_new(n); }
|
||||||
|
|
||||||
void* operator new (std::size_t n, const std::nothrow_t& tag) noexcept { (void)(tag); return mi_new_nothrow(n); }
|
mi_decl_new_nothrow(n) void* operator new (std::size_t n, const std::nothrow_t& tag) noexcept { (void)(tag); return mi_new_nothrow(n); }
|
||||||
void* operator new[](std::size_t n, const std::nothrow_t& tag) noexcept { (void)(tag); return mi_new_nothrow(n); }
|
mi_decl_new_nothrow(n) void* operator new[](std::size_t n, const std::nothrow_t& tag) noexcept { (void)(tag); return mi_new_nothrow(n); }
|
||||||
|
|
||||||
#if (__cplusplus >= 201402L || _MSC_VER >= 1916)
|
#if (__cplusplus >= 201402L || _MSC_VER >= 1916)
|
||||||
void operator delete (void* p, std::size_t n) noexcept { mi_free_size(p,n); };
|
void operator delete (void* p, std::size_t n) noexcept { mi_free_size(p,n); };
|
||||||
|
|
|
@ -10,12 +10,13 @@ terms of the MIT license. A copy of the license can be found in the file
|
||||||
|
|
||||||
// ------------------------------------------------------
|
// ------------------------------------------------------
|
||||||
// Track memory ranges with macros for tools like Valgrind
|
// Track memory ranges with macros for tools like Valgrind
|
||||||
// or other memory checkers.
|
// address sanitizer, or other memory checkers.
|
||||||
// ------------------------------------------------------
|
// ------------------------------------------------------
|
||||||
|
|
||||||
#if MI_VALGRIND
|
#if MI_VALGRIND
|
||||||
|
|
||||||
#define MI_TRACK_ENABLED 1
|
#define MI_TRACK_ENABLED 1
|
||||||
|
#define MI_TRACK_TOOL "valgrind"
|
||||||
|
|
||||||
#include <valgrind/valgrind.h>
|
#include <valgrind/valgrind.h>
|
||||||
#include <valgrind/memcheck.h>
|
#include <valgrind/memcheck.h>
|
||||||
|
@ -23,17 +24,35 @@ terms of the MIT license. A copy of the license can be found in the file
|
||||||
#define mi_track_malloc(p,size,zero) VALGRIND_MALLOCLIKE_BLOCK(p,size,MI_PADDING_SIZE /*red zone*/,zero)
|
#define mi_track_malloc(p,size,zero) VALGRIND_MALLOCLIKE_BLOCK(p,size,MI_PADDING_SIZE /*red zone*/,zero)
|
||||||
#define mi_track_resize(p,oldsize,newsize) VALGRIND_RESIZEINPLACE_BLOCK(p,oldsize,newsize,MI_PADDING_SIZE /*red zone*/)
|
#define mi_track_resize(p,oldsize,newsize) VALGRIND_RESIZEINPLACE_BLOCK(p,oldsize,newsize,MI_PADDING_SIZE /*red zone*/)
|
||||||
#define mi_track_free(p) VALGRIND_FREELIKE_BLOCK(p,MI_PADDING_SIZE /*red zone*/)
|
#define mi_track_free(p) VALGRIND_FREELIKE_BLOCK(p,MI_PADDING_SIZE /*red zone*/)
|
||||||
|
#define mi_track_free_size(p,_size) mi_track_free(p)
|
||||||
#define mi_track_mem_defined(p,size) VALGRIND_MAKE_MEM_DEFINED(p,size)
|
#define mi_track_mem_defined(p,size) VALGRIND_MAKE_MEM_DEFINED(p,size)
|
||||||
#define mi_track_mem_undefined(p,size) VALGRIND_MAKE_MEM_UNDEFINED(p,size)
|
#define mi_track_mem_undefined(p,size) VALGRIND_MAKE_MEM_UNDEFINED(p,size)
|
||||||
#define mi_track_mem_noaccess(p,size) VALGRIND_MAKE_MEM_NOACCESS(p,size)
|
#define mi_track_mem_noaccess(p,size) VALGRIND_MAKE_MEM_NOACCESS(p,size)
|
||||||
|
|
||||||
|
#elif MI_ASAN
|
||||||
|
|
||||||
|
#define MI_TRACK_ENABLED 1
|
||||||
|
#define MI_TRACK_TOOL "asan"
|
||||||
|
|
||||||
|
#include <sanitizer/asan_interface.h>
|
||||||
|
|
||||||
|
#define mi_track_malloc(p,size,zero) ASAN_UNPOISON_MEMORY_REGION(p,size)
|
||||||
|
#define mi_track_resize(p,oldsize,newsize) ASAN_POISON_MEMORY_REGION(p,oldsize); ASAN_UNPOISON_MEMORY_REGION(p,newsize)
|
||||||
|
#define mi_track_free(p) ASAN_POISON_MEMORY_REGION(p,mi_usable_size(p))
|
||||||
|
#define mi_track_free_size(p,size) ASAN_POISON_MEMORY_REGION(p,size)
|
||||||
|
#define mi_track_mem_defined(p,size) ASAN_UNPOISON_MEMORY_REGION(p,size)
|
||||||
|
#define mi_track_mem_undefined(p,size) ASAN_UNPOISON_MEMORY_REGION(p,size)
|
||||||
|
#define mi_track_mem_noaccess(p,size) ASAN_POISON_MEMORY_REGION(p,size)
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#define MI_TRACK_ENABLED 0
|
#define MI_TRACK_ENABLED 0
|
||||||
|
#define MI_TRACK_TOOL "none"
|
||||||
|
|
||||||
#define mi_track_malloc(p,size,zero)
|
#define mi_track_malloc(p,size,zero)
|
||||||
#define mi_track_resize(p,oldsize,newsize)
|
#define mi_track_resize(p,oldsize,newsize)
|
||||||
#define mi_track_free(p)
|
#define mi_track_free(p)
|
||||||
|
#define mi_track_free_size(p,_size)
|
||||||
#define mi_track_mem_defined(p,size)
|
#define mi_track_mem_defined(p,size)
|
||||||
#define mi_track_mem_undefined(p,size)
|
#define mi_track_mem_undefined(p,size)
|
||||||
#define mi_track_mem_noaccess(p,size)
|
#define mi_track_mem_noaccess(p,size)
|
||||||
|
|
|
@ -28,6 +28,8 @@ terms of the MIT license. A copy of the license can be found in the file
|
||||||
#define mi_decl_nodiscard [[nodiscard]]
|
#define mi_decl_nodiscard [[nodiscard]]
|
||||||
#elif (defined(__GNUC__) && (__GNUC__ >= 4)) || defined(__clang__) // includes clang, icc, and clang-cl
|
#elif (defined(__GNUC__) && (__GNUC__ >= 4)) || defined(__clang__) // includes clang, icc, and clang-cl
|
||||||
#define mi_decl_nodiscard __attribute__((warn_unused_result))
|
#define mi_decl_nodiscard __attribute__((warn_unused_result))
|
||||||
|
#elif defined(_HAS_NODISCARD)
|
||||||
|
#define mi_decl_nodiscard _NODISCARD
|
||||||
#elif (_MSC_VER >= 1700)
|
#elif (_MSC_VER >= 1700)
|
||||||
#define mi_decl_nodiscard _Check_return_
|
#define mi_decl_nodiscard _Check_return_
|
||||||
#else
|
#else
|
||||||
|
@ -530,7 +532,7 @@ template<class T> struct mi_heap_destroy_stl_allocator : public _mi_heap_stl_all
|
||||||
template<class U> mi_heap_destroy_stl_allocator(const mi_heap_destroy_stl_allocator<U>& x) mi_attr_noexcept : _mi_heap_stl_allocator_common<T, true>(x) { }
|
template<class U> mi_heap_destroy_stl_allocator(const mi_heap_destroy_stl_allocator<U>& x) mi_attr_noexcept : _mi_heap_stl_allocator_common<T, true>(x) { }
|
||||||
|
|
||||||
mi_heap_destroy_stl_allocator select_on_container_copy_construction() const { return *this; }
|
mi_heap_destroy_stl_allocator select_on_container_copy_construction() const { return *this; }
|
||||||
void deallocate(T* p, size_type) { /* do nothing as we destroy the heap on destruct. */ }
|
void deallocate(T*, size_type) { /* do nothing as we destroy the heap on destruct. */ }
|
||||||
template<class U> struct rebind { typedef mi_heap_destroy_stl_allocator<U> other; };
|
template<class U> struct rebind { typedef mi_heap_destroy_stl_allocator<U> other; };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -755,4 +755,3 @@ free list encoding](https://github.com/microsoft/mimalloc/blob/783e3377f79ee82af
|
||||||
* 2019-10-07, `v1.1.0`: stable release 1.1.
|
* 2019-10-07, `v1.1.0`: stable release 1.1.
|
||||||
* 2019-09-01, `v1.0.8`: pre-release 8: more robust windows dynamic overriding, initial huge page support.
|
* 2019-09-01, `v1.0.8`: pre-release 8: more robust windows dynamic overriding, initial huge page support.
|
||||||
* 2019-08-10, `v1.0.6`: pre-release 6: various performance improvements.
|
* 2019-08-10, `v1.0.6`: pre-release 6: various performance improvements.
|
||||||
|
|
||||||
|
|
|
@ -80,7 +80,7 @@ static mi_decl_noinline void* mi_heap_malloc_zero_aligned_at_fallback(mi_heap_t*
|
||||||
|
|
||||||
#if MI_TRACK_ENABLED
|
#if MI_TRACK_ENABLED
|
||||||
if (p != aligned_p) {
|
if (p != aligned_p) {
|
||||||
mi_track_free(p);
|
mi_track_free_size(p, oversize);
|
||||||
mi_track_malloc(aligned_p, size, zero);
|
mi_track_malloc(aligned_p, size, zero);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -306,4 +306,3 @@ mi_decl_nodiscard void* mi_recalloc_aligned_at(void* p, size_t newcount, size_t
|
||||||
mi_decl_nodiscard void* mi_recalloc_aligned(void* p, size_t newcount, size_t size, size_t alignment) mi_attr_noexcept {
|
mi_decl_nodiscard void* mi_recalloc_aligned(void* p, size_t newcount, size_t size, size_t alignment) mi_attr_noexcept {
|
||||||
return mi_heap_recalloc_aligned(mi_get_default_heap(), p, newcount, size, alignment);
|
return mi_heap_recalloc_aligned(mi_get_default_heap(), p, newcount, size, alignment);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -697,7 +697,7 @@ void* _mi_heap_realloc_zero(mi_heap_t* heap, void* p, size_t newsize, bool zero)
|
||||||
const size_t size = _mi_usable_size(p,"mi_realloc"); // also works if p == NULL (with size 0)
|
const size_t size = _mi_usable_size(p,"mi_realloc"); // also works if p == NULL (with size 0)
|
||||||
if mi_unlikely(newsize <= size && newsize >= (size / 2) && newsize > 0) { // note: newsize must be > 0 or otherwise we return NULL for realloc(NULL,0)
|
if mi_unlikely(newsize <= size && newsize >= (size / 2) && newsize > 0) { // note: newsize must be > 0 or otherwise we return NULL for realloc(NULL,0)
|
||||||
// todo: adjust potential padding to reflect the new size?
|
// todo: adjust potential padding to reflect the new size?
|
||||||
mi_track_free(p);
|
mi_track_free_size(p, size);
|
||||||
mi_track_malloc(p,newsize,true);
|
mi_track_malloc(p,newsize,true);
|
||||||
return p; // reallocation still fits and not more than 50% waste
|
return p; // reallocation still fits and not more than 50% waste
|
||||||
}
|
}
|
||||||
|
|
|
@ -558,6 +558,7 @@ void mi_process_init(void) mi_attr_noexcept {
|
||||||
_mi_verbose_message("debug level : %d\n", MI_DEBUG);
|
_mi_verbose_message("debug level : %d\n", MI_DEBUG);
|
||||||
#endif
|
#endif
|
||||||
_mi_verbose_message("secure level: %d\n", MI_SECURE);
|
_mi_verbose_message("secure level: %d\n", MI_SECURE);
|
||||||
|
_mi_verbose_message("mem tracking: %s\n", MI_TRACK_TOOL);
|
||||||
mi_thread_init();
|
mi_thread_init();
|
||||||
|
|
||||||
#if defined(_WIN32) && !defined(MI_SHARED_LIB)
|
#if defined(_WIN32) && !defined(MI_SHARED_LIB)
|
||||||
|
|
|
@ -106,7 +106,8 @@ void _mi_options_init(void) {
|
||||||
for(int i = 0; i < _mi_option_last; i++ ) {
|
for(int i = 0; i < _mi_option_last; i++ ) {
|
||||||
mi_option_t option = (mi_option_t)i;
|
mi_option_t option = (mi_option_t)i;
|
||||||
long l = mi_option_get(option); MI_UNUSED(l); // initialize
|
long l = mi_option_get(option); MI_UNUSED(l); // initialize
|
||||||
if (option != mi_option_verbose) {
|
// if (option != mi_option_verbose)
|
||||||
|
{
|
||||||
mi_option_desc_t* desc = &options[option];
|
mi_option_desc_t* desc = &options[option];
|
||||||
_mi_verbose_message("option '%s': %ld\n", desc->name, desc->value);
|
_mi_verbose_message("option '%s': %ld\n", desc->name, desc->value);
|
||||||
}
|
}
|
||||||
|
@ -179,13 +180,26 @@ static void mi_cdecl mi_out_stderr(const char* msg, void* arg) {
|
||||||
if (!_mi_preloading()) {
|
if (!_mi_preloading()) {
|
||||||
// _cputs(msg); // _cputs cannot be used at is aborts if it fails to lock the console
|
// _cputs(msg); // _cputs cannot be used at is aborts if it fails to lock the console
|
||||||
static HANDLE hcon = INVALID_HANDLE_VALUE;
|
static HANDLE hcon = INVALID_HANDLE_VALUE;
|
||||||
|
static bool hconIsConsole;
|
||||||
if (hcon == INVALID_HANDLE_VALUE) {
|
if (hcon == INVALID_HANDLE_VALUE) {
|
||||||
|
CONSOLE_SCREEN_BUFFER_INFO sbi;
|
||||||
hcon = GetStdHandle(STD_ERROR_HANDLE);
|
hcon = GetStdHandle(STD_ERROR_HANDLE);
|
||||||
|
hconIsConsole = ((hcon != INVALID_HANDLE_VALUE) && GetConsoleScreenBufferInfo(hcon, &sbi));
|
||||||
}
|
}
|
||||||
const size_t len = strlen(msg);
|
const size_t len = strlen(msg);
|
||||||
if (hcon != INVALID_HANDLE_VALUE && len > 0 && len < UINT32_MAX) {
|
if (len > 0 && len < UINT32_MAX) {
|
||||||
DWORD written = 0;
|
DWORD written = 0;
|
||||||
WriteConsoleA(hcon, msg, (DWORD)len, &written, NULL);
|
if (hconIsConsole) {
|
||||||
|
WriteConsoleA(hcon, msg, (DWORD)len, &written, NULL);
|
||||||
|
}
|
||||||
|
else if (hcon != INVALID_HANDLE_VALUE) {
|
||||||
|
// use direct write if stderr was redirected
|
||||||
|
WriteFile(hcon, msg, (DWORD)len, &written, NULL);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// finally fall back to fputs after all
|
||||||
|
fputs(msg, stderr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
@ -346,7 +360,7 @@ void _mi_fprintf( mi_output_fun* out, void* arg, const char* fmt, ... ) {
|
||||||
static void mi_vfprintf_thread(mi_output_fun* out, void* arg, const char* prefix, const char* fmt, va_list args) {
|
static void mi_vfprintf_thread(mi_output_fun* out, void* arg, const char* prefix, const char* fmt, va_list args) {
|
||||||
if (prefix != NULL && strlen(prefix) <= 32 && !_mi_is_main_thread()) {
|
if (prefix != NULL && strlen(prefix) <= 32 && !_mi_is_main_thread()) {
|
||||||
char tprefix[64];
|
char tprefix[64];
|
||||||
snprintf(tprefix, sizeof(tprefix), "%sthread 0x%zx: ", prefix, _mi_thread_id());
|
snprintf(tprefix, sizeof(tprefix), "%sthread 0x%llx: ", prefix, (unsigned long long)_mi_thread_id());
|
||||||
mi_vfprintf(out, arg, tprefix, fmt, args);
|
mi_vfprintf(out, arg, tprefix, fmt, args);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
11
src/os.c
11
src/os.c
|
@ -177,9 +177,11 @@ typedef struct MI_PROCESSOR_NUMBER_S { WORD Group; BYTE Number; BYTE Reserved; }
|
||||||
typedef VOID (__stdcall *PGetCurrentProcessorNumberEx)(MI_PROCESSOR_NUMBER* ProcNumber);
|
typedef VOID (__stdcall *PGetCurrentProcessorNumberEx)(MI_PROCESSOR_NUMBER* ProcNumber);
|
||||||
typedef BOOL (__stdcall *PGetNumaProcessorNodeEx)(MI_PROCESSOR_NUMBER* Processor, PUSHORT NodeNumber);
|
typedef BOOL (__stdcall *PGetNumaProcessorNodeEx)(MI_PROCESSOR_NUMBER* Processor, PUSHORT NodeNumber);
|
||||||
typedef BOOL (__stdcall* PGetNumaNodeProcessorMaskEx)(USHORT Node, PGROUP_AFFINITY ProcessorMask);
|
typedef BOOL (__stdcall* PGetNumaNodeProcessorMaskEx)(USHORT Node, PGROUP_AFFINITY ProcessorMask);
|
||||||
|
typedef BOOL (__stdcall *PGetNumaProcessorNode)(UCHAR Processor, PUCHAR NodeNumber);
|
||||||
static PGetCurrentProcessorNumberEx pGetCurrentProcessorNumberEx = NULL;
|
static PGetCurrentProcessorNumberEx pGetCurrentProcessorNumberEx = NULL;
|
||||||
static PGetNumaProcessorNodeEx pGetNumaProcessorNodeEx = NULL;
|
static PGetNumaProcessorNodeEx pGetNumaProcessorNodeEx = NULL;
|
||||||
static PGetNumaNodeProcessorMaskEx pGetNumaNodeProcessorMaskEx = NULL;
|
static PGetNumaNodeProcessorMaskEx pGetNumaNodeProcessorMaskEx = NULL;
|
||||||
|
static PGetNumaProcessorNode pGetNumaProcessorNode = NULL;
|
||||||
|
|
||||||
static bool mi_win_enable_large_os_pages(void)
|
static bool mi_win_enable_large_os_pages(void)
|
||||||
{
|
{
|
||||||
|
@ -245,6 +247,7 @@ void _mi_os_init(void)
|
||||||
pGetCurrentProcessorNumberEx = (PGetCurrentProcessorNumberEx)(void (*)(void))GetProcAddress(hDll, "GetCurrentProcessorNumberEx");
|
pGetCurrentProcessorNumberEx = (PGetCurrentProcessorNumberEx)(void (*)(void))GetProcAddress(hDll, "GetCurrentProcessorNumberEx");
|
||||||
pGetNumaProcessorNodeEx = (PGetNumaProcessorNodeEx)(void (*)(void))GetProcAddress(hDll, "GetNumaProcessorNodeEx");
|
pGetNumaProcessorNodeEx = (PGetNumaProcessorNodeEx)(void (*)(void))GetProcAddress(hDll, "GetNumaProcessorNodeEx");
|
||||||
pGetNumaNodeProcessorMaskEx = (PGetNumaNodeProcessorMaskEx)(void (*)(void))GetProcAddress(hDll, "GetNumaNodeProcessorMaskEx");
|
pGetNumaNodeProcessorMaskEx = (PGetNumaNodeProcessorMaskEx)(void (*)(void))GetProcAddress(hDll, "GetNumaNodeProcessorMaskEx");
|
||||||
|
pGetNumaProcessorNode = (PGetNumaProcessorNode)(void (*)(void))GetProcAddress(hDll, "GetNumaProcessorNode");
|
||||||
FreeLibrary(hDll);
|
FreeLibrary(hDll);
|
||||||
}
|
}
|
||||||
if (mi_option_is_enabled(mi_option_large_os_pages) || mi_option_is_enabled(mi_option_reserve_huge_os_pages)) {
|
if (mi_option_is_enabled(mi_option_large_os_pages) || mi_option_is_enabled(mi_option_reserve_huge_os_pages)) {
|
||||||
|
@ -1346,14 +1349,14 @@ static size_t mi_os_numa_nodex(void) {
|
||||||
(*pGetCurrentProcessorNumberEx)(&pnum);
|
(*pGetCurrentProcessorNumberEx)(&pnum);
|
||||||
USHORT nnode = 0;
|
USHORT nnode = 0;
|
||||||
BOOL ok = (*pGetNumaProcessorNodeEx)(&pnum, &nnode);
|
BOOL ok = (*pGetNumaProcessorNodeEx)(&pnum, &nnode);
|
||||||
if (ok) numa_node = nnode;
|
if (ok) { numa_node = nnode; }
|
||||||
}
|
}
|
||||||
else {
|
else if (pGetNumaProcessorNode != NULL) {
|
||||||
// Vista or earlier, use older API that is limited to 64 processors. Issue #277
|
// Vista or earlier, use older API that is limited to 64 processors. Issue #277
|
||||||
DWORD pnum = GetCurrentProcessorNumber();
|
DWORD pnum = GetCurrentProcessorNumber();
|
||||||
UCHAR nnode = 0;
|
UCHAR nnode = 0;
|
||||||
BOOL ok = GetNumaProcessorNode((UCHAR)pnum, &nnode);
|
BOOL ok = pGetNumaProcessorNode((UCHAR)pnum, &nnode);
|
||||||
if (ok) numa_node = nnode;
|
if (ok) { numa_node = nnode; }
|
||||||
}
|
}
|
||||||
return numa_node;
|
return numa_node;
|
||||||
}
|
}
|
||||||
|
|
23
src/random.c
23
src/random.c
|
@ -187,10 +187,27 @@ static bool os_random_buf(void* buf, size_t buf_len) {
|
||||||
return (RtlGenRandom(buf, (ULONG)buf_len) != 0);
|
return (RtlGenRandom(buf, (ULONG)buf_len) != 0);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
#pragma comment (lib,"bcrypt.lib")
|
|
||||||
#include <bcrypt.h>
|
#ifndef BCRYPT_USE_SYSTEM_PREFERRED_RNG
|
||||||
|
#define BCRYPT_USE_SYSTEM_PREFERRED_RNG 0x00000002
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef LONG (NTAPI *PBCryptGenRandom)(HANDLE, PUCHAR, ULONG, ULONG);
|
||||||
|
static PBCryptGenRandom pBCryptGenRandom = NULL;
|
||||||
|
|
||||||
static bool os_random_buf(void* buf, size_t buf_len) {
|
static bool os_random_buf(void* buf, size_t buf_len) {
|
||||||
return (BCryptGenRandom(NULL, (PUCHAR)buf, (ULONG)buf_len, BCRYPT_USE_SYSTEM_PREFERRED_RNG) >= 0);
|
if (pBCryptGenRandom == NULL) {
|
||||||
|
HINSTANCE hDll = LoadLibrary(TEXT("bcrypt.dll"));
|
||||||
|
if (hDll != NULL) {
|
||||||
|
pBCryptGenRandom = (PBCryptGenRandom)(void (*)(void))GetProcAddress(hDll, "BCryptGenRandom");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (pBCryptGenRandom == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return (pBCryptGenRandom(NULL, (PUCHAR)buf, (ULONG)buf_len, BCRYPT_USE_SYSTEM_PREFERRED_RNG) >= 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
34
src/stats.c
34
src/stats.c
|
@ -465,8 +465,6 @@ mi_msecs_t _mi_clock_end(mi_msecs_t start) {
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <psapi.h>
|
|
||||||
#pragma comment(lib,"psapi.lib")
|
|
||||||
|
|
||||||
static mi_msecs_t filetime_msecs(const FILETIME* ftime) {
|
static mi_msecs_t filetime_msecs(const FILETIME* ftime) {
|
||||||
ULARGE_INTEGER i;
|
ULARGE_INTEGER i;
|
||||||
|
@ -476,6 +474,22 @@ static mi_msecs_t filetime_msecs(const FILETIME* ftime) {
|
||||||
return msecs;
|
return msecs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct _PROCESS_MEMORY_COUNTERS {
|
||||||
|
DWORD cb;
|
||||||
|
DWORD PageFaultCount;
|
||||||
|
SIZE_T PeakWorkingSetSize;
|
||||||
|
SIZE_T WorkingSetSize;
|
||||||
|
SIZE_T QuotaPeakPagedPoolUsage;
|
||||||
|
SIZE_T QuotaPagedPoolUsage;
|
||||||
|
SIZE_T QuotaPeakNonPagedPoolUsage;
|
||||||
|
SIZE_T QuotaNonPagedPoolUsage;
|
||||||
|
SIZE_T PagefileUsage;
|
||||||
|
SIZE_T PeakPagefileUsage;
|
||||||
|
} PROCESS_MEMORY_COUNTERS;
|
||||||
|
typedef PROCESS_MEMORY_COUNTERS* PPROCESS_MEMORY_COUNTERS;
|
||||||
|
typedef BOOL (WINAPI *PGetProcessMemoryInfo)(HANDLE, PPROCESS_MEMORY_COUNTERS, DWORD);
|
||||||
|
static PGetProcessMemoryInfo pGetProcessMemoryInfo = NULL;
|
||||||
|
|
||||||
static void mi_stat_process_info(mi_msecs_t* elapsed, mi_msecs_t* utime, mi_msecs_t* stime, size_t* current_rss, size_t* peak_rss, size_t* current_commit, size_t* peak_commit, size_t* page_faults)
|
static void mi_stat_process_info(mi_msecs_t* elapsed, mi_msecs_t* utime, mi_msecs_t* stime, size_t* current_rss, size_t* peak_rss, size_t* current_commit, size_t* peak_commit, size_t* page_faults)
|
||||||
{
|
{
|
||||||
*elapsed = _mi_clock_end(mi_process_start);
|
*elapsed = _mi_clock_end(mi_process_start);
|
||||||
|
@ -486,8 +500,21 @@ static void mi_stat_process_info(mi_msecs_t* elapsed, mi_msecs_t* utime, mi_msec
|
||||||
GetProcessTimes(GetCurrentProcess(), &ct, &et, &st, &ut);
|
GetProcessTimes(GetCurrentProcess(), &ct, &et, &st, &ut);
|
||||||
*utime = filetime_msecs(&ut);
|
*utime = filetime_msecs(&ut);
|
||||||
*stime = filetime_msecs(&st);
|
*stime = filetime_msecs(&st);
|
||||||
|
|
||||||
|
// load psapi on demand
|
||||||
|
if (pGetProcessMemoryInfo == NULL) {
|
||||||
|
HINSTANCE hDll = LoadLibrary(TEXT("psapi.dll"));
|
||||||
|
if (hDll != NULL) {
|
||||||
|
pGetProcessMemoryInfo = (PGetProcessMemoryInfo)(void (*)(void))GetProcAddress(hDll, "GetProcessMemoryInfo");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// get process info
|
||||||
PROCESS_MEMORY_COUNTERS info;
|
PROCESS_MEMORY_COUNTERS info;
|
||||||
GetProcessMemoryInfo(GetCurrentProcess(), &info, sizeof(info));
|
memset(&info, 0, sizeof(info));
|
||||||
|
if (pGetProcessMemoryInfo != NULL) {
|
||||||
|
pGetProcessMemoryInfo(GetCurrentProcess(), &info, sizeof(info));
|
||||||
|
}
|
||||||
*current_rss = (size_t)info.WorkingSetSize;
|
*current_rss = (size_t)info.WorkingSetSize;
|
||||||
*peak_rss = (size_t)info.PeakWorkingSetSize;
|
*peak_rss = (size_t)info.PeakWorkingSetSize;
|
||||||
*current_commit = (size_t)info.PagefileUsage;
|
*current_commit = (size_t)info.PagefileUsage;
|
||||||
|
@ -589,4 +616,3 @@ mi_decl_export void mi_process_info(size_t* elapsed_msecs, size_t* user_msecs, s
|
||||||
if (peak_commit!=NULL) *peak_commit = peak_commit0;
|
if (peak_commit!=NULL) *peak_commit = peak_commit0;
|
||||||
if (page_faults!=NULL) *page_faults = page_faults0;
|
if (page_faults!=NULL) *page_faults = page_faults0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -383,4 +383,3 @@ static void mi_bins(void) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -31,9 +31,9 @@ terms of the MIT license. A copy of the license can be found in the file
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int main(int argc, char** argv) {
|
int main(int argc, char** argv) {
|
||||||
int* p = mi(malloc)(3*sizeof(int));
|
int* p = (int*)mi(malloc)(3*sizeof(int));
|
||||||
|
|
||||||
int* r = mi_malloc_aligned(8,16);
|
int* r = (int*)mi_malloc_aligned(8,16);
|
||||||
mi_free(r);
|
mi_free(r);
|
||||||
|
|
||||||
// illegal byte wise read
|
// illegal byte wise read
|
||||||
|
@ -42,7 +42,7 @@ int main(int argc, char** argv) {
|
||||||
mi(free)(c);
|
mi(free)(c);
|
||||||
|
|
||||||
// undefined access
|
// undefined access
|
||||||
int* q = mi(malloc)(sizeof(int));
|
int* q = (int*)mi(malloc)(sizeof(int));
|
||||||
printf("undefined: %d\n", *q);
|
printf("undefined: %d\n", *q);
|
||||||
|
|
||||||
// illegal int read
|
// illegal int read
|
||||||
|
|
Loading…
Add table
Reference in a new issue