Blender V4.3
BLI_memblock.c
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2008 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
11#include <stdlib.h>
12#include <string.h>
13
14#include "BLI_utildefines.h"
15
16#include "BLI_memblock.h" /* own include */
17
18#include "MEM_guardedalloc.h"
19
20#include "BLI_strict_flags.h" /* Keep last. */
21
22#define CHUNK_LIST_SIZE 16
23
44
46{
47 BLI_assert(elem_size < chunk_size);
48
49 BLI_memblock *mblk = MEM_mallocN(sizeof(BLI_memblock), "BLI_memblock");
50 mblk->elem_size = (int)elem_size;
51 mblk->elem_next = 0;
52 mblk->elem_last = -1;
53 mblk->chunk_size = (int)chunk_size;
55 mblk->chunk_list = MEM_callocN(sizeof(void *) * (uint)mblk->chunk_len, "chunk list");
56 mblk->chunk_list[0] = MEM_mallocN_aligned((uint)mblk->chunk_size, 32, "BLI_memblock chunk");
57 memset(mblk->chunk_list[0], 0x0, (uint)mblk->chunk_size);
58 mblk->chunk_max_ofs = (mblk->chunk_size / mblk->elem_size) * mblk->elem_size;
59 mblk->elem_next_ofs = 0;
60 mblk->chunk_next = 0;
61 return mblk;
62}
63
65{
66 int elem_per_chunk = mblk->chunk_size / mblk->elem_size;
67
68 if (free_callback) {
69 for (int i = 0; i <= mblk->elem_last; i++) {
70 int chunk_idx = i / elem_per_chunk;
71 int elem_idx = i - elem_per_chunk * chunk_idx;
72 void *val = (char *)(mblk->chunk_list[chunk_idx]) + mblk->elem_size * elem_idx;
73 free_callback(val);
74 }
75 }
76
77 for (int i = 0; i < mblk->chunk_len; i++) {
78 MEM_SAFE_FREE(mblk->chunk_list[i]);
79 }
81 MEM_freeN(mblk);
82}
83
85{
86 int elem_per_chunk = mblk->chunk_size / mblk->elem_size;
87 int last_used_chunk = mblk->elem_next / elem_per_chunk;
88
89 if (free_callback) {
90 for (int i = mblk->elem_last; i >= mblk->elem_next; i--) {
91 int chunk_idx = i / elem_per_chunk;
92 int elem_idx = i - elem_per_chunk * chunk_idx;
93 void *val = (char *)(mblk->chunk_list[chunk_idx]) + mblk->elem_size * elem_idx;
94 free_callback(val);
95 }
96 }
97
98 for (int i = last_used_chunk + 1; i < mblk->chunk_len; i++) {
99 MEM_SAFE_FREE(mblk->chunk_list[i]);
100 }
101
102 if (UNLIKELY(last_used_chunk + 1 < mblk->chunk_len - CHUNK_LIST_SIZE)) {
103 mblk->chunk_len -= CHUNK_LIST_SIZE;
104 mblk->chunk_list = MEM_recallocN(mblk->chunk_list, sizeof(void *) * (uint)mblk->chunk_len);
105 }
106
107 mblk->elem_last = mblk->elem_next - 1;
108 mblk->elem_next = 0;
109 mblk->elem_next_ofs = 0;
110 mblk->chunk_next = 0;
111}
112
114{
115 /* Bookkeeping. */
116 if (mblk->elem_last < mblk->elem_next) {
117 mblk->elem_last = mblk->elem_next;
118 }
119 mblk->elem_next++;
120
121 void *ptr = (char *)(mblk->chunk_list[mblk->chunk_next]) + mblk->elem_next_ofs;
122
123 mblk->elem_next_ofs += mblk->elem_size;
124
125 if (mblk->elem_next_ofs == mblk->chunk_max_ofs) {
126 mblk->elem_next_ofs = 0;
127 mblk->chunk_next++;
128
129 if (UNLIKELY(mblk->chunk_next >= mblk->chunk_len)) {
130 mblk->chunk_len += CHUNK_LIST_SIZE;
131 mblk->chunk_list = MEM_recallocN(mblk->chunk_list, sizeof(void *) * (uint)mblk->chunk_len);
132 }
133
134 if (UNLIKELY(mblk->chunk_list[mblk->chunk_next] == NULL)) {
136 (uint)mblk->chunk_size, 32, "BLI_memblock chunk");
137 memset(mblk->chunk_list[mblk->chunk_next], 0x0, (uint)mblk->chunk_size);
138 }
139 }
140 return ptr;
141}
142
144{
145 /* Small copy of the memblock used for better cache coherence. */
146 iter->chunk_list = mblk->chunk_list;
147 iter->end_index = mblk->elem_next;
148 iter->cur_index = 0;
149 iter->chunk_idx = 0;
150 iter->elem_ofs = 0;
151 iter->elem_size = mblk->elem_size;
152 iter->chunk_max_ofs = mblk->chunk_max_ofs;
153}
154
156{
157 if (iter->cur_index == iter->end_index) {
158 return NULL;
159 }
160
161 iter->cur_index++;
162
163 void *ptr = (char *)(iter->chunk_list[iter->chunk_idx]) + iter->elem_ofs;
164
165 iter->elem_ofs += iter->elem_size;
166
167 if (iter->elem_ofs == iter->chunk_max_ofs) {
168 iter->elem_ofs = 0;
169 iter->chunk_idx++;
170 }
171 return ptr;
172}
173
174void *BLI_memblock_elem_get(BLI_memblock *mblk, int chunk, int elem)
175{
176 BLI_assert(chunk < mblk->chunk_len);
177 int elem_per_chunk = mblk->chunk_size / mblk->elem_size;
178 chunk += elem / elem_per_chunk;
179 elem = elem % elem_per_chunk;
180 return (char *)(mblk->chunk_list[chunk]) + mblk->elem_size * elem;
181}
#define BLI_assert(a)
Definition BLI_assert.h:50
#define CHUNK_LIST_SIZE
void BLI_memblock_clear(BLI_memblock *mblk, MemblockValFreeFP free_callback)
BLI_memblock * BLI_memblock_create_ex(uint elem_size, uint chunk_size)
void * BLI_memblock_elem_get(BLI_memblock *mblk, int chunk, int elem)
void * BLI_memblock_iterstep(BLI_memblock_iter *iter)
void BLI_memblock_iternew(BLI_memblock *mblk, BLI_memblock_iter *iter)
void * BLI_memblock_alloc(BLI_memblock *mblk)
void BLI_memblock_destroy(BLI_memblock *mblk, MemblockValFreeFP free_callback)
void(* MemblockValFreeFP)(void *val)
unsigned int uint
#define UNLIKELY(x)
Read Guarded memory(de)allocation.
#define MEM_recallocN(vmemh, len)
#define MEM_SAFE_FREE(v)
#define NULL
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_aligned(size_t len, size_t alignment, const char *str)
Definition mallocn.cc:110
void *(* MEM_mallocN)(size_t len, const char *str)
Definition mallocn.cc:44
void MEM_freeN(void *vmemh)
Definition mallocn.cc:105
void *(* MEM_callocN)(size_t len, const char *str)
Definition mallocn.cc:42
void ** chunk_list
PointerRNA * ptr
Definition wm_files.cc:4126