Blender V4.3
mallocn.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2002-2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
11#include "MEM_guardedalloc.h"
12
13/* To ensure strict conversions. */
14#include "../../source/blender/blenlib/BLI_strict_flags.h"
15
16#include <cassert>
17
18#include "mallocn_intern.hh"
19
21
22using namespace mem_guarded::internal;
23
24#ifdef WITH_JEMALLOC_CONF
30const char *malloc_conf =
31 "background_thread:true,dirty_decay_ms:4000,thp:always,metadata_thp:always";
32#endif
33
34/* NOTE: Keep in sync with MEM_use_lockfree_allocator(). */
35
36size_t (*MEM_allocN_len)(const void *vmemh) = MEM_lockfree_allocN_len;
38 AllocationType allocation_type) = MEM_lockfree_freeN;
39void *(*MEM_dupallocN)(const void *vmemh) = MEM_lockfree_dupallocN;
40void *(*MEM_reallocN_id)(void *vmemh, size_t len, const char *str) = MEM_lockfree_reallocN_id;
41void *(*MEM_recallocN_id)(void *vmemh, size_t len, const char *str) = MEM_lockfree_recallocN_id;
42void *(*MEM_callocN)(size_t len, const char *str) = MEM_lockfree_callocN;
43void *(*MEM_calloc_arrayN)(size_t len, size_t size, const char *str) = MEM_lockfree_calloc_arrayN;
44void *(*MEM_mallocN)(size_t len, const char *str) = MEM_lockfree_mallocN;
45void *(*MEM_malloc_arrayN)(size_t len, size_t size, const char *str) = MEM_lockfree_malloc_arrayN;
46void *(*mem_guarded::internal::mem_mallocN_aligned_ex)(size_t len,
47 size_t alignment,
48 const char *str,
49 AllocationType allocation_type) =
51void *(*MEM_calloc_arrayN_aligned)(size_t len,
52 size_t size,
53 size_t alignment,
57void (*MEM_callbackmemlist)(void (*func)(void *)) = MEM_lockfree_callbackmemlist;
59void (*MEM_set_error_callback)(void (*func)(const char *)) = MEM_lockfree_set_error_callback;
66
68
69#ifndef NDEBUG
70const char *(*MEM_name_ptr)(void *vmemh) = MEM_lockfree_name_ptr;
71void (*MEM_name_ptr_set)(void *vmemh, const char *str) = MEM_lockfree_name_ptr_set;
72#endif
73
74void *aligned_malloc(size_t size, size_t alignment)
75{
76 /* #posix_memalign requires alignment to be a multiple of `sizeof(void *)`. */
77 assert(alignment >= ALIGNED_MALLOC_MINIMUM_ALIGNMENT);
78
79#ifdef _WIN32
80 return _aligned_malloc(size, alignment);
81#elif defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
82 void *result;
83
84 if (posix_memalign(&result, alignment, size)) {
85 /* non-zero means allocation error
86 * either no allocation or bad alignment value
87 */
88 return NULL;
89 }
90 return result;
91#else /* This is for Linux. */
92 return memalign(alignment, size);
93#endif
94}
95
96void aligned_free(void *ptr)
97{
98#ifdef _WIN32
99 _aligned_free(ptr);
100#else
101 free(ptr);
102#endif
103}
104
105void MEM_freeN(void *vmemh)
106{
107 mem_freeN_ex(vmemh, AllocationType::ALLOC_FREE);
108}
109
110void *MEM_mallocN_aligned(size_t len, size_t alignment, const char *str)
111{
112 return mem_mallocN_aligned_ex(len, alignment, str, AllocationType::ALLOC_FREE);
113}
114
122{
123 /* NOTE: Assume that there is no "sticky" internal state which would make switching allocator
124 * type after all allocations are freed unsafe. In fact, it should be safe to change allocator
125 * type after all blocks has been freed: some regression tests do rely on this property of
126 * allocators. */
127 assert(MEM_get_memory_blocks_in_use() == 0);
128}
129
131{
132 /* NOTE: Keep in sync with static initialization of the variables. */
133
134 /* TODO(sergey): Find a way to de-duplicate the logic. Maybe by requiring an explicit call
135 * to guarded allocator initialization at an application startup. */
136
138
161
163
164#ifndef NDEBUG
167#endif
168}
169
void BLI_kdtree_nd_ free(KDTree *tree)
unsigned int uint
Read Guarded memory(de)allocation.
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition btDbvt.cpp:52
#define NULL
int len
#define str(s)
size_t(* MEM_get_peak_memory)(void)
Definition mallocn.cc:65
void aligned_free(void *ptr)
Definition mallocn.cc:96
void MEM_use_lockfree_allocator()
Definition mallocn.cc:130
void * MEM_mallocN_aligned(size_t len, size_t alignment, const char *str)
Definition mallocn.cc:110
void *(* MEM_reallocN_id)(void *vmemh, size_t len, const char *str)
Definition mallocn.cc:40
void *(* MEM_mallocN)(size_t len, const char *str)
Definition mallocn.cc:44
void(* MEM_reset_peak_memory)(void)
Definition mallocn.cc:64
void(* MEM_name_ptr_set)(void *vmemh, const char *str)
Definition mallocn.cc:71
size_t(* MEM_get_memory_in_use)(void)
Definition mallocn.cc:62
const char *(* MEM_name_ptr)(void *vmemh)
Definition mallocn.cc:70
void *(* MEM_calloc_arrayN_aligned)(size_t len, size_t size, size_t alignment, const char *str)
Definition mallocn.cc:51
void *(* MEM_malloc_arrayN)(size_t len, size_t size, const char *str)
Definition mallocn.cc:45
void(* MEM_printmemlist_stats)(void)
Definition mallocn.cc:58
void(* MEM_set_memory_debug)(void)
Definition mallocn.cc:61
void(* mem_clearmemlist)(void)
Definition mallocn.cc:67
void(* MEM_set_error_callback)(void(*func)(const char *))
Definition mallocn.cc:59
void MEM_use_guarded_allocator()
Definition mallocn.cc:170
size_t(* MEM_allocN_len)(const void *vmemh)
Definition mallocn.cc:36
void *(* MEM_calloc_arrayN)(size_t len, size_t size, const char *str)
Definition mallocn.cc:43
void *(* MEM_recallocN_id)(void *vmemh, size_t len, const char *str)
Definition mallocn.cc:41
void MEM_freeN(void *vmemh)
Definition mallocn.cc:105
bool(* MEM_consistency_check)(void)
Definition mallocn.cc:60
void *(* MEM_callocN)(size_t len, const char *str)
Definition mallocn.cc:42
void(* MEM_printmemlist_pydict)(void)
Definition mallocn.cc:55
uint(* MEM_get_memory_blocks_in_use)(void)
Definition mallocn.cc:63
void * aligned_malloc(size_t size, size_t alignment)
Definition mallocn.cc:74
static void assert_for_allocator_change()
Definition mallocn.cc:121
void *(* MEM_dupallocN)(const void *vmemh)
Definition mallocn.cc:39
void(* MEM_callbackmemlist)(void(*func)(void *))
Definition mallocn.cc:57
void(* MEM_printmemlist)(void)
Definition mallocn.cc:56
void * MEM_guarded_mallocN_aligned(size_t len, size_t alignment, const char *str, const AllocationType allocation_type)
void * MEM_guarded_calloc_arrayN_aligned(const size_t len, const size_t size, const size_t alignment, const char *str)
size_t MEM_guarded_allocN_len(const void *vmemh)
void * MEM_guarded_mallocN(size_t len, const char *str)
size_t MEM_guarded_get_peak_memory()
void * MEM_guarded_calloc_arrayN(size_t len, size_t size, const char *str)
void MEM_guarded_reset_peak_memory()
void MEM_guarded_freeN(void *vmemh, const AllocationType allocation_type)
void MEM_guarded_set_error_callback(void(*func)(const char *))
bool MEM_guarded_consistency_check()
void MEM_guarded_printmemlist_pydict()
void MEM_guarded_callbackmemlist(void(*func)(void *))
void MEM_guarded_printmemlist()
uint MEM_guarded_get_memory_blocks_in_use()
void * MEM_guarded_callocN(size_t len, const char *str)
void * MEM_guarded_reallocN_id(void *vmemh, size_t len, const char *str)
void MEM_guarded_printmemlist_stats()
void * MEM_guarded_malloc_arrayN(size_t len, size_t size, const char *str)
void * MEM_guarded_dupallocN(const void *vmemh)
size_t MEM_guarded_get_memory_in_use()
void * MEM_guarded_recallocN_id(void *vmemh, size_t len, const char *str)
void MEM_guarded_name_ptr_set(void *vmemh, const char *str)
void MEM_guarded_set_memory_debug()
const char * MEM_guarded_name_ptr(void *vmemh)
void mem_guarded_clearmemlist()
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_dupallocN(const void *vmemh) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
void MEM_lockfree_freeN(void *vmemh, mem_guarded::internal::AllocationType allocation_type)
void MEM_lockfree_reset_peak_memory(void)
void mem_lockfree_clearmemlist(void)
void MEM_lockfree_name_ptr_set(void *vmemh, const char *str)
void * MEM_lockfree_mallocN_aligned(size_t len, size_t alignment, const char *str, mem_guarded::internal::AllocationType allocation_type) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(1) ATTR_NONNULL(3)
void * MEM_lockfree_calloc_arrayN(size_t len, size_t size, const char *str) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(1
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_reallocN_id(void *vmemh, size_t len, const char *str) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(2)
bool MEM_lockfree_consistency_check(void)
void * MEM_lockfree_callocN(size_t len, const char *str) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(1) ATTR_NONNULL(2)
void MEM_lockfree_printmemlist_pydict(void)
#define ALIGNED_MALLOC_MINIMUM_ALIGNMENT
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_mallocN(size_t len, const char *str) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(1) ATTR_NONNULL(2)
void MEM_lockfree_printmemlist(void)
size_t MEM_lockfree_allocN_len(const void *vmemh) ATTR_WARN_UNUSED_RESULT
const char * MEM_lockfree_name_ptr(void *vmemh)
void MEM_lockfree_callbackmemlist(void(*func)(void *))
void * MEM_lockfree_calloc_arrayN_aligned(size_t len, size_t size, size_t alignment, 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
void(* mem_freeN_ex)(void *vmemh, AllocationType allocation_type)
Definition mallocn.cc:37
void *(* mem_mallocN_aligned_ex)(size_t len, size_t alignment, const char *str, AllocationType allocation_type)
Definition mallocn.cc:46
PointerRNA * ptr
Definition wm_files.cc:4126