Blender V5.0
BLI_mempool.cc File Reference
#include <algorithm>
#include <cstdlib>
#include <cstring>
#include "atomic_ops.h"
#include "BLI_utildefines.h"
#include "BLI_asan.h"
#include "BLI_math_base.h"
#include "BLI_mempool.h"
#include "BLI_mempool_private.h"
#include "MEM_guardedalloc.h"
#include "BLI_strict_flags.h"

Go to the source code of this file.

Classes

struct  BLI_freenode
struct  BLI_mempool_chunk
struct  BLI_mempool

Macros

#define POISON_REDZONE_SIZE   0
#define MAKE_ID(a, b, c, d)
#define MAKE_ID_8(a, b, c, d, e, f, g, h)
#define FREEWORD
#define USEDWORD   MAKE_ID('u', 's', 'e', 'd')
#define USE_CHUNK_POW2
#define MEMPOOL_ELEM_SIZE_MIN   (sizeof(void *) * 2)
#define CHUNK_DATA(chunk)
#define NODE_STEP_NEXT(node)
#define NODE_STEP_PREV(node)
#define CHUNK_OVERHEAD   uint(MEM_SIZE_OVERHEAD + sizeof(BLI_mempool_chunk))

Functions

static void mempool_asan_unlock (BLI_mempool *pool)
static void mempool_asan_lock (BLI_mempool *pool)
BLI_INLINE BLI_mempool_chunkmempool_chunk_find (BLI_mempool_chunk *head, uint index)
BLI_INLINE uint mempool_maxchunks (const uint elem_num, const uint pchunk)
static BLI_mempool_chunkmempool_chunk_alloc (const BLI_mempool *pool)
static BLI_freenodemempool_chunk_add (BLI_mempool *pool, BLI_mempool_chunk *mpchunk, BLI_freenode *last_tail)
static void mempool_chunk_free (BLI_mempool_chunk *mpchunk, BLI_mempool *pool)
static void mempool_chunk_free_all (BLI_mempool_chunk *mpchunk, BLI_mempool *pool)
BLI_mempoolBLI_mempool_create (uint esize, uint elem_num, uint pchunk, uint flag)
void * BLI_mempool_alloc (BLI_mempool *pool)
void * BLI_mempool_calloc (BLI_mempool *pool)
void BLI_mempool_free (BLI_mempool *pool, void *addr)
int BLI_mempool_len (const BLI_mempool *pool)
void * BLI_mempool_findelem (BLI_mempool *pool, uint index)
void BLI_mempool_as_array (BLI_mempool *pool, void *data)
void * BLI_mempool_as_arrayN (BLI_mempool *pool, const char *allocstr)
void BLI_mempool_iternew (BLI_mempool *pool, BLI_mempool_iter *iter)
static void mempool_threadsafe_iternew (BLI_mempool *pool, BLI_mempool_threadsafe_iter *ts_iter)
ParallelMempoolTaskDatamempool_iter_threadsafe_create (BLI_mempool *pool, const size_t iter_num)
void mempool_iter_threadsafe_destroy (ParallelMempoolTaskData *iter_arr)
void * BLI_mempool_iterstep (BLI_mempool_iter *iter)
void * mempool_iter_threadsafe_step (BLI_mempool_threadsafe_iter *ts_iter)
void BLI_mempool_clear_ex (BLI_mempool *pool, const int elem_num_reserve)
void BLI_mempool_clear (BLI_mempool *pool)
void BLI_mempool_destroy (BLI_mempool *pool)
void BLI_mempool_set_memory_debug ()

Variables

static bool mempool_debug_memset = false

Detailed Description

Simple, fast memory allocator for allocating many elements of the same size.

Supports:

Definition in file BLI_mempool.cc.

Macro Definition Documentation

◆ CHUNK_DATA

#define CHUNK_DATA ( chunk)
Value:
((BLI_freenode *)(CHECK_TYPE_INLINE(chunk, BLI_mempool_chunk *), (void *)((chunk) + 1)))
#define CHECK_TYPE_INLINE(val, type)

Definition at line 129 of file BLI_mempool.cc.

Referenced by BLI_mempool_free(), BLI_mempool_iterstep(), mempool_chunk_add(), and mempool_iter_threadsafe_step().

◆ CHUNK_OVERHEAD

#define CHUNK_OVERHEAD   uint(MEM_SIZE_OVERHEAD + sizeof(BLI_mempool_chunk))

Extra bytes implicitly used for every chunk alloc.

Definition at line 136 of file BLI_mempool.cc.

Referenced by BLI_mempool_create().

◆ FREEWORD

