Blender V4.3
BLI_mempool.c File Reference
#include <stdlib.h>
#include <string.h>
#include "atomic_ops.h"
#include "BLI_utildefines.h"
#include "BLI_asan.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)   ((int)(d) << 24 | (int)(c) << 16 | (b) << 8 | (a))
 
#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)   (CHECK_TYPE_INLINE(chunk, BLI_mempool_chunk *), (void *)((chunk) + 1))
 
#define NODE_STEP_NEXT(node)   ((void *)((char *)(node) + esize))
 
#define NODE_STEP_PREV(node)   ((void *)((char *)(node)-esize))
 
#define CHUNK_OVERHEAD   (uint)(MEM_SIZE_OVERHEAD + sizeof(BLI_mempool_chunk))
 

Typedefs

typedef struct BLI_freenode BLI_freenode
 
typedef struct BLI_mempool_chunk BLI_mempool_chunk
 

Functions

static void mempool_asan_unlock (BLI_mempool *pool)
 
static void mempool_asan_lock (BLI_mempool *pool)
 
static uint power_of_2_max_u (uint x)
 
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 (void)
 

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.c.

Macro Definition Documentation

◆ CHUNK_DATA

#define CHUNK_DATA ( chunk)    (CHECK_TYPE_INLINE(chunk, BLI_mempool_chunk *), (void *)((chunk) + 1))

◆ CHUNK_OVERHEAD

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

Extra bytes implicitly used for every chunk alloc.

Definition at line 141 of file BLI_mempool.c.

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)
Definition BLI_mempool.c:56
signed int int32_t
Definition stdint.h:77

Important that this value is an 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 67 of file BLI_mempool.c.

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 )   ((int)(d) << 24 | (int)(c) << 16 | (b) << 8 | (a))

Definition at line 55 of file BLI_mempool.c.

◆ 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
local_group_size(16, 16) .push_constant(Type b
__int64 int64_t
Definition stdint.h:89

Definition at line 56 of file BLI_mempool.c.

◆ MEMPOOL_ELEM_SIZE_MIN

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

Definition at line 133 of file BLI_mempool.c.

Referenced by BLI_mempool_create().

◆ NODE_STEP_NEXT

#define NODE_STEP_NEXT ( node)    ((void *)((char *)(node) + esize))

Definition at line 137 of file BLI_mempool.c.

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

◆ NODE_STEP_PREV

#define NODE_STEP_PREV ( node)    ((void *)((char *)(node)-esize))

Definition at line 138 of file BLI_mempool.c.

Referenced by BLI_mempool_free(), and mempool_chunk_add().

◆ POISON_REDZONE_SIZE

◆ USE_CHUNK_POW2

#define USE_CHUNK_POW2

Definition at line 77 of file BLI_mempool.c.

◆ USEDWORD

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

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

Definition at line 74 of file BLI_mempool.c.

Referenced by BLI_mempool_alloc().

Typedef Documentation

◆ BLI_freenode

typedef struct BLI_freenode BLI_freenode

A free element from BLI_mempool_chunk. Data is cast to this type and stored in BLI_mempool.free as a single linked list, each item BLI_mempool.esize large.

Each element represents a block which BLI_mempool_alloc may return.

◆ BLI_mempool_chunk

typedef struct BLI_mempool_chunk BLI_mempool_chunk

A chunk of memory in the mempool stored in BLI_mempool.chunks as a double linked list.

Function Documentation

◆ BLI_mempool_alloc()

◆ BLI_mempool_as_array()

◆ BLI_mempool_as_arrayN()

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

Definition at line 593 of file BLI_mempool.c.

References BLI_mempool_as_array(), data, and MEM_malloc_arrayN.

◆ BLI_mempool_calloc()

◆ BLI_mempool_clear()

void BLI_mempool_clear ( BLI_mempool * pool)

◆ 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 808 of file BLI_mempool.c.

References mempool_chunk_add(), mempool_chunk_find(), mempool_chunk_free(), mempool_maxchunks(), BLI_mempool_chunk::next, NULL, VALGRIND_CREATE_MEMPOOL, and VALGRIND_DESTROY_MEMPOOL.

Referenced by BLI_ghash_clear_ex(), BLI_mempool_clear(), and DRW_instance_data_list_resize().

◆ BLI_mempool_create()

◆ BLI_mempool_destroy()

◆ BLI_mempool_findelem()

◆ BLI_mempool_free()

void BLI_mempool_free ( BLI_mempool * pool,
void * addr )

◆ BLI_mempool_iternew()

◆ BLI_mempool_iterstep()

◆ BLI_mempool_len()

◆ BLI_mempool_set_memory_debug()

void BLI_mempool_set_memory_debug ( void )

Definition at line 873 of file BLI_mempool.c.

References mempool_debug_memset.

Referenced by arg_handle_debug_mode_set().

◆ mempool_asan_lock()

static void mempool_asan_lock ( BLI_mempool * pool)
static

◆ mempool_asan_unlock()

static void mempool_asan_unlock ( BLI_mempool * pool)
static

◆ mempool_chunk_add()

static 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 207 of file BLI_mempool.c.

References BLI_asan_poison, BLI_asan_unpoison, BLI_assert, BLI_MEMPOOL_ALLOW_ITER, CHUNK_DATA, FREEWORD, BLI_freenode::freeword, BLI_freenode::next, BLI_mempool_chunk::next, next, NODE_STEP_NEXT, NODE_STEP_PREV, NULL, POISON_REDZONE_SIZE, and UNLIKELY.

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

◆ mempool_chunk_alloc()

static BLI_mempool_chunk * mempool_chunk_alloc ( const BLI_mempool * pool)
static

Definition at line 193 of file BLI_mempool.c.

References 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 174 of file BLI_mempool.c.

References BLI_mempool_chunk::next.

Referenced by BLI_mempool_clear_ex().

◆ mempool_chunk_free()

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

Definition at line 310 of file BLI_mempool.c.

References BLI_asan_unpoison, MEM_freeN(), and UNUSED_VARS.

Referenced by BLI_mempool_clear_ex(), and mempool_chunk_free_all().

◆ mempool_chunk_free_all()

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

Definition at line 323 of file BLI_mempool.c.

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 615 of file BLI_mempool.c.

References BLI_assert, BLI_MEMPOOL_ALLOW_ITER, BLI_mempool_iter::curchunk, BLI_mempool_threadsafe_iter::curchunk_threaded_shared, BLI_mempool_threadsafe_iter::iter, MEM_mallocN, mempool_threadsafe_iternew(), NULL, 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 188 of file BLI_mempool.c.

Referenced by BLI_mempool_clear_ex(), and BLI_mempool_create().

◆ mempool_threadsafe_iternew()

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

◆ power_of_2_max_u()

static uint power_of_2_max_u ( uint x)
static

Definition at line 162 of file BLI_mempool.c.

Referenced by BLI_mempool_create().

Variable Documentation

◆ mempool_debug_memset

bool mempool_debug_memset = false
static

Definition at line 80 of file BLI_mempool.c.

Referenced by BLI_mempool_free(), and BLI_mempool_set_memory_debug().