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 | #pragma once |
8 | #ifndef MIMALLOC_H |
9 | #define MIMALLOC_H |
10 | |
11 | #define MI_MALLOC_VERSION 120 // major + 2 digits minor |
12 | |
13 | // ------------------------------------------------------ |
14 | // Compiler specific attributes |
15 | // ------------------------------------------------------ |
16 | |
17 | #ifdef __cplusplus |
18 | #if (__GNUC__ <= 5) || (_MSC_VER <= 1900) |
19 | #define mi_attr_noexcept throw() |
20 | #else |
21 | #define mi_attr_noexcept noexcept |
22 | #endif |
23 | #else |
24 | #define mi_attr_noexcept |
25 | #endif |
26 | |
27 | #ifdef _MSC_VER |
28 | #if !defined(MI_SHARED_LIB) |
29 | #define mi_decl_export |
30 | #elif defined(MI_SHARED_LIB_EXPORT) |
31 | #define mi_decl_export __declspec(dllexport) |
32 | #else |
33 | #define mi_decl_export __declspec(dllimport) |
34 | #endif |
35 | #if (_MSC_VER >= 1900) && !defined(__EDG__) |
36 | #define mi_decl_allocator __declspec(allocator) __declspec(restrict) |
37 | #else |
38 | #define mi_decl_allocator __declspec(restrict) |
39 | #endif |
40 | #define mi_decl_thread __declspec(thread) |
41 | #define mi_attr_malloc |
42 | #define mi_attr_alloc_size(s) |
43 | #define mi_attr_alloc_size2(s1,s2) |
44 | #define mi_cdecl __cdecl |
45 | #elif defined(__GNUC__) || defined(__clang__) |
46 | #define mi_decl_thread __thread |
47 | #define mi_decl_export __attribute__((visibility("default"))) |
48 | #define mi_decl_allocator |
49 | #define mi_attr_malloc __attribute__((malloc)) |
50 | #if defined(__clang_major__) && (__clang_major__ < 4) |
51 | #define mi_attr_alloc_size(s) |
52 | #define mi_attr_alloc_size2(s1,s2) |
53 | #else |
54 | #define mi_attr_alloc_size(s) __attribute__((alloc_size(s))) |
55 | #define mi_attr_alloc_size2(s1,s2) __attribute__((alloc_size(s1,s2))) |
56 | #endif |
57 | #define mi_cdecl // leads to warnings... __attribute__((cdecl)) |
58 | #else |
59 | #define mi_decl_thread __thread |
60 | #define mi_decl_export |
61 | #define mi_decl_allocator |
62 | #define mi_attr_malloc |
63 | #define mi_attr_alloc_size(s) |
64 | #define mi_attr_alloc_size2(s1,s2) |
65 | #define mi_cdecl |
66 | #endif |
67 | |
68 | // ------------------------------------------------------ |
69 | // Includes |
70 | // ------------------------------------------------------ |
71 | |
72 | #include <stddef.h> // size_t |
73 | #include <stdbool.h> // bool |
74 | |
75 | #ifdef __cplusplus |
76 | extern "C" { |
77 | #endif |
78 | |
79 | // ------------------------------------------------------ |
80 | // Standard malloc interface |
81 | // ------------------------------------------------------ |
82 | |
83 | mi_decl_export mi_decl_allocator void* mi_malloc(size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1); |
84 | mi_decl_export mi_decl_allocator void* mi_calloc(size_t count, size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size2(1,2); |
85 | mi_decl_export mi_decl_allocator void* mi_realloc(void* p, size_t newsize) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(2); |
86 | mi_decl_export mi_decl_allocator void* mi_expand(void* p, size_t newsize) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(2); |
87 | |
88 | mi_decl_export void mi_free(void* p) mi_attr_noexcept; |
89 | mi_decl_export char* mi_strdup(const char* s) mi_attr_noexcept; |
90 | mi_decl_export char* mi_strndup(const char* s, size_t n) mi_attr_noexcept; |
91 | mi_decl_export char* mi_realpath(const char* fname, char* resolved_name) mi_attr_noexcept; |
92 | |
93 | // ------------------------------------------------------ |
94 | // Extended functionality |
95 | // ------------------------------------------------------ |
96 | #define MI_SMALL_WSIZE_MAX (128) |
97 | #define MI_SMALL_SIZE_MAX (MI_SMALL_WSIZE_MAX*sizeof(void*)) |
98 | |
99 | mi_decl_export mi_decl_allocator void* mi_malloc_small(size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1); |
100 | mi_decl_export mi_decl_allocator void* mi_zalloc_small(size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1); |
101 | mi_decl_export mi_decl_allocator void* mi_zalloc(size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1); |
102 | |
103 | mi_decl_export mi_decl_allocator void* mi_mallocn(size_t count, size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size2(1,2); |
104 | mi_decl_export mi_decl_allocator void* mi_reallocn(void* p, size_t count, size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size2(2,3); |
105 | mi_decl_export mi_decl_allocator void* mi_reallocf(void* p, size_t newsize) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(2); |
106 | |
107 | |
108 | mi_decl_export size_t mi_usable_size(const void* p) mi_attr_noexcept; |
109 | mi_decl_export size_t mi_good_size(size_t size) mi_attr_noexcept; |
110 | |
111 | typedef void (mi_deferred_free_fun)(bool force, unsigned long long heartbeat); |
112 | mi_decl_export void mi_register_deferred_free(mi_deferred_free_fun* deferred_free) mi_attr_noexcept; |
113 | |
114 | typedef void (mi_output_fun)(const char* msg); |
115 | mi_decl_export void mi_register_output(mi_output_fun* out) mi_attr_noexcept; |
116 | |
117 | mi_decl_export void mi_collect(bool force) mi_attr_noexcept; |
118 | mi_decl_export int mi_version(void) mi_attr_noexcept; |
119 | mi_decl_export void mi_stats_reset(void) mi_attr_noexcept; |
120 | mi_decl_export void mi_stats_merge(void) mi_attr_noexcept; |
121 | mi_decl_export void mi_stats_print(mi_output_fun* out) mi_attr_noexcept; |
122 | |
123 | mi_decl_export void mi_process_init(void) mi_attr_noexcept; |
124 | mi_decl_export void mi_thread_init(void) mi_attr_noexcept; |
125 | mi_decl_export void mi_thread_done(void) mi_attr_noexcept; |
126 | mi_decl_export void mi_thread_stats_print(mi_output_fun* out) mi_attr_noexcept; |
127 | |
128 | |
129 | // ------------------------------------------------------------------------------------- |
130 | // Aligned allocation |
131 | // Note that `alignment` always follows `size` for consistency with unaligned |
132 | // allocation, but unfortunately this differs from `posix_memalign` and `aligned_alloc`. |
133 | // ------------------------------------------------------------------------------------- |
134 | |
135 | mi_decl_export mi_decl_allocator void* mi_malloc_aligned(size_t size, size_t alignment) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1); |
136 | mi_decl_export mi_decl_allocator void* mi_malloc_aligned_at(size_t size, size_t alignment, size_t offset) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1); |
137 | mi_decl_export mi_decl_allocator void* mi_zalloc_aligned(size_t size, size_t alignment) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1); |
138 | mi_decl_export mi_decl_allocator void* mi_zalloc_aligned_at(size_t size, size_t alignment, size_t offset) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1); |
139 | mi_decl_export mi_decl_allocator void* mi_calloc_aligned(size_t count, size_t size, size_t alignment) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size2(1,2); |
140 | mi_decl_export mi_decl_allocator void* mi_calloc_aligned_at(size_t count, size_t size, size_t alignment, size_t offset) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size2(1,2); |
141 | mi_decl_export mi_decl_allocator void* mi_realloc_aligned(void* p, size_t newsize, size_t alignment) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(2); |
142 | mi_decl_export mi_decl_allocator void* mi_realloc_aligned_at(void* p, size_t newsize, size_t alignment, size_t offset) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(2); |
143 | |
144 | |
145 | // ------------------------------------------------------ |
146 | // Heaps |
147 | // ------------------------------------------------------ |
148 | struct mi_heap_s; |
149 | typedef struct mi_heap_s mi_heap_t; |
150 | |
151 | mi_decl_export mi_heap_t* mi_heap_new(void); |
152 | mi_decl_export void mi_heap_delete(mi_heap_t* heap); |
153 | mi_decl_export void mi_heap_destroy(mi_heap_t* heap); |
154 | mi_decl_export mi_heap_t* mi_heap_set_default(mi_heap_t* heap); |
155 | mi_decl_export mi_heap_t* mi_heap_get_default(void); |
156 | mi_decl_export mi_heap_t* mi_heap_get_backing(void); |
157 | mi_decl_export void mi_heap_collect(mi_heap_t* heap, bool force) mi_attr_noexcept; |
158 | |
159 | mi_decl_export mi_decl_allocator void* mi_heap_malloc(mi_heap_t* heap, size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(2); |
160 | mi_decl_export mi_decl_allocator void* mi_heap_zalloc(mi_heap_t* heap, size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(2); |
161 | mi_decl_export mi_decl_allocator void* mi_heap_calloc(mi_heap_t* heap, size_t count, size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size2(2, 3); |
162 | mi_decl_export mi_decl_allocator void* mi_heap_mallocn(mi_heap_t* heap, size_t count, size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size2(2, 3); |
163 | mi_decl_export mi_decl_allocator void* mi_heap_malloc_small(mi_heap_t* heap, size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(2); |
164 | |
165 | mi_decl_export mi_decl_allocator void* mi_heap_realloc(mi_heap_t* heap, void* p, size_t newsize) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(3); |
166 | mi_decl_export mi_decl_allocator void* mi_heap_reallocn(mi_heap_t* heap, void* p, size_t count, size_t size) mi_attr_noexcept; |
167 | mi_decl_export mi_decl_allocator void* mi_heap_reallocf(mi_heap_t* heap, void* p, size_t newsize) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(3); |
168 | |
169 | mi_decl_export char* mi_heap_strdup(mi_heap_t* heap, const char* s) mi_attr_noexcept; |
170 | mi_decl_export char* mi_heap_strndup(mi_heap_t* heap, const char* s, size_t n) mi_attr_noexcept; |
171 | mi_decl_export char* mi_heap_realpath(mi_heap_t* heap, const char* fname, char* resolved_name) mi_attr_noexcept; |
172 | |
173 | mi_decl_export mi_decl_allocator void* mi_heap_malloc_aligned(mi_heap_t* heap, size_t size, size_t alignment) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(2); |
174 | mi_decl_export mi_decl_allocator void* mi_heap_malloc_aligned_at(mi_heap_t* heap, size_t size, size_t alignment, size_t offset) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(2); |
175 | mi_decl_export mi_decl_allocator void* mi_heap_zalloc_aligned(mi_heap_t* heap, size_t size, size_t alignment) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(2); |
176 | mi_decl_export mi_decl_allocator void* mi_heap_zalloc_aligned_at(mi_heap_t* heap, size_t size, size_t alignment, size_t offset) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(2); |
177 | mi_decl_export mi_decl_allocator void* mi_heap_calloc_aligned(mi_heap_t* heap, size_t count, size_t size, size_t alignment) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size2(2, 3); |
178 | mi_decl_export mi_decl_allocator void* mi_heap_calloc_aligned_at(mi_heap_t* heap, size_t count, size_t size, size_t alignment, size_t offset) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size2(2, 3); |
179 | mi_decl_export mi_decl_allocator void* mi_heap_realloc_aligned(mi_heap_t* heap, void* p, size_t newsize, size_t alignment) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(3); |
180 | mi_decl_export mi_decl_allocator void* mi_heap_realloc_aligned_at(mi_heap_t* heap, void* p, size_t newsize, size_t alignment, size_t offset) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(3); |
181 | |
182 | |
183 | // -------------------------------------------------------------------------------- |
184 | // Zero initialized re-allocation. |
185 | // Only valid on memory that was originally allocated with zero initialization too. |
186 | // e.g. `mi_calloc`, `mi_zalloc`, `mi_zalloc_aligned` etc. |
187 | // see <https://github.com/microsoft/mimalloc/issues/63#issuecomment-508272992> |
188 | // -------------------------------------------------------------------------------- |
189 | |
190 | mi_decl_export mi_decl_allocator void* mi_rezalloc(void* p, size_t newsize) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(2); |
191 | mi_decl_export mi_decl_allocator void* mi_recalloc(void* p, size_t newcount, size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size2(2,3); |
192 | |
193 | mi_decl_export mi_decl_allocator void* mi_rezalloc_aligned(void* p, size_t newsize, size_t alignment) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(2); |
194 | mi_decl_export mi_decl_allocator void* mi_rezalloc_aligned_at(void* p, size_t newsize, size_t alignment, size_t offset) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(2); |
195 | mi_decl_export mi_decl_allocator void* mi_recalloc_aligned(void* p, size_t newcount, size_t size, size_t alignment) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size2(2,3); |
196 | mi_decl_export mi_decl_allocator void* mi_recalloc_aligned_at(void* p, size_t newcount, size_t size, size_t alignment, size_t offset) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size2(2,3); |
197 | |
198 | mi_decl_export mi_decl_allocator void* mi_heap_rezalloc(mi_heap_t* heap, void* p, size_t newsize) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(3); |
199 | mi_decl_export mi_decl_allocator void* mi_heap_recalloc(mi_heap_t* heap, void* p, size_t newcount, size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size2(3,4); |
200 | |
201 | mi_decl_export mi_decl_allocator void* mi_heap_rezalloc_aligned(mi_heap_t* heap, void* p, size_t newsize, size_t alignment) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(3); |
202 | mi_decl_export mi_decl_allocator void* mi_heap_rezalloc_aligned_at(mi_heap_t* heap, void* p, size_t newsize, size_t alignment, size_t offset) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(3); |
203 | mi_decl_export mi_decl_allocator void* mi_heap_recalloc_aligned(mi_heap_t* heap, void* p, size_t newcount, size_t size, size_t alignment) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size2(3,4); |
204 | mi_decl_export mi_decl_allocator void* mi_heap_recalloc_aligned_at(mi_heap_t* heap, void* p, size_t newcount, size_t size, size_t alignment, size_t offset) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size2(3,4); |
205 | |
206 | |
207 | // ------------------------------------------------------ |
208 | // Analysis |
209 | // ------------------------------------------------------ |
210 | |
211 | mi_decl_export bool mi_heap_contains_block(mi_heap_t* heap, const void* p); |
212 | |
213 | mi_decl_export bool mi_heap_check_owned(mi_heap_t* heap, const void* p); |
214 | mi_decl_export bool mi_check_owned(const void* p); |
215 | |
216 | // An area of heap space contains blocks of a single size. |
217 | typedef struct mi_heap_area_s { |
218 | void* blocks; // start of the area containing heap blocks |
219 | size_t reserved; // bytes reserved for this area (virtual) |
220 | size_t committed; // current available bytes for this area |
221 | size_t used; // bytes in use by allocated blocks |
222 | size_t block_size; // size in bytes of each block |
223 | } mi_heap_area_t; |
224 | |
225 | typedef bool (mi_cdecl mi_block_visit_fun)(const mi_heap_t* heap, const mi_heap_area_t* area, void* block, size_t block_size, void* arg); |
226 | |
227 | mi_decl_export bool mi_heap_visit_blocks(const mi_heap_t* heap, bool visit_all_blocks, mi_block_visit_fun* visitor, void* arg); |
228 | |
229 | // Experimental |
230 | mi_decl_export bool mi_is_in_heap_region(const void* p) mi_attr_noexcept; |
231 | mi_decl_export int mi_reserve_huge_os_pages(size_t pages, double max_secs, size_t* pages_reserved) mi_attr_noexcept; |
232 | mi_decl_export bool mi_is_redirected() mi_attr_noexcept; |
233 | |
234 | // ------------------------------------------------------ |
235 | // Convenience |
236 | // ------------------------------------------------------ |
237 | |
238 | #define mi_malloc_tp(tp) ((tp*)mi_malloc(sizeof(tp))) |
239 | #define mi_zalloc_tp(tp) ((tp*)mi_zalloc(sizeof(tp))) |
240 | #define mi_calloc_tp(tp,n) ((tp*)mi_calloc(n,sizeof(tp))) |
241 | #define mi_mallocn_tp(tp,n) ((tp*)mi_mallocn(n,sizeof(tp))) |
242 | #define mi_reallocn_tp(p,tp,n) ((tp*)mi_reallocn(p,n,sizeof(tp))) |
243 | #define mi_recalloc_tp(p,tp,n) ((tp*)mi_recalloc(p,n,sizeof(tp))) |
244 | |
245 | #define mi_heap_malloc_tp(hp,tp) ((tp*)mi_heap_malloc(hp,sizeof(tp))) |
246 | #define mi_heap_zalloc_tp(hp,tp) ((tp*)mi_heap_zalloc(hp,sizeof(tp))) |
247 | #define mi_heap_calloc_tp(hp,tp,n) ((tp*)mi_heap_calloc(hp,n,sizeof(tp))) |
248 | #define mi_heap_mallocn_tp(hp,tp,n) ((tp*)mi_heap_mallocn(hp,n,sizeof(tp))) |
249 | #define mi_heap_reallocn_tp(hp,p,tp,n) ((tp*)mi_heap_reallocn(hp,p,n,sizeof(tp))) |
250 | #define mi_heap_recalloc_tp(hp,p,tp,n) ((tp*)mi_heap_recalloc(hp,p,n,sizeof(tp))) |
251 | |
252 | |
253 | // ------------------------------------------------------ |
254 | // Options, all `false` by default |
255 | // ------------------------------------------------------ |
256 | |
257 | typedef enum mi_option_e { |
258 | // stable options |
259 | mi_option_show_errors, |
260 | mi_option_show_stats, |
261 | mi_option_verbose, |
262 | // the following options are experimental |
263 | mi_option_eager_commit, |
264 | mi_option_eager_region_commit, |
265 | mi_option_large_os_pages, // implies eager commit |
266 | mi_option_reserve_huge_os_pages, |
267 | mi_option_segment_cache, |
268 | mi_option_page_reset, |
269 | mi_option_cache_reset, |
270 | mi_option_reset_decommits, |
271 | mi_option_eager_commit_delay, |
272 | mi_option_segment_reset, |
273 | mi_option_os_tag, |
274 | mi_option_max_errors, |
275 | _mi_option_last |
276 | } mi_option_t; |
277 | |
278 | |
279 | mi_decl_export bool mi_option_is_enabled(mi_option_t option); |
280 | mi_decl_export void mi_option_enable(mi_option_t option); |
281 | mi_decl_export void mi_option_disable(mi_option_t option); |
282 | mi_decl_export void mi_option_set_enabled(mi_option_t option, bool enable); |
283 | mi_decl_export void mi_option_set_enabled_default(mi_option_t option, bool enable); |
284 | |
285 | mi_decl_export long mi_option_get(mi_option_t option); |
286 | mi_decl_export void mi_option_set(mi_option_t option, long value); |
287 | mi_decl_export void mi_option_set_default(mi_option_t option, long value); |
288 | |
289 | |
290 | // ------------------------------------------------------------------------------------------------------- |
291 | // "mi" prefixed implementations of various posix, Unix, Windows, and C++ allocation functions. |
292 | // (This can be convenient when providing overrides of these functions as done in `mimalloc-override.h`.) |
293 | // ------------------------------------------------------------------------------------------------------- |
294 | |
295 | mi_decl_export size_t mi_malloc_size(const void* p) mi_attr_noexcept; |
296 | mi_decl_export size_t mi_malloc_usable_size(const void *p) mi_attr_noexcept; |
297 | mi_decl_export void mi_cfree(void* p) mi_attr_noexcept; |
298 | mi_decl_export void* mi__expand(void* p, size_t newsize) mi_attr_noexcept; |
299 | |
300 | mi_decl_export int mi_posix_memalign(void** p, size_t alignment, size_t size) mi_attr_noexcept; |
301 | mi_decl_export void* mi_memalign(size_t alignment, size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(2); |
302 | mi_decl_export void* mi_valloc(size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1); |
303 | |
304 | mi_decl_export void* mi_pvalloc(size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1); |
305 | mi_decl_export void* mi_aligned_alloc(size_t alignment, size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(2); |
306 | mi_decl_export void* mi_reallocarray(void* p, size_t count, size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size2(2,3); |
307 | |
308 | mi_decl_export void* mi_aligned_recalloc(void* p, size_t newcount, size_t size, size_t alignment) mi_attr_noexcept; |
309 | mi_decl_export void* mi_aligned_offset_recalloc(void* p, size_t newcount, size_t size, size_t alignment, size_t offset) mi_attr_noexcept; |
310 | |
311 | mi_decl_export unsigned short* mi_wcsdup(const unsigned short* s) mi_attr_noexcept; |
312 | mi_decl_export unsigned char* mi_mbsdup(const unsigned char* s) mi_attr_noexcept; |
313 | mi_decl_export int mi_dupenv_s(char** buf, size_t* size, const char* name) mi_attr_noexcept; |
314 | mi_decl_export int mi_wdupenv_s(unsigned short** buf, size_t* size, const unsigned short* name) mi_attr_noexcept; |
315 | |
316 | mi_decl_export void mi_free_size(void* p, size_t size) mi_attr_noexcept; |
317 | mi_decl_export void mi_free_size_aligned(void* p, size_t size, size_t alignment) mi_attr_noexcept; |
318 | mi_decl_export void mi_free_aligned(void* p, size_t alignment) mi_attr_noexcept; |
319 | |
320 | mi_decl_export void* mi_new(size_t n) mi_attr_malloc mi_attr_alloc_size(1); |
321 | mi_decl_export void* mi_new_aligned(size_t n, size_t alignment) mi_attr_malloc mi_attr_alloc_size(1); |
322 | mi_decl_export void* mi_new_nothrow(size_t n) mi_attr_malloc mi_attr_alloc_size(1); |
323 | mi_decl_export void* mi_new_aligned_nothrow(size_t n, size_t alignment) mi_attr_malloc mi_attr_alloc_size(1); |
324 | |
325 | #ifdef __cplusplus |
326 | } |
327 | #endif |
328 | |
329 | |
330 | #endif |
331 | |