#define FREEWORD
Value:
((sizeof(void *) > sizeof(int32_t)) ? MAKE_ID_8('e', 'e', 'r', 'f', 'f', 'r', 'e', 'e') : \
MAKE_ID('e', 'f', 'f', 'e'))
#define MAKE_ID_8(a, b, c, d, e, f, g, h)
#define MAKE_ID(a, b, c, d)
Definition blendthumb.hh:49

Important that this value is not aligned with sizeof(void *). So having a pointer to 2/4/8... aligned memory is enough to ensure the freeword will never be used. To be safe, use a word that's the same in both directions.

Definition at line 61 of file BLI_mempool.cc.

Referenced by BLI_mempool_free(), BLI_mempool_iterstep(), mempool_chunk_add(), and mempool_iter_threadsafe_step().

◆ MAKE_ID

#define MAKE_ID ( a,
b,
c,
d )
Value:
(int(d) << 24 | int(c) << 16 | (b) << 8 | (a))

Definition at line 50 of file BLI_mempool.cc.

◆ MAKE_ID_8

#define MAKE_ID_8 ( a,
b,
c,
d,
e,
f,
g,
h )
Value:
(int64_t(h) << 56 | int64_t(g) << 48 | int64_t(f) << 40 | int64_t(e) << 32 | int64_t(d) << 24 | \
int64_t(c) << 16 | int64_t(b) << 8 | (a))
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
long long int int64_t

Definition at line 51 of file BLI_mempool.cc.

◆ MEMPOOL_ELEM_SIZE_MIN

#define MEMPOOL_ELEM_SIZE_MIN   (sizeof(void *) * 2)

Definition at line 127 of file BLI_mempool.cc.

Referenced by BLI_mempool_create().

◆ NODE_STEP_NEXT

#define NODE_STEP_NEXT ( node)
Value:
((BLI_freenode *)((char *)(node) + esize))

Definition at line 132 of file BLI_mempool.cc.

Referenced by BLI_mempool_as_array(), BLI_mempool_free(), and mempool_chunk_add().

◆ NODE_STEP_PREV

#define NODE_STEP_PREV ( node)
Value:
((BLI_freenode *)((char *)(node) - esize))

Definition at line 133 of file BLI_mempool.cc.

Referenced by BLI_mempool_free(), and mempool_chunk_add().

◆ POISON_REDZONE_SIZE

◆ USE_CHUNK_POW2

#define USE_CHUNK_POW2

Definition at line 71 of file BLI_mempool.cc.

◆ USEDWORD

#define USEDWORD   MAKE_ID('u', 's', 'e', 'd')

The 'used' word just needs to be set to something besides FREEWORD.

Definition at line 68 of file BLI_mempool.cc.

Referenced by BLI_mempool_alloc().

Function Documentation

◆ BLI_mempool_alloc()

◆ BLI_mempool_as_array()

◆ BLI_mempool_as_arrayN()

void * BLI_mempool_as_arrayN ( BLI_mempool * pool,
const char * allocstr )

◆ BLI_mempool_calloc()

◆ BLI_mempool_clear()

void BLI_mempool_clear ( BLI_mempool * pool)

Wrap BLI_mempool_clear_ex with no reserve set.

Definition at line 835 of file BLI_mempool.cc.

References BLI_mempool_clear_ex().

Referenced by BLI_array_store_clear(), bm_uidwalk_clear(), and bmo_planar_faces_exec().

◆ BLI_mempool_clear_ex()

void BLI_mempool_clear_ex ( BLI_mempool * pool,
int elem_num_reserve )

Empty the pool, as if it were just created.

Parameters
poolThe pool to clear.
elem_num_reserveOptionally reserve how many items should be kept from clearing.

Definition at line 787 of file BLI_mempool.cc.

References BLI_mempool::chunk_tail, BLI_mempool::chunks, BLI_mempool::free, BLI_mempool::maxchunks, mempool_chunk_add(), mempool_chunk_find(), mempool_chunk_free(), mempool_maxchunks(), BLI_mempool_chunk::next, BLI_mempool::pchunk, BLI_mempool::totused, VALGRIND_CREATE_MEMPOOL, and VALGRIND_DESTROY_MEMPOOL.

Referenced by BLI_ghash_clear_ex(), and BLI_mempool_clear().

◆ BLI_mempool_create()

◆ BLI_mempool_destroy()

◆ BLI_mempool_findelem()

◆ BLI_mempool_free()

◆ BLI_mempool_iternew()

◆ BLI_mempool_iterstep()

◆ BLI_mempool_len()

◆ BLI_mempool_set_memory_debug()

void BLI_mempool_set_memory_debug ( )

Definition at line 852 of file BLI_mempool.cc.

References mempool_debug_memset.

Referenced by arg_handle_debug_mode_set().

◆ mempool_asan_lock()

void mempool_asan_lock ( BLI_mempool * pool)
static

