diff --git a/CMakeLists.txt b/CMakeLists.txt index 28dfe830..7aba5553 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,6 +12,7 @@ option(MI_XMALLOC "Enable abort() call on memory allocation failure by option(MI_SHOW_ERRORS "Show error and warning messages by default (only enabled by default in DEBUG mode)" OFF) option(MI_TRACK_VALGRIND "Compile with Valgrind support (adds a small overhead)" OFF) option(MI_TRACK_ASAN "Compile with address sanitizer support (adds a small overhead)" OFF) +option(MI_TRACK_ETW "Compile with Windows event tracing (ETW) 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_SEE_ASM "Generate assembly files" OFF) option(MI_OSX_INTERPOSE "Use interpose to override standard malloc on macOS" ON) @@ -165,6 +166,21 @@ if(MI_TRACK_ASAN) endif() endif() +if(MI_TRACK_ETW) + if NOT WIN32 + set(MI_TRACK_ETW OFF) + message(WARNING "Can only enable ETW support on Windows (MI_TRACK_ETW=OFF)") + endif() + if (MI_TRACK_VALGRIND OR MI_TRACK_ASAN) + set(MI_TRACK_ETW OFF) + message(WARNING "Cannot enable ETW support with also Valgrind or ASAN support enabled (MI_TRACK_ETW=OFF)") + endif() + if(MI_TRACK_ETW) + message(STATUS "Compile with Windows event tracing support (MI_TRACK_ETW=ON)") + list(APPEND mi_defines MI_TRACK_ETW=1) + endif() +endif() + if(MI_SEE_ASM) message(STATUS "Generate assembly listings (MI_SEE_ASM=ON)") list(APPEND mi_cflags -save-temps) diff --git a/include/mimalloc-etw.h b/include/mimalloc-etw.h deleted file mode 100644 index 3c894056..00000000 --- a/include/mimalloc-etw.h +++ /dev/null @@ -1,4 +0,0 @@ -#pragma once -#include -#include "mimalloc-etw-gen.h" - diff --git a/include/mimalloc-track.h b/include/mimalloc-track.h index 5e050512..f78e8daa 100644 --- a/include/mimalloc-track.h +++ b/include/mimalloc-track.h @@ -27,10 +27,12 @@ Optional: #define mi_track_align(p,alignedp,offset,size) #define mi_track_resize(p,oldsize,newsize) + #define mi_track_init() The `mi_track_align` is called right after a `mi_track_malloc` for aligned pointers in a block. The corresponding `mi_track_free` still uses the block start pointer and original size (corresponding to the `mi_track_malloc`). The `mi_track_resize` is currently unused but could be called on reallocations within a block. +`mi_track_init` is called at program start. The following macros are for tools like asan and valgrind to track whether memory is defined, undefined, or not accessible at all: @@ -42,6 +44,7 @@ defined, undefined, or not accessible at all: -------------------------------------------------------------------------------------------------------*/ #if MI_TRACK_VALGRIND +// valgrind tool #define MI_TRACK_ENABLED 1 #define MI_TRACK_HEAP_DESTROY 1 // track free of individual blocks on heap_destroy @@ -58,6 +61,7 @@ defined, undefined, or not accessible at all: #define mi_track_mem_noaccess(p,size) VALGRIND_MAKE_MEM_NOACCESS(p,size) #elif MI_TRACK_ASAN +// address sanitizer #define MI_TRACK_ENABLED 1 #define MI_TRACK_HEAP_DESTROY 0 @@ -71,19 +75,23 @@ defined, undefined, or not accessible at all: #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) -#elif MI_ETW -#define MI_TRACK_ENABLED 1 -#define MI_TRACK_TOOL "ETW" +#elif MI_TRACK_ETW +// windows event tracing -#include "mimalloc-etw.h" +#define MI_TRACK_ENABLED 1 +#define MI_TRACK_HEAP_DESTROY 0 +#define MI_TRACK_TOOL "ETW" -#define mi_track_malloc_size(p,reqsize,size,zero) EventWriteETW_MI_ALLOC((UINT64)p, size) -#define mi_track_free_size(p,size) EventWriteETW_MI_FREE((UINT64)p, size) -#define mi_track_mem_defined(p,size) -#define mi_track_mem_undefined(p,size) -#define mi_track_mem_noaccess(p,size) +#define WIN32_LEAN_AND_MEAN +#include +#include "../src/prim/windows/etw.h" + +#define mi_track_init() EventRegistermicrosoft_windows_mimalloc(); +#define mi_track_malloc_size(p,reqsize,size,zero) EventWriteETW_MI_ALLOC((UINT64)(p), size) +#define mi_track_free_size(p,size) EventWriteETW_MI_FREE((UINT64)(p), size) #else +// no tracking #define MI_TRACK_ENABLED 0 #define MI_TRACK_HEAP_DESTROY 0 @@ -91,11 +99,6 @@ defined, undefined, or not accessible at all: #define mi_track_malloc_size(p,reqsize,size,zero) #define mi_track_free_size(p,_size) -#define mi_track_align(p,alignedp,offset,size) -#define mi_track_resize(p,oldsize,newsize) -#define mi_track_mem_defined(p,size) -#define mi_track_mem_undefined(p,size) -#define mi_track_mem_noaccess(p,size) #endif @@ -110,6 +113,23 @@ defined, undefined, or not accessible at all: #define mi_track_align(p,alignedp,offset,size) mi_track_mem_noaccess(p,offset) #endif +#ifndef mi_track_init +#define mi_track_init() +#endif + +#ifndef mi_track_mem_defined +#define mi_track_mem_defined(p,size) +#endif + +#ifndef mi_track_mem_undefined +#define mi_track_mem_undefined(p,size) +#endif + +#ifndef mi_track_mem_noaccess +#define mi_track_mem_noaccess(p,size) +#endif + + #if MI_PADDING #define mi_track_malloc(p,reqsize,zero) \ if ((p)!=NULL) { \ diff --git a/include/mimalloc-types.h b/include/mimalloc-types.h index f8d891cb..ebf764ab 100644 --- a/include/mimalloc-types.h +++ b/include/mimalloc-types.h @@ -32,8 +32,7 @@ terms of the MIT license. A copy of the license can be found in the file // Define MI_TRACK_ to enable tracking support // #define MI_TRACK_VALGRIND 1 // #define MI_TRACK_ASAN 1 -// Define MI_ETW to enable ETW provider - #define MI_ETW 1 +#define MI_TRACK_ETW 1 // Define MI_STAT as 1 to maintain statistics; set it to 2 to have detailed statistics (but costs some performance). // #define MI_STAT 1 @@ -62,7 +61,7 @@ terms of the MIT license. A copy of the license can be found in the file // Reserve extra padding at the end of each block to be more resilient against heap block overflows. // The padding can detect buffer overflow on free. -#if !defined(MI_PADDING) && (MI_SECURE>=3 || MI_DEBUG>=1 || MI_TRACK_VALGRIND || MI_TRACK_ASAN || MI_ETW) +#if !defined(MI_PADDING) && (MI_SECURE>=3 || MI_DEBUG>=1 || (MI_TRACK_VALGRIND || MI_TRACK_ASAN || MI_TRACK_ETW)) #define MI_PADDING 1 #endif diff --git a/src/init.c b/src/init.c index 5574548e..495d26fd 100644 --- a/src/init.c +++ b/src/init.c @@ -534,6 +534,7 @@ void mi_process_init(void) mi_attr_noexcept { #endif mi_stats_reset(); // only call stat reset *after* thread init (or the heap tld == NULL) + mi_track_init(); if (mi_option_is_enabled(mi_option_reserve_huge_os_pages)) { size_t pages = mi_option_get_clamp(mi_option_reserve_huge_os_pages, 0, 128*1024); @@ -550,10 +551,6 @@ void mi_process_init(void) mi_attr_noexcept { mi_reserve_os_memory((size_t)ksize*MI_KiB, true, true); } } - -#ifdef MI_ETW - EventRegistermicrosoft_windows_mimalloc(); -#endif } // Called when the process is done (through `at_exit`) diff --git a/src/prim/readme.md b/src/prim/readme.md index 14248496..eb02f274 100644 --- a/src/prim/readme.md +++ b/src/prim/readme.md @@ -1,6 +1,8 @@ +## Portability Primitives + This is the portability layer where all primitives needed from the OS are defined. - `prim.h`: API definition -- `prim.c`: Selects one of `prim-unix.c`, `prim-wasi.c`, or `prim-windows.c` depending on the host platform. +- `prim.c`: Selects one of `unix/prim.c`, `wasi/prim.c`, or `windows/prim.c` depending on the host platform. -Note: still work in progress, there may be other places in the sources that still depend on OS ifdef's. \ No newline at end of file +Note: still work in progress, there may still be places in the sources that still depend on OS ifdef's. \ No newline at end of file diff --git a/include/mimalloc-etw-gen.h b/src/prim/windows/etw.h similarity index 100% rename from include/mimalloc-etw-gen.h rename to src/prim/windows/etw.h diff --git a/include/mimalloc-etw-gen.man b/src/prim/windows/etw.man similarity index 97% rename from include/mimalloc-etw-gen.man rename to src/prim/windows/etw.man index 9ef58029..cfd1f8a9 100644 Binary files a/include/mimalloc-etw-gen.man and b/src/prim/windows/etw.man differ diff --git a/include/mimalloc.wprp b/src/prim/windows/mimalloc.wprp similarity index 91% rename from include/mimalloc.wprp rename to src/prim/windows/mimalloc.wprp index 7f284e9d..b00cd7ad 100644 --- a/include/mimalloc.wprp +++ b/src/prim/windows/mimalloc.wprp @@ -29,7 +29,12 @@ - + + + + + + diff --git a/src/prim/windows/readme.md b/src/prim/windows/readme.md new file mode 100644 index 00000000..70292231 --- /dev/null +++ b/src/prim/windows/readme.md @@ -0,0 +1,17 @@ +## Primitives: + +- `prim.c` contains Windows primitives for OS allocation. + +## Event Tracing for Windows (ETW) + +- `etw.h` is generated from `etw.man` which contains the manifest for mimalloc events. + (100 is an allocation, 101 is for a free) + +- `mimalloc.wprp` is a profile for the Windows Performance Recorder (WPR). + In an admin prompt, you can use: + ``` + > wpr -start src\prim\windows\mimalloc.wprp -filemode + > + > wpr -stop test.etl + ``` + and then open `test.etl` in the Windows Performance Analyzer (WPA). \ No newline at end of file