34#ifdef WITH_MEM_VALGRIND
35# include "valgrind/memcheck.h"
41# define POISON_REDZONE_SIZE 32
43# define POISON_REDZONE_SIZE 0
49# define MAKE_ID(a, b, c, d) ((int)(a) << 24 | (int)(b) << 16 | (c) << 8 | (d))
50# define MAKE_ID_8(a, b, c, d, e, f, g, h) \
51 ((int64_t)(a) << 56 | (int64_t)(b) << 48 | (int64_t)(c) << 40 | (int64_t)(d) << 32 | \
52 (int64_t)(e) << 24 | (int64_t)(f) << 16 | (int64_t)(g) << 8 | (h))
55# define MAKE_ID(a, b, c, d) ((int)(d) << 24 | (int)(c) << 16 | (b) << 8 | (a))
56# define MAKE_ID_8(a, b, c, d, e, f, g, h) \
57 ((int64_t)(h) << 56 | (int64_t)(g) << 48 | (int64_t)(f) << 40 | (int64_t)(e) << 32 | \
58 (int64_t)(d) << 24 | (int64_t)(c) << 16 | (int64_t)(b) << 8 | (a))
68 ((sizeof(void *) > sizeof(int32_t)) ? MAKE_ID_8('e', 'e', 'r', 'f', 'f', 'r', 'e', 'e') : \
69 MAKE_ID('e', 'f', 'f', 'e'))
74#define USEDWORD MAKE_ID('u', 's', 'e', 'd')
133#define MEMPOOL_ELEM_SIZE_MIN (sizeof(void *) * 2)
135#define CHUNK_DATA(chunk) (CHECK_TYPE_INLINE(chunk, BLI_mempool_chunk *), (void *)((chunk) + 1))
137#define NODE_STEP_NEXT(node) ((void *)((char *)(node) + esize))
138#define NODE_STEP_PREV(node) ((void *)((char *)(node)-esize))
141#define CHUNK_OVERHEAD (uint)(MEM_SIZE_OVERHEAD + sizeof(BLI_mempool_chunk))
176 while (index-- && head) {
190 return (elem_num <= pchunk) ? 1 : ((elem_num / pchunk) + 1);
211 const uint esize = pool->esize;
216 if (pool->chunk_tail) {
217 pool->chunk_tail->next = mpchunk;
221 pool->chunks = mpchunk;
225 pool->chunk_tail = mpchunk;
228 pool->free = curnode;
238#ifdef WITH_MEM_VALGRIND
245#ifdef WITH_MEM_VALGRIND
246 VALGRIND_MAKE_MEM_UNDEFINED(curnode, pool->esize);
256#ifdef WITH_MEM_VALGRIND
261#ifdef WITH_MEM_VALGRIND
262 VALGRIND_MAKE_MEM_UNDEFINED(curnode, pool->esize);
275#ifdef WITH_MEM_VALGRIND
277 VALGRIND_MAKE_MEM_UNDEFINED(curnode, pool->esize);
284#ifdef WITH_MEM_VALGRIND
290#ifdef WITH_MEM_VALGRIND
291 VALGRIND_MAKE_MEM_UNDEFINED(curnode, pool->esize);
297#ifdef WITH_MEM_VALGRIND
302#ifdef WITH_MEM_VALGRIND
303 VALGRIND_MAKE_MEM_UNDEFINED(last_tail, pool->esize);
317#ifdef WITH_MEM_VALGRIND
318 VALGRIND_MAKE_MEM_DEFINED(mpchunk,
sizeof(
BLI_mempool_chunk) + pool->esize * pool->csize);
327 for (; mpchunk; mpchunk = mpchunk_next) {
328 mpchunk_next = mpchunk->
next;
360 pool->chunk_tail =
NULL;
371 pool->csize = esize * pchunk;
374#if defined(USE_CHUNK_POW2) && !defined(NDEBUG)
381 pool->pchunk = pchunk;
384 pool->maxchunks = maxchunks;
389 for (i = 0; i < maxchunks; i++) {
395#ifdef WITH_MEM_VALGRIND
412 free_pop = pool->free;
415#ifdef WITH_MEM_VALGRIND
433 pool->free = free_pop->
next;
436#ifdef WITH_MEM_VALGRIND
440 return (
void *)free_pop;
465 for (chunk = pool->chunks; chunk; chunk = chunk->
next) {
472 BLI_assert_msg(0,
"Attempt to free data which is not in pool.\n");
490 newhead->
next = pool->free;
491 pool->free = newhead;
497#ifdef WITH_MEM_VALGRIND
498 VALGRIND_MEMPOOL_FREE(pool, addr);
502 if (
UNLIKELY(pool->totused == 0) && (pool->chunks->next)) {
503 const uint esize = pool->esize;
508 first = pool->chunks;
511 pool->chunk_tail = first;
514#ifdef WITH_MEM_VALGRIND
519 pool->free = curnode;
539#ifdef WITH_MEM_VALGRIND
540 VALGRIND_MEMPOOL_FREE(pool,
CHUNK_DATA(first));
547 int ret = (
int)pool->totused;
558 if (index < (
uint)pool->totused) {
587 memcpy(p, elem, (
size_t)esize);
626 for (
size_t i = 1; i < iter_num; i++) {
629 ((*curchunk_threaded_shared) ? (*curchunk_threaded_shared)->next :
NULL);
671 ret = bli_mempool_iternext(iter);
692# ifdef WITH_MEM_VALGRIND
704# ifdef WITH_MEM_VALGRIND
711# ifdef WITH_MEM_VALGRIND
741# ifdef WITH_MEM_VALGRIND
763# ifdef WITH_MEM_VALGRIND
778# ifdef WITH_MEM_VALGRIND
793# ifdef WITH_MEM_VALGRIND
817#ifdef WITH_MEM_VALGRIND
822 if (elem_num_reserve == -1) {
823 maxchunks = pool->maxchunks;
831 if (mpchunk && mpchunk->
next) {
833 mpchunk_next = mpchunk->
next;
835 mpchunk = mpchunk_next;
838 mpchunk_next = mpchunk->
next;
840 }
while ((mpchunk = mpchunk_next));
846 chunks_temp = pool->chunks;
848 pool->chunk_tail =
NULL;
850 while ((mpchunk = chunks_temp)) {
851 chunks_temp = mpchunk->
next;
865#ifdef WITH_MEM_VALGRIND
#define BLI_asan_unpoison(addr, size)
#define BLI_asan_poison(addr, size)
#define BLI_assert_msg(a, msg)
#define VALGRIND_MEMPOOL_ALLOC(pool, addr, size)
#define VALGRIND_CREATE_MEMPOOL(pool, rzB, is_zeroed)
#define VALGRIND_DESTROY_MEMPOOL(pool)
#define MEMPOOL_ELEM_SIZE_MIN
void BLI_mempool_clear_ex(BLI_mempool *pool, const int elem_num_reserve)
#define NODE_STEP_PREV(node)
static bool mempool_debug_memset
ParallelMempoolTaskData * mempool_iter_threadsafe_create(BLI_mempool *pool, const size_t iter_num)
void * BLI_mempool_findelem(BLI_mempool *pool, uint index)
#define CHUNK_DATA(chunk)
void BLI_mempool_as_array(BLI_mempool *pool, void *data)
static void mempool_asan_lock(BLI_mempool *pool)
void mempool_iter_threadsafe_destroy(ParallelMempoolTaskData *iter_arr)
void * BLI_mempool_as_arrayN(BLI_mempool *pool, const char *allocstr)
void * BLI_mempool_alloc(BLI_mempool *pool)
int BLI_mempool_len(const BLI_mempool *pool)
void BLI_mempool_free(BLI_mempool *pool, void *addr)
void BLI_mempool_clear(BLI_mempool *pool)
static BLI_mempool_chunk * mempool_chunk_alloc(const BLI_mempool *pool)
static void mempool_threadsafe_iternew(BLI_mempool *pool, BLI_mempool_threadsafe_iter *ts_iter)
void BLI_mempool_set_memory_debug(void)
void BLI_mempool_iternew(BLI_mempool *pool, BLI_mempool_iter *iter)
static void mempool_asan_unlock(BLI_mempool *pool)
static void mempool_chunk_free(BLI_mempool_chunk *mpchunk, BLI_mempool *pool)
void * mempool_iter_threadsafe_step(BLI_mempool_threadsafe_iter *ts_iter)
struct BLI_freenode BLI_freenode
void * BLI_mempool_calloc(BLI_mempool *pool)
void BLI_mempool_destroy(BLI_mempool *pool)
struct BLI_mempool_chunk BLI_mempool_chunk
void * BLI_mempool_iterstep(BLI_mempool_iter *iter)
#define POISON_REDZONE_SIZE
static BLI_freenode * mempool_chunk_add(BLI_mempool *pool, BLI_mempool_chunk *mpchunk, BLI_freenode *last_tail)
BLI_mempool * BLI_mempool_create(uint esize, uint elem_num, uint pchunk, uint flag)
static void mempool_chunk_free_all(BLI_mempool_chunk *mpchunk, BLI_mempool *pool)
#define NODE_STEP_NEXT(node)
BLI_INLINE BLI_mempool_chunk * mempool_chunk_find(BLI_mempool_chunk *head, uint index)
BLI_INLINE uint mempool_maxchunks(const uint elem_num, const uint pchunk)
static uint power_of_2_max_u(uint x)
void BLI_mutex_init(ThreadMutex *mutex)
void BLI_mutex_lock(ThreadMutex *mutex)
void BLI_mutex_unlock(ThreadMutex *mutex)
pthread_mutex_t ThreadMutex
#define ARRAY_HAS_ITEM(arr_item, arr_start, arr_len)
#define POINTER_OFFSET(v, ofs)
Read Guarded memory(de)allocation.
#define MEM_SIZE_OVERHEAD
Provides wrapper around system-specific atomic primitives, and some extensions (faked-atomic operatio...
ATOMIC_INLINE void * atomic_cas_ptr(void **v, void *old, void *_new)
draw_view push_constant(Type::INT, "radiance_src") .push_constant(Type capture_info_buf storage_buf(1, Qualifier::READ, "ObjectBounds", "bounds_buf[]") .push_constant(Type draw_view int
void *(* MEM_mallocN)(size_t len, const char *str)
void *(* MEM_malloc_arrayN)(size_t len, size_t size, const char *str)
void MEM_freeN(void *vmemh)
struct BLI_freenode * next
struct BLI_mempool_chunk * next
struct BLI_mempool_chunk * curchunk
struct BLI_mempool_chunk ** curchunk_threaded_shared
BLI_mempool_chunk * chunks
BLI_mempool_chunk * chunk_tail
BLI_mempool_threadsafe_iter ts_iter