◆ mempool_asan_unlock()

void mempool_asan_unlock ( BLI_mempool * pool)
static

◆ mempool_chunk_add()

BLI_freenode * mempool_chunk_add ( BLI_mempool * pool,
BLI_mempool_chunk * mpchunk,
BLI_freenode * last_tail )
static

Initialize a chunk and add into pool->chunks

Parameters
poolThe pool to add the chunk into.
mpchunkThe new uninitialized chunk (can be malloc'd)
last_tailThe last element of the previous chunk (used when building free chunks initially)
Returns
The last chunk,

Definition at line 190 of file BLI_mempool.cc.

References BLI_asan_poison, BLI_asan_unpoison, BLI_assert, BLI_MEMPOOL_ALLOW_ITER, CHUNK_DATA, BLI_mempool::chunk_tail, BLI_mempool::chunks, BLI_mempool::esize, BLI_mempool::flag, BLI_mempool::free, FREEWORD, BLI_freenode::freeword, BLI_freenode::next, BLI_mempool_chunk::next, next, NODE_STEP_NEXT, NODE_STEP_PREV, BLI_mempool::pchunk, POISON_REDZONE_SIZE, and UNLIKELY.

Referenced by BLI_mempool_alloc(), BLI_mempool_clear_ex(), and BLI_mempool_create().

◆ mempool_chunk_alloc()

BLI_mempool_chunk * mempool_chunk_alloc ( const BLI_mempool * pool)
static

Definition at line 175 of file BLI_mempool.cc.

References BLI_mempool::csize, and MEM_mallocN().

Referenced by BLI_mempool_alloc(), and BLI_mempool_create().

◆ mempool_chunk_find()

BLI_INLINE BLI_mempool_chunk * mempool_chunk_find ( BLI_mempool_chunk * head,
uint index )

Definition at line 156 of file BLI_mempool.cc.

References BLI_INLINE, and BLI_mempool_chunk::next.

Referenced by BLI_mempool_clear_ex().

◆ mempool_chunk_free()

void mempool_chunk_free ( BLI_mempool_chunk * mpchunk,
BLI_mempool * pool )
static

◆ mempool_chunk_free_all()

void mempool_chunk_free_all ( BLI_mempool_chunk * mpchunk,
BLI_mempool * pool )
static

Definition at line 306 of file BLI_mempool.cc.

References mempool_chunk_free(), and BLI_mempool_chunk::next.

Referenced by BLI_mempool_destroy(), and BLI_mempool_free().

◆ mempool_iter_threadsafe_create()

ParallelMempoolTaskData * mempool_iter_threadsafe_create ( BLI_mempool * pool,
size_t iter_num )

Initialize an array of mempool iterators, BLI_MEMPOOL_ALLOW_ITER flag must be set.

This is used in threaded code, to generate as much iterators as needed (each task should have its own), such that each iterator goes over its own single chunk, and only getting the next chunk to iterate over has to be protected against concurrency (which can be done in a lock-less way).

To be used when creating a task for each single item in the pool is totally overkill.

See BLI_task_parallel_mempool implementation for detailed usage example.

Definition at line 592 of file BLI_mempool.cc.

References BLI_assert, BLI_MEMPOOL_ALLOW_ITER, BLI_mempool_iter::curchunk, BLI_mempool_threadsafe_iter::curchunk_threaded_shared, BLI_mempool::flag, i, BLI_mempool_threadsafe_iter::iter, MEM_calloc_arrayN(), MEM_callocN(), mempool_threadsafe_iternew(), and ParallelMempoolTaskData::ts_iter.

Referenced by BLI_task_parallel_mempool().

◆ mempool_iter_threadsafe_destroy()

void mempool_iter_threadsafe_destroy ( ParallelMempoolTaskData * iter_arr)

◆ mempool_iter_threadsafe_step()

◆ mempool_maxchunks()

BLI_INLINE uint mempool_maxchunks ( const uint elem_num,
const uint pchunk )
Returns
the number of chunks to allocate based on how many elements are needed.
Note
for small pools 1 is a good default, the elements need to be initialized, adding overhead on creation which is redundant if they aren't used.

Definition at line 170 of file BLI_mempool.cc.

References BLI_INLINE.

Referenced by BLI_mempool_clear_ex(), and BLI_mempool_create().

◆ mempool_threadsafe_iternew()

void mempool_threadsafe_iternew ( BLI_mempool * pool,
BLI_mempool_threadsafe_iter * ts_iter )
static

Variable Documentation

◆ mempool_debug_memset

bool mempool_debug_memset = false
static

Definition at line 74 of file BLI_mempool.cc.

Referenced by BLI_mempool_free(), and BLI_mempool_set_memory_debug().