Derive-C
Loading...
Searching...
No Matches
template.h File Reference

Go to the source code of this file.

Data Structures

struct  block_info
struct  SELF
 An allocator that prints to stdout when it allocates or frees memory. More...

Macros

#define BLOCK_SIZE   65536
 A chunked bump allocator that allocates memory in fixed-size blocks.
#define BLOCK_VECTOR   NS(NAME, block_vector)
#define ITEM   NS(NAME, block_info)
#define ITEM_CLONE   NS(NAME, block_info_clone)
#define ITEM_DELETE   NS(NAME, block_info_delete)
#define ITEM_DEBUG   NS(NAME, block_info_debug)
#define INTERNAL_NAME   BLOCK_VECTOR

Functions

 DC_STATIC_ASSERT (BLOCK_SIZE > 0, "Block size must be larger than zero")
static block_info block_info_clone (block_info const *self)
static void block_info_delete (block_info *)
static void block_info_debug (block_info const *, dc_debug_fmt, FILE *)
static DC_PUBLIC SELF new (ref alloc_ref)
static DC_INTERNAL void *PRIV allocate_new_blocks (SELF *self, size_t size)
static DC_PUBLIC void * allocate_uninit (SELF *self, size_t size)
static DC_PUBLIC void * allocate_zeroed (SELF *self, size_t size)
static DC_PUBLIC void deallocate (SELF *self, void *ptr, size_t size)
static DC_PUBLIC void * reallocate (SELF *self, void *ptr, size_t old_size, size_t new_size)
static DC_PUBLIC void reset (SELF *self)
static DC_PUBLIC void delete (SELF *self)
static DC_PUBLIC void debug (SELF const *self, dc_debug_fmt fmt, FILE *stream)
 DC_TRAIT_REFERENCABLE_BY_PTR (SELF)
 DC_TRAIT_ALLOC (SELF)

Macro Definition Documentation

◆ BLOCK_SIZE

#define BLOCK_SIZE   65536

A chunked bump allocator that allocates memory in fixed-size blocks.

Definition at line 15 of file template.h.

◆ BLOCK_VECTOR

#define BLOCK_VECTOR   NS(NAME, block_vector)

Definition at line 20 of file template.h.

◆ INTERNAL_NAME

#define INTERNAL_NAME   BLOCK_VECTOR

Definition at line 40 of file template.h.

◆ ITEM

#define ITEM   NS(NAME, block_info)

Definition at line 36 of file template.h.

◆ ITEM_CLONE

#define ITEM_CLONE   NS(NAME, block_info_clone)

Definition at line 37 of file template.h.

◆ ITEM_DEBUG

#define ITEM_DEBUG   NS(NAME, block_info_debug)

Definition at line 39 of file template.h.

◆ ITEM_DELETE

#define ITEM_DELETE   NS(NAME, block_info_delete)

Definition at line 38 of file template.h.

Function Documentation

◆ allocate_new_blocks()

DC_INTERNAL void *PRIV allocate_new_blocks ( SELF * self,
size_t size )
static

Definition at line 63 of file template.h.

63 {
64 DC_ASSUME(self);
65 DC_ASSERT(size > 0);
66
67 size_t num_blocks = (size + BLOCK_SIZE - 1) / BLOCK_SIZE;
68 size_t total_size = num_blocks * BLOCK_SIZE;
69
70 void* base_ptr = NS(ALLOC, allocate_uninit)(self->alloc_ref, total_size);
71
72 for (size_t i = 0; i < num_blocks; i++) {
73 void* block_ptr = (char*)base_ptr + (i * BLOCK_SIZE);
74 size_t block_count = (i == 0) ? num_blocks : 0;
75
76 NS(NAME, block_info) info = {.ptr = block_ptr, .num_blocks = block_count};
77 NS(BLOCK_VECTOR, push)(&self->blocks, info);
78 }
79
80 self->current_block_idx = NS(BLOCK_VECTOR, size)(&self->blocks) - 1;
82
83 if (self->current_block_offset == 0 && size > 0) {
85 }
86
88
89 return base_ptr;
90}
#define BLOCK_VECTOR
Definition template.h:20
#define BLOCK_SIZE
A chunked bump allocator that allocates memory in fixed-size blocks.
Definition template.h:15
static DC_PUBLIC void * allocate_uninit(SELF *self, size_t size)
Definition template.h:92
#define ALLOC
Definition template.h:31
static DC_PUBLIC size_t size(SELF const *self)
Definition template.h:252
static DC_PUBLIC ITEM * push(SELF *self, ITEM item)
Definition template.h:263
#define NAME
Supporting templates that internally invoke new templates.
Definition def.h:51
static DC_PUBLIC void dc_memory_tracker_set(dc_memory_tracker_level level, dc_memory_tracker_capability cap, const volatile void *addr, size_t size)
@ DC_MEMORY_TRACKER_LVL_ALLOC
@ DC_MEMORY_TRACKER_CAP_WRITE
#define NS(pre, post)
Definition namespace.h:14
#define DC_ASSERT(expr,...)
Definition panic.h:37
#define DC_ASSUME(expr,...)
Definition panic.h:57
BLOCK_VECTOR blocks
Definition template.h:46
size_t current_block_idx
Definition template.h:47
size_t current_block_offset
Definition template.h:48
ref alloc_ref
Definition template.h:49

◆ allocate_uninit()

DC_PUBLIC void * allocate_uninit ( SELF * self,
size_t size )
static

Definition at line 92 of file template.h.

92 {
93 DC_ASSUME(self);
94 DC_ASSERT(size > 0, "Cannot allocate zero sized");
95
96 size_t num_blocks = NS(BLOCK_VECTOR, size)(&self->blocks);
97 if (num_blocks > 0) {
98 size_t remaining = BLOCK_SIZE - self->current_block_offset;
99
100 if (remaining >= size) {
102 const* current_info = NS(BLOCK_VECTOR, read)(&self->blocks, self->current_block_idx);
103 void* allocation_ptr = (char*)current_info->ptr + self->current_block_offset;
104
105 self->current_block_offset += size;
106
108 allocation_ptr, size);
109
110 return allocation_ptr;
111 }
112 }
113
114 return PRIV(NS(SELF, allocate_new_blocks))(self, size);
115}
static DC_INTERNAL void *PRIV allocate_new_blocks(SELF *self, size_t size)
Definition template.h:63
static DC_PUBLIC VALUE const * read(SELF const *self, INDEX index)
Definition template.h:199
#define SELF
Definition def.h:52
#define PRIV(name)
Definition namespace.h:20

◆ allocate_zeroed()

DC_PUBLIC void * allocate_zeroed ( SELF * self,
size_t size )
static

Definition at line 117 of file template.h.

117 {
118 DC_ASSUME(self);
119 DC_ASSERT(size > 0, "Cannot allocate zero sized");
120
121 void* ptr = NS(SELF, allocate_uninit)(self, size);
122 memset(ptr, 0, size);
124 return ptr;
125}
@ DC_MEMORY_TRACKER_CAP_READ_WRITE

◆ block_info_clone()

block_info block_info_clone ( block_info const * self)
static

Definition at line 29 of file template.h.

29 {
30 return *self;
31}

◆ block_info_debug()

void block_info_debug ( block_info const * ,
dc_debug_fmt ,
FILE *  )
static

Definition at line 33 of file template.h.

34 {}

◆ block_info_delete()

void block_info_delete ( block_info * )
static

Definition at line 32 of file template.h.

32{}

◆ DC_STATIC_ASSERT()

DC_STATIC_ASSERT ( BLOCK_SIZE ,
0 ,
"Block size must be larger than zero"  )

◆ DC_TRAIT_ALLOC()

DC_TRAIT_ALLOC ( SELF )

◆ DC_TRAIT_REFERENCABLE_BY_PTR()

DC_TRAIT_REFERENCABLE_BY_PTR ( SELF )

◆ deallocate()

DC_PUBLIC void deallocate ( SELF * self,
void * ptr,
size_t size )
static

Definition at line 127 of file template.h.

127 {
128 DC_ASSUME(self);
129 DC_ASSUME(ptr); // deallocate requires non-null pointer
130 DC_ASSERT(size > 0, "Cannot deallocate zero sized");
131
132 // Bump allocators don't free individual items, but we poison the memory
133 // to catch use-after-free bugs
135}
@ DC_MEMORY_TRACKER_CAP_NONE

◆ debug()

DC_PUBLIC void debug ( SELF const * self,
dc_debug_fmt fmt,
FILE * stream )
static

Definition at line 212 of file template.h.

212 {
213 DC_ASSUME(self);
214 fprintf(stream, DC_EXPAND_STRING(SELF) "@%p {\n", (void*)self);
215 fmt = dc_debug_fmt_scope_begin(fmt);
216
217 dc_debug_fmt_print(fmt, stream, "block_size: %zu,\n", (size_t)BLOCK_SIZE);
218 dc_debug_fmt_print(fmt, stream, "num_blocks: %zu,\n", NS(BLOCK_VECTOR, size)(&self->blocks));
219 dc_debug_fmt_print(fmt, stream, "current_block_idx: %zu,\n", self->current_block_idx);
220 dc_debug_fmt_print(fmt, stream, "current_block_offset: %zu,\n", self->current_block_offset);
221
222 size_t total_allocated = 0;
223 size_t num_blocks = NS(BLOCK_VECTOR, size)(&self->blocks);
224 for (size_t i = 0; i < num_blocks; i++) {
225 NS(NAME, block_info) const* info = NS(BLOCK_VECTOR, read)(&self->blocks, i);
226 if (info->num_blocks > 0) {
227 total_allocated += info->num_blocks * BLOCK_SIZE;
228 }
229 }
230 dc_debug_fmt_print(fmt, stream, "total_allocated: %zu,\n", total_allocated);
231
232 dc_debug_fmt_print(fmt, stream, "alloc: ");
233 NS(ALLOC, debug)(NS(NS(ALLOC, ref), deref)(self->alloc_ref), fmt, stream);
234 fprintf(stream, "\n");
235
236 fmt = dc_debug_fmt_scope_end(fmt);
237 dc_debug_fmt_print(fmt, stream, "}");
238}
static DC_PUBLIC void debug(SELF const *self, dc_debug_fmt fmt, FILE *stream)
Definition template.h:212
static DC_PUBLIC void dc_debug_fmt_print(dc_debug_fmt fmt, FILE *stream, const char *format,...)
Definition fmt.h:32
static DC_PUBLIC dc_debug_fmt dc_debug_fmt_scope_end(dc_debug_fmt fmt)
Definition fmt.h:57
static DC_PUBLIC dc_debug_fmt dc_debug_fmt_scope_begin(dc_debug_fmt fmt)
Definition fmt.h:50
#define DC_EXPAND_STRING(NAME)
Definition namespace.h:6
static DC_PUBLIC FILE * stream(SELF *self)
Definition template.h:108

◆ delete()

DC_PUBLIC void delete ( SELF * self)
static

Definition at line 205 of file template.h.

205 {
206 DC_ASSUME(self);
207
208 NS(SELF, reset)(self);
209 NS(BLOCK_VECTOR, delete)(&self->blocks);
210}
static DC_PUBLIC void reset(SELF *self)
Definition template.h:186

◆ new()

DC_PUBLIC SELF new ( ref alloc_ref)
static

Definition at line 53 of file template.h.

53 {
54 return (SELF){
55 .blocks = NS(BLOCK_VECTOR, new)(alloc_ref),
56 .current_block_idx = 0,
57 .current_block_offset = 0,
58 .alloc_ref = alloc_ref,
59 .derive_c_chunkedbumpalloc = {},
60 };
61}

◆ reallocate()

DC_PUBLIC void * reallocate ( SELF * self,
void * ptr,
size_t old_size,
size_t new_size )
static

Definition at line 137 of file template.h.

138 {
139 DC_ASSUME(self);
140 DC_ASSUME(ptr);
141 DC_ASSERT(old_size > 0, "Cannot reallocate zero sized");
142 DC_ASSERT(new_size > 0, "Cannot allocate zero sized");
143
144 // Check if this is the last allocation and can be extended in place
145 size_t num_blocks = NS(BLOCK_VECTOR, size)(&self->blocks);
146 if (num_blocks > 0 && new_size > old_size) {
148 const* current_info = NS(BLOCK_VECTOR, read)(&self->blocks, self->current_block_idx);
149 char* expected_last_alloc =
150 (char*)current_info->ptr + self->current_block_offset - old_size;
151
152 if ((char*)ptr == expected_last_alloc) {
153 // This is the last allocation - check if we can extend in place
154 size_t extension = new_size - old_size;
155 size_t remaining = BLOCK_SIZE - self->current_block_offset;
156
157 if (extension <= remaining) {
158 // Can extend in place!
160 (char*)ptr + old_size, extension);
161 self->current_block_offset += extension;
162 return ptr;
163 }
164 }
165 }
166
167 // Can't extend in place, allocate new memory and copy
168 void* new_ptr = NS(SELF, allocate_uninit)(self, new_size);
169
170 size_t copy_size = (old_size < new_size) ? old_size : new_size;
171 memcpy(new_ptr, ptr, copy_size);
172
173 if (new_size <= old_size) {
175 new_ptr, new_size);
176 } else {
178 new_ptr, copy_size);
179 }
180
182
183 return new_ptr;
184}

◆ reset()

DC_PUBLIC void reset ( SELF * self)
static

Definition at line 186 of file template.h.

186 {
187 DC_ASSUME(self);
188
189 size_t num_blocks = NS(BLOCK_VECTOR, size)(&self->blocks);
190 for (size_t i = 0; i < num_blocks; i++) {
191 NS(NAME, block_info) const* info = NS(BLOCK_VECTOR, read)(&self->blocks, i);
192 if (info->num_blocks > 0) {
193 size_t total_size = info->num_blocks * BLOCK_SIZE;
195 info->ptr, total_size);
196 NS(ALLOC, deallocate)(self->alloc_ref, info->ptr, total_size);
197 }
198 }
199
200 NS(BLOCK_VECTOR, remove_at)(&self->blocks, 0, num_blocks);
201 self->current_block_idx = 0;
202 self->current_block_offset = 0;
203}
static DC_PUBLIC void deallocate(SELF *self, void *ptr, size_t size)
Definition template.h:127
static DC_PUBLIC void remove_at(SELF *self, size_t at, size_t count)
Definition template.h:211