Blender  V2.93
MEM_guardedalloc.h
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
17  * All rights reserved.
18  */
19 
49 #ifndef __MEM_GUARDEDALLOC_H__
50 #define __MEM_GUARDEDALLOC_H__
51 
52 /* Needed for uintptr_t and attributes, exception, don't use BLI anywhere else in `MEM_*` */
53 #include "../../source/blender/blenlib/BLI_compiler_attrs.h"
54 #include "../../source/blender/blenlib/BLI_sys_types.h"
55 
56 #ifdef __cplusplus
57 extern "C" {
58 #endif
59 
65 extern size_t (*MEM_allocN_len)(const void *vmemh) ATTR_WARN_UNUSED_RESULT;
66 
70 extern void (*MEM_freeN)(void *vmemh);
71 
72 #if 0 /* UNUSED */
76 extern short (*MEM_testN)(void *vmemh);
77 #endif
78 
82 extern void *(*MEM_dupallocN)(const void *vmemh) /* ATTR_MALLOC */ ATTR_WARN_UNUSED_RESULT;
83 
89 extern void *(*MEM_reallocN_id)(void *vmemh,
90  size_t len,
91  const char *str) /* ATTR_MALLOC */ ATTR_WARN_UNUSED_RESULT
92  ATTR_ALLOC_SIZE(2);
93 
97 extern void *(*MEM_recallocN_id)(void *vmemh,
98  size_t len,
99  const char *str) /* ATTR_MALLOC */ ATTR_WARN_UNUSED_RESULT
100  ATTR_ALLOC_SIZE(2);
101 
102 #define MEM_reallocN(vmemh, len) MEM_reallocN_id(vmemh, len, __func__)
103 #define MEM_recallocN(vmemh, len) MEM_recallocN_id(vmemh, len, __func__)
104 
110 extern void *(*MEM_callocN)(size_t len, const char *str) /* ATTR_MALLOC */ ATTR_WARN_UNUSED_RESULT
112 
118 extern void *(*MEM_calloc_arrayN)(size_t len,
119  size_t size,
120  const char *str) /* ATTR_MALLOC */ ATTR_WARN_UNUSED_RESULT
122 
127 extern void *(*MEM_mallocN)(size_t len, const char *str) /* ATTR_MALLOC */ ATTR_WARN_UNUSED_RESULT
129 
135 extern void *(*MEM_malloc_arrayN)(size_t len,
136  size_t size,
137  const char *str) /* ATTR_MALLOC */ ATTR_WARN_UNUSED_RESULT
138  ATTR_ALLOC_SIZE(1, 2) ATTR_NONNULL(3);
139 
144 extern void *(*MEM_mallocN_aligned)(size_t len,
145  size_t alignment,
146  const char *str) /* ATTR_MALLOC */ ATTR_WARN_UNUSED_RESULT
148 
153 extern void (*MEM_printmemlist_pydict)(void);
154 
158 extern void (*MEM_printmemlist)(void);
159 
161 extern void (*MEM_callbackmemlist)(void (*func)(void *));
162 
164 extern void (*MEM_printmemlist_stats)(void);
165 
167 extern void (*MEM_set_error_callback)(void (*func)(const char *));
168 
174 extern bool (*MEM_consistency_check)(void);
175 
177 extern void (*MEM_set_memory_debug)(void);
178 
180 extern size_t (*MEM_get_memory_in_use)(void);
182 extern unsigned int (*MEM_get_memory_blocks_in_use)(void);
183 
185 extern void (*MEM_reset_peak_memory)(void);
186 
188 extern size_t (*MEM_get_peak_memory)(void) ATTR_WARN_UNUSED_RESULT;
189 
190 #ifdef __GNUC__
191 # define MEM_SAFE_FREE(v) \
192  do { \
193  typeof(&(v)) _v = &(v); \
194  if (*_v) { \
195  /* Cast so we can free constant arrays. */ \
196  MEM_freeN((void *)*_v); \
197  *_v = NULL; \
198  } \
199  } while (0)
200 #else
201 # define MEM_SAFE_FREE(v) \
202  do { \
203  void **_v = (void **)&(v); \
204  if (*_v) { \
205  MEM_freeN(*_v); \
206  *_v = NULL; \
207  } \
208  } while (0)
209 #endif
210 
211 /* overhead for lockfree allocator (use to avoid slop-space) */
212 #define MEM_SIZE_OVERHEAD sizeof(size_t)
213 #define MEM_SIZE_OPTIMAL(size) ((size)-MEM_SIZE_OVERHEAD)
214 
215 #ifndef NDEBUG
216 extern const char *(*MEM_name_ptr)(void *vmemh);
217 #endif
218 
223 void MEM_init_memleak_detection(void);
224 
230 
236 void MEM_enable_fail_on_memleak(void);
237 
238 /* Switch allocator to fast mode, with less tracking.
239  *
240  * Use in the production code where performance is the priority, and exact details about allocation
241  * is not. This allocator keeps track of number of allocation and amount of allocated bytes, but it
242  * does not track of names of allocated blocks.
243  *
244  * NOTE: The switch between allocator types can only happen before any allocation did happen. */
245 void MEM_use_lockfree_allocator(void);
246 
247 /* Switch allocator to slow fully guarded mode.
248  *
249  * Use for debug purposes. This allocator contains lock section around every allocator call, which
250  * makes it slow. What is gained with this is the ability to have list of allocated blocks (in an
251  * addition to the tracking of number of allocations and amount of allocated bytes).
252  *
253  * NOTE: The switch between allocator types can only happen before any allocation did happen. */
254 void MEM_use_guarded_allocator(void);
255 
256 #ifdef __cplusplus
257 }
258 #endif /* __cplusplus */
259 
260 #ifdef __cplusplus
261 /* Allocation functions (for C++ only). */
262 # define MEM_CXX_CLASS_ALLOC_FUNCS(_id) \
263  public: \
264  void *operator new(size_t num_bytes) \
265  { \
266  return MEM_mallocN(num_bytes, _id); \
267  } \
268  void operator delete(void *mem) \
269  { \
270  if (mem) { \
271  MEM_freeN(mem); \
272  } \
273  } \
274  void *operator new[](size_t num_bytes) \
275  { \
276  return MEM_mallocN(num_bytes, _id "[]"); \
277  } \
278  void operator delete[](void *mem) \
279  { \
280  if (mem) { \
281  MEM_freeN(mem); \
282  } \
283  } \
284  void *operator new(size_t /*count*/, void *ptr) \
285  { \
286  return ptr; \
287  } \
288  /* This is the matching delete operator to the placement-new operator above. Both parameters \
289  * will have the same value. Without this, we get the warning C4291 on windows. */ \
290  void operator delete(void * /*ptr_to_free*/, void * /*ptr*/) \
291  { \
292  }
293 
294 /* Needed when type includes a namespace, then the namespace should not be
295  * specified after ~, so using a macro fails. */
296 template<class T> inline void OBJECT_GUARDED_DESTRUCTOR(T *what)
297 {
298  what->~T();
299 }
300 
301 # if defined __GNUC__
302 # define OBJECT_GUARDED_NEW(type, args...) new (MEM_mallocN(sizeof(type), __func__)) type(args)
303 # else
304 # define OBJECT_GUARDED_NEW(type, ...) \
305  new (MEM_mallocN(sizeof(type), __FUNCTION__)) type(__VA_ARGS__)
306 # endif
307 # define OBJECT_GUARDED_DELETE(what, type) \
308  { \
309  if (what) { \
310  OBJECT_GUARDED_DESTRUCTOR((type *)what); \
311  MEM_freeN(what); \
312  } \
313  } \
314  (void)0
315 # define OBJECT_GUARDED_SAFE_DELETE(what, type) \
316  { \
317  if (what) { \
318  OBJECT_GUARDED_DESTRUCTOR((type *)what); \
319  MEM_freeN(what); \
320  what = NULL; \
321  } \
322  } \
323  (void)0
324 #endif /* __cplusplus */
325 
326 #endif /* __MEM_GUARDEDALLOC_H__ */
#define ATTR_ALLOC_SIZE(...)
void BLI_kdtree_nd_() int BLI_kdtree_nd_() int BLI_kdtree_nd_() int BLI_kdtree_nd_() ATTR_WARN_UNUSED_RESULT
void MEM_use_guarded_allocator(void)
Definition: mallocn.c:148
void MEM_use_memleak_detection(bool enabled)
void *(* MEM_calloc_arrayN)(size_t len, size_t size, const char *str) ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(1
Definition: mallocn.c:46
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
void(* MEM_reset_peak_memory)(void)
Definition: mallocn.c:61
void MEM_enable_fail_on_memleak(void)
size_t(* MEM_get_memory_in_use)(void)
Definition: mallocn.c:59
void(* MEM_printmemlist_stats)(void)
Definition: mallocn.c:55
void(* MEM_set_memory_debug)(void)
Definition: mallocn.c:58
size_t(* MEM_get_peak_memory)(void) ATTR_WARN_UNUSED_RESULT
Definition: mallocn.c:62
void MEM_init_memleak_detection(void)
void *(* MEM_mallocN)(size_t len, const char *str) ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(1) ATTR_NONNULL(2)
Definition: mallocn.c:47
void(* MEM_set_error_callback)(void(*func)(const char *))
Definition: mallocn.c:56
size_t(* MEM_allocN_len)(const void *vmemh) ATTR_WARN_UNUSED_RESULT
Definition: mallocn.c:40
void MEM_use_lockfree_allocator(void)
Definition: mallocn.c:112
bool(* MEM_consistency_check)(void)
Definition: mallocn.c:57
unsigned int(* MEM_get_memory_blocks_in_use)(void)
Definition: mallocn.c:60
void(* MEM_printmemlist_pydict)(void)
Definition: mallocn.c:52
void *(* ATTR_NONNULL)(3)
Iterator New.
void *(* MEM_malloc_arrayN)(size_t len, size_t size, const char *str) ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(1
Definition: mallocn.c:48
void *(* MEM_mallocN_aligned)(size_t len, size_t alignment, const char *str) ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(1) ATTR_NONNULL(3)
Definition: mallocn.c:49
void(* MEM_callbackmemlist)(void(*func)(void *))
Definition: mallocn.c:54
void(* MEM_printmemlist)(void)
Definition: mallocn.c:53
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
#define str(s)
bool enabled
#define T
uint len