tracy_rpmalloc.hpp (5356B)
1 /* rpmalloc.h - Memory allocator - Public Domain - 2016 Mattias Jansson / Rampant Pixels 2 * 3 * This library provides a cross-platform lock free thread caching malloc implementation in C11. 4 * The latest source code is always available at 5 * 6 * https://github.com/rampantpixels/rpmalloc 7 * 8 * This library is put in the public domain; you can redistribute it and/or modify it without any restrictions. 9 * 10 */ 11 12 #pragma once 13 14 #include <stddef.h> 15 16 #include "../common/TracyApi.h" 17 18 namespace tracy 19 { 20 21 #if defined(__clang__) || defined(__GNUC__) 22 # define RPMALLOC_ATTRIBUTE __attribute__((__malloc__)) 23 # define RPMALLOC_RESTRICT 24 # define RPMALLOC_CDECL 25 #elif defined(_MSC_VER) 26 # define RPMALLOC_ATTRIBUTE 27 # define RPMALLOC_RESTRICT __declspec(restrict) 28 # define RPMALLOC_CDECL __cdecl 29 #else 30 # define RPMALLOC_ATTRIBUTE 31 # define RPMALLOC_RESTRICT 32 # define RPMALLOC_CDECL 33 #endif 34 35 //! Flag to rpaligned_realloc to not preserve content in reallocation 36 #define RPMALLOC_NO_PRESERVE 1 37 38 typedef struct rpmalloc_global_statistics_t { 39 //! Current amount of virtual memory mapped (only if ENABLE_STATISTICS=1) 40 size_t mapped; 41 //! Current amount of memory in global caches for small and medium sizes (<64KiB) 42 size_t cached; 43 //! Total amount of memory mapped (only if ENABLE_STATISTICS=1) 44 size_t mapped_total; 45 //! Total amount of memory unmapped (only if ENABLE_STATISTICS=1) 46 size_t unmapped_total; 47 } rpmalloc_global_statistics_t; 48 49 typedef struct rpmalloc_thread_statistics_t { 50 //! Current number of bytes available for allocation from active spans 51 size_t active; 52 //! Current number of bytes available in thread size class caches 53 size_t sizecache; 54 //! Current number of bytes available in thread span caches 55 size_t spancache; 56 //! Current number of bytes in pending deferred deallocations 57 size_t deferred; 58 //! Total number of bytes transitioned from thread cache to global cache 59 size_t thread_to_global; 60 //! Total number of bytes transitioned from global cache to thread cache 61 size_t global_to_thread; 62 } rpmalloc_thread_statistics_t; 63 64 typedef struct rpmalloc_config_t { 65 //! Map memory pages for the given number of bytes. The returned address MUST be 66 // aligned to the rpmalloc span size, which will always be a power of two. 67 // Optionally the function can store an alignment offset in the offset variable 68 // in case it performs alignment and the returned pointer is offset from the 69 // actual start of the memory region due to this alignment. The alignment offset 70 // will be passed to the memory unmap function. The alignment offset MUST NOT be 71 // larger than 65535 (storable in an uint16_t), if it is you must use natural 72 // alignment to shift it into 16 bits. 73 void* (*memory_map)(size_t size, size_t* offset); 74 //! Unmap the memory pages starting at address and spanning the given number of bytes. 75 // If release is set to 1, the unmap is for an entire span range as returned by 76 // a previous call to memory_map and that the entire range should be released. 77 // If release is set to 0, the unmap is a partial decommit of a subset of the mapped 78 // memory range. 79 void (*memory_unmap)(void* address, size_t size, size_t offset, int release); 80 //! Size of memory pages. The page size MUST be a power of two in [512,16384] range 81 // (2^9 to 2^14) unless 0 - set to 0 to use system page size. All memory mapping 82 // requests to memory_map will be made with size set to a multiple of the page size. 83 size_t page_size; 84 //! Size of a span of memory pages. MUST be a multiple of page size, and in [4096,262144] 85 // range (unless 0 - set to 0 to use the default span size). 86 size_t span_size; 87 //! Number of spans to map at each request to map new virtual memory blocks. This can 88 // be used to minimize the system call overhead at the cost of virtual memory address 89 // space. The extra mapped pages will not be written until actually used, so physical 90 // committed memory should not be affected in the default implementation. 91 size_t span_map_count; 92 //! Debug callback if memory guards are enabled. Called if a memory overwrite is detected 93 void (*memory_overwrite)(void* address); 94 } rpmalloc_config_t; 95 96 extern int 97 rpmalloc_initialize(void); 98 99 extern int 100 rpmalloc_initialize_config(const rpmalloc_config_t* config); 101 102 extern const rpmalloc_config_t* 103 rpmalloc_config(void); 104 105 extern void 106 rpmalloc_finalize(void); 107 108 void 109 rpmalloc_thread_initialize(void); 110 111 extern void 112 rpmalloc_thread_finalize(void); 113 114 extern void 115 rpmalloc_thread_collect(void); 116 117 extern int 118 rpmalloc_is_thread_initialized(void); 119 120 extern void 121 rpmalloc_thread_statistics(rpmalloc_thread_statistics_t* stats); 122 123 extern void 124 rpmalloc_global_statistics(rpmalloc_global_statistics_t* stats); 125 126 TRACY_API RPMALLOC_RESTRICT void* 127 rpmalloc(size_t size) RPMALLOC_ATTRIBUTE; 128 129 TRACY_API void 130 rpfree(void* ptr); 131 132 extern RPMALLOC_RESTRICT void* 133 rpcalloc(size_t num, size_t size) RPMALLOC_ATTRIBUTE; 134 135 extern void* 136 rprealloc(void* ptr, size_t size); 137 138 extern void* 139 rpaligned_realloc(void* ptr, size_t alignment, size_t size, size_t oldsize, unsigned int flags); 140 141 extern RPMALLOC_RESTRICT void* 142 rpaligned_alloc(size_t alignment, size_t size) RPMALLOC_ATTRIBUTE; 143 144 extern RPMALLOC_RESTRICT void* 145 rpmemalign(size_t alignment, size_t size) RPMALLOC_ATTRIBUTE; 146 147 extern int 148 rpposix_memalign(void **memptr, size_t alignment, size_t size); 149 150 extern size_t 151 rpmalloc_usable_size(void* ptr); 152 153 }