Blender  V2.93
mallocn.c
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 
23 #include "MEM_guardedalloc.h"
24 
25 /* to ensure strict conversions */
26 #include "../../source/blender/blenlib/BLI_strict_flags.h"
27 
28 #include <assert.h>
29 
30 #include "mallocn_intern.h"
31 
32 #ifdef WITH_JEMALLOC_CONF
33 /* If jemalloc is used, it reads this global variable and enables background
34  * threads to purge dirty pages. Otherwise we release memory too slowly or not
35  * at all if the thread that did the allocation stays inactive. */
36 const char *malloc_conf = "background_thread:true,dirty_decay_ms:4000";
37 #endif
38 
39 /* NOTE: Keep in sync with MEM_use_lockfree_allocator(). */
40 size_t (*MEM_allocN_len)(const void *vmemh) = MEM_lockfree_allocN_len;
41 void (*MEM_freeN)(void *vmemh) = MEM_lockfree_freeN;
42 void *(*MEM_dupallocN)(const void *vmemh) = MEM_lockfree_dupallocN;
43 void *(*MEM_reallocN_id)(void *vmemh, size_t len, const char *str) = MEM_lockfree_reallocN_id;
44 void *(*MEM_recallocN_id)(void *vmemh, size_t len, const char *str) = MEM_lockfree_recallocN_id;
45 void *(*MEM_callocN)(size_t len, const char *str) = MEM_lockfree_callocN;
46 void *(*MEM_calloc_arrayN)(size_t len, size_t size, const char *str) = MEM_lockfree_calloc_arrayN;
47 void *(*MEM_mallocN)(size_t len, const char *str) = MEM_lockfree_mallocN;
48 void *(*MEM_malloc_arrayN)(size_t len, size_t size, const char *str) = MEM_lockfree_malloc_arrayN;
49 void *(*MEM_mallocN_aligned)(size_t len,
50  size_t alignment,
51  const char *str) = MEM_lockfree_mallocN_aligned;
54 void (*MEM_callbackmemlist)(void (*func)(void *)) = MEM_lockfree_callbackmemlist;
56 void (*MEM_set_error_callback)(void (*func)(const char *)) = MEM_lockfree_set_error_callback;
63 
64 #ifndef NDEBUG
65 const char *(*MEM_name_ptr)(void *vmemh) = MEM_lockfree_name_ptr;
66 #endif
67 
68 void *aligned_malloc(size_t size, size_t alignment)
69 {
70  /* posix_memalign requires alignment to be a multiple of sizeof(void *). */
71  assert(alignment >= ALIGNED_MALLOC_MINIMUM_ALIGNMENT);
72 
73 #ifdef _WIN32
74  return _aligned_malloc(size, alignment);
75 #elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__APPLE__)
76  void *result;
77 
78  if (posix_memalign(&result, alignment, size)) {
79  /* non-zero means allocation error
80  * either no allocation or bad alignment value
81  */
82  return NULL;
83  }
84  return result;
85 #else /* This is for Linux. */
86  return memalign(alignment, size);
87 #endif
88 }
89 
90 void aligned_free(void *ptr)
91 {
92 #ifdef _WIN32
93  _aligned_free(ptr);
94 #else
95  free(ptr);
96 #endif
97 }
98 
99 /* Perform assert checks on allocator type change.
100  *
101  * Helps catching issues (in debug build) caused by an unintended allocator type change when there
102  * are allocation happened. */
104 {
105  /* NOTE: Assume that there is no "sticky" internal state which would make switching allocator
106  * type after all allocations are freed unsafe. In fact, it should be safe to change allocator
107  * type after all blocks has been freed: some regression tests do rely on this property of
108  * allocators. */
109  assert(MEM_get_memory_blocks_in_use() == 0);
110 }
111 
113 {
114  /* NOTE: Keep in sync with static initialization of the variables. */
115 
116  /* TODO(sergey): Find a way to de-duplicate the logic. Maybe by requiring an explicit call
117  * to guarded allocator initialization at an application startup. */
118 
120 
142 
143 #ifndef NDEBUG
145 #endif
146 }
147 
149 {
151 
173 
174 #ifndef NDEBUG
176 #endif
177 }
void BLI_kdtree_nd_() free(KDTree *tree)
Definition: kdtree_impl.h:116
Read Guarded memory(de)allocation.
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
#define str(s)
void MEM_use_guarded_allocator(void)
Definition: mallocn.c:148
size_t(* MEM_get_peak_memory)(void)
Definition: mallocn.c:62
void aligned_free(void *ptr)
Definition: mallocn.c:90
void *(* MEM_malloc_arrayN)(size_t len, size_t size, const char *str)
Definition: mallocn.c:48
void * aligned_malloc(size_t size, size_t alignment)
Definition: mallocn.c:68
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
void(* MEM_reset_peak_memory)(void)
Definition: mallocn.c:61
size_t(* MEM_get_memory_in_use)(void)
Definition: mallocn.c:59
void *(* MEM_dupallocN)(const void *vmemh)
Definition: mallocn.c:42
void *(* MEM_mallocN_aligned)(size_t len, size_t alignment, const char *str)
Definition: mallocn.c:49
void *(* MEM_calloc_arrayN)(size_t len, size_t size, const char *str)
Definition: mallocn.c:46
void(* MEM_printmemlist_stats)(void)
Definition: mallocn.c:55
void(* MEM_set_memory_debug)(void)
Definition: mallocn.c:58
void(* MEM_set_error_callback)(void(*func)(const char *))
Definition: mallocn.c:56
void *(* MEM_reallocN_id)(void *vmemh, size_t len, const char *str)
Definition: mallocn.c:43
size_t(* MEM_allocN_len)(const void *vmemh)
Definition: mallocn.c:40
void MEM_use_lockfree_allocator(void)
Definition: mallocn.c:112
bool(* MEM_consistency_check)(void)
Definition: mallocn.c:57
const char *(* MEM_name_ptr)(void *vmemh)
Definition: mallocn.c:65
void *(* MEM_recallocN_id)(void *vmemh, size_t len, const char *str)
Definition: mallocn.c:44
unsigned int(* MEM_get_memory_blocks_in_use)(void)
Definition: mallocn.c:60
void(* MEM_printmemlist_pydict)(void)
Definition: mallocn.c:52
static void assert_for_allocator_change(void)
Definition: mallocn.c:103
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:45
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:47
void(* MEM_callbackmemlist)(void(*func)(void *))
Definition: mallocn.c:54
void(* MEM_printmemlist)(void)
Definition: mallocn.c:53
size_t MEM_guarded_allocN_len(const void *vmemh)
const char * MEM_guarded_name_ptr(void *vmemh)
unsigned int MEM_guarded_get_memory_blocks_in_use(void)
void * MEM_guarded_callocN(size_t len, const char *str)
void * MEM_guarded_dupallocN(const void *vmemh)
void * MEM_guarded_calloc_arrayN(size_t len, size_t size, const char *str)
void MEM_guarded_set_error_callback(void(*func)(const char *))
void MEM_guarded_printmemlist(void)
void MEM_guarded_printmemlist_pydict(void)
void MEM_guarded_callbackmemlist(void(*func)(void *))
bool MEM_guarded_consistency_check(void)
void MEM_guarded_set_memory_debug(void)
void MEM_guarded_printmemlist_stats(void)
size_t MEM_guarded_get_peak_memory(void)
void * MEM_guarded_malloc_arrayN(size_t len, size_t size, const char *str)
void * MEM_guarded_mallocN(size_t len, const char *str)
void * MEM_guarded_mallocN_aligned(size_t len, size_t alignment, const char *str)
void * MEM_guarded_reallocN_id(void *vmemh, size_t len, const char *str)
void * MEM_guarded_recallocN_id(void *vmemh, size_t len, const char *str)
void MEM_guarded_reset_peak_memory(void)
size_t MEM_guarded_get_memory_in_use(void)
void MEM_guarded_freeN(void *vmemh)
void * MEM_lockfree_mallocN_aligned(size_t len, size_t alignment, const char *str) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(1) ATTR_NONNULL(3)
void * MEM_lockfree_mallocN(size_t len, const char *str) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(1) ATTR_NONNULL(2)
void * MEM_lockfree_reallocN_id(void *vmemh, size_t len, const char *str) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(2)
void MEM_lockfree_reset_peak_memory(void)
void * MEM_lockfree_recallocN_id(void *vmemh, size_t len, const char *str) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(2)
void MEM_lockfree_set_error_callback(void(*func)(const char *))
void MEM_lockfree_printmemlist_stats(void)
void MEM_lockfree_set_memory_debug(void)
void * MEM_lockfree_callocN(size_t len, const char *str) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(1) ATTR_NONNULL(2)
bool MEM_lockfree_consistency_check(void)
void * MEM_lockfree_dupallocN(const void *vmemh) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
const char * MEM_lockfree_name_ptr(void *vmemh)
void * MEM_lockfree_malloc_arrayN(size_t len, size_t size, const char *str) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(1
void MEM_lockfree_printmemlist_pydict(void)
#define ALIGNED_MALLOC_MINIMUM_ALIGNMENT
void MEM_lockfree_printmemlist(void)
void MEM_lockfree_freeN(void *vmemh)
size_t MEM_lockfree_allocN_len(const void *vmemh) ATTR_WARN_UNUSED_RESULT
void MEM_lockfree_callbackmemlist(void(*func)(void *))
void * MEM_lockfree_calloc_arrayN(size_t len, size_t size, const char *str) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(1
size_t MEM_lockfree_get_memory_in_use(void)
unsigned int MEM_lockfree_get_memory_blocks_in_use(void)
size_t MEM_lockfree_get_peak_memory(void) ATTR_WARN_UNUSED_RESULT
uint len
PointerRNA * ptr
Definition: wm_files.c:3157