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

Go to the source code of this file.

Data Structures

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

Macros

#define BLOCK_SIZE   64
 A slab allocator for fixed-size allocations with freelist tracking.
#define SLAB_SIZE   4096
#define SLAB_VECTOR   NS(NAME, slab_vector)
#define ITEM   NS(NAME, slab_info)
#define ITEM_CLONE   NS(NAME, slab_info_clone)
#define ITEM_DELETE   NS(NAME, slab_info_delete)
#define ITEM_DEBUG   NS(NAME, slab_info_debug)
#define INTERNAL_NAME   SLAB_VECTOR

Functions

 DC_STATIC_ASSERT (BLOCK_SIZE > 0, "Block size must be larger than zero")
 DC_STATIC_ASSERT (SLAB_SIZE >=BLOCK_SIZE, "Slab size must be at least block size")
 DC_STATIC_ASSERT (BLOCK_SIZE >=sizeof(void *), "Block size must be at least pointer size for freelist")
static slab_info slab_info_clone (slab_info const *self)
static void slab_info_delete (slab_info *)
static void slab_info_debug (slab_info const *, dc_debug_fmt, FILE *)
static DC_PUBLIC SELF new (ref alloc_ref)
static DC_INTERNAL void PRIV allocate_new_slab (SELF *self)
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   64

A slab allocator for fixed-size allocations with freelist tracking.

Definition at line 15 of file template.h.

◆ INTERNAL_NAME

#define INTERNAL_NAME   SLAB_VECTOR

Definition at line 49 of file template.h.

◆ ITEM

#define ITEM   NS(NAME, slab_info)

Definition at line 45 of file template.h.

◆ ITEM_CLONE

#define ITEM_CLONE   NS(NAME, slab_info_clone)

Definition at line 46 of file template.h.

◆ ITEM_DEBUG

#define ITEM_DEBUG   NS(NAME, slab_info_debug)

Definition at line 48 of file template.h.

◆ ITEM_DELETE

#define ITEM_DELETE   NS(NAME, slab_info_delete)

Definition at line 47 of file template.h.

◆ SLAB_SIZE

#define SLAB_SIZE   4096

Definition at line 22 of file template.h.

◆ SLAB_VECTOR

#define SLAB_VECTOR   NS(NAME, slab_vector)

Definition at line 30 of file template.h.

Function Documentation

◆ allocate_new_slab()

DC_INTERNAL void PRIV allocate_new_slab ( SELF * self)
static

Definition at line 70 of file template.h.

70 {
71 DC_ASSUME(self);
72
73 size_t blocks_per_slab = SLAB_SIZE / BLOCK_SIZE;
74 void* slab_ptr = NS(ALLOC, allocate_uninit)(self->alloc_ref, SLAB_SIZE);
75
76 NS(NAME, slab_info) info = {.ptr = slab_ptr};
77 NS(SLAB_VECTOR, push)(&self->slabs, info);
78
79 for (size_t i = 0; i < blocks_per_slab; i++) {
80 void* block_ptr = (char*)slab_ptr + (i * BLOCK_SIZE);
81 // Temporarily unpoison to write the freelist pointer
83 block_ptr, sizeof(void*));
84 *(void**)block_ptr = self->free_list_head;
85 self->free_list_head = block_ptr;
86 // Mark the entire block as inaccessible (NONE) - including the freelist pointer
89 }
90}
#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 SLAB_SIZE
Definition template.h:22
#define SLAB_VECTOR
Definition template.h:30
#define ALLOC
Definition template.h:31
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_NONE
@ DC_MEMORY_TRACKER_CAP_READ_WRITE
#define NS(pre, post)
Definition namespace.h:14
#define DC_ASSUME(expr,...)
Definition panic.h:57
void * free_list_head
Definition template.h:56
ref alloc_ref
Definition template.h:49
SLAB_VECTOR slabs
Definition template.h:55

◆ 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 if (size > BLOCK_SIZE) {
97 return NS(ALLOC, allocate_uninit)(self->alloc_ref, size);
98 }
99
100 if (self->free_list_head == NULL) {
101 PRIV(NS(SELF, allocate_new_slab))(self);
102 }
103
104 void* block = self->free_list_head;
105
106 // Temporarily mark as READ_WRITE to read the freelist pointer
108 sizeof(void*));
109 void* next = *(void**)block;
110 self->free_list_head = next;
111
112 // Mark the allocated region as writable but uninitialized (WRITE)
114 // Mark any remaining space in the block as inaccessible
115 if (size < BLOCK_SIZE) {
117 (char*)block + size, BLOCK_SIZE - size);
118 }
119
120 return block;
121}
static DC_INTERNAL void PRIV allocate_new_slab(SELF *self)
Definition template.h:70
static DC_PUBLIC IV_PAIR next(ITER *iter)
Definition template.h:355
static DC_PUBLIC size_t size(SELF const *self)
Definition template.h:252
#define SELF
Definition def.h:52
@ DC_MEMORY_TRACKER_CAP_WRITE
#define PRIV(name)
Definition namespace.h:20
#define DC_ASSERT(expr,...)
Definition panic.h:37

◆ allocate_zeroed()

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

Definition at line 123 of file template.h.

123 {
124 DC_ASSUME(self);
125 DC_ASSERT(size > 0, "Cannot allocate zero sized");
126
127 void* ptr = NS(SELF, allocate_uninit)(self, size);
128 memset(ptr, 0, size);
130 return ptr;
131}

◆ DC_STATIC_ASSERT() [1/3]

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

◆ DC_STATIC_ASSERT() [2/3]

DC_STATIC_ASSERT ( BLOCK_SIZE >= sizeofvoid *,
"Block size must be at least pointer size for freelist"  )

◆ DC_STATIC_ASSERT() [3/3]

DC_STATIC_ASSERT ( SLAB_SIZE >= BLOCK_SIZE,
"Slab size must be at least block size"  )

◆ 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 133 of file template.h.

133 {
134 DC_ASSUME(self);
135 DC_ASSUME(ptr);
136 DC_ASSERT(size > 0, "Cannot deallocate zero sized");
137
138 if (size > BLOCK_SIZE) {
139 NS(ALLOC, deallocate)(self->alloc_ref, ptr, size);
140 return;
141 }
142
143 // Temporarily unpoison to write the freelist pointer
145 sizeof(void*));
146 *(void**)ptr = self->free_list_head;
147 self->free_list_head = ptr;
148
149 // Mark the entire block as inaccessible (NONE) - including the freelist pointer
151}
static DC_PUBLIC void deallocate(SELF *self, void *ptr, size_t size)
Definition template.h:127

◆ debug()

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

Definition at line 204 of file template.h.

204 {
205 DC_ASSUME(self);
206 fprintf(stream, DC_EXPAND_STRING(SELF) "@%p {\n", (void*)self);
207 fmt = dc_debug_fmt_scope_begin(fmt);
208
209 dc_debug_fmt_print(fmt, stream, "block_size: %zu,\n", (size_t)BLOCK_SIZE);
210 dc_debug_fmt_print(fmt, stream, "slab_size: %zu,\n", (size_t)SLAB_SIZE);
211 dc_debug_fmt_print(fmt, stream, "blocks_per_slab: %zu,\n", (size_t)(SLAB_SIZE / BLOCK_SIZE));
212 dc_debug_fmt_print(fmt, stream, "num_slabs: %zu,\n", NS(SLAB_VECTOR, size)(&self->slabs));
213
214 dc_debug_fmt_print(fmt, stream, "alloc: ");
215 NS(ALLOC, debug)(NS(NS(ALLOC, ref), deref)(self->alloc_ref), fmt, stream);
216 fprintf(stream, "\n");
217
218 fmt = dc_debug_fmt_scope_end(fmt);
219 dc_debug_fmt_print(fmt, stream, "}");
220}
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 197 of file template.h.

197 {
198 DC_ASSUME(self);
199
200 NS(SELF, reset)(self);
201 NS(SLAB_VECTOR, delete)(&self->slabs);
202}
static DC_PUBLIC void reset(SELF *self)
Definition template.h:186

◆ new()

DC_PUBLIC SELF new ( ref alloc_ref)
static

Definition at line 61 of file template.h.

61 {
62 return (SELF){
63 .slabs = NS(SLAB_VECTOR, new)(alloc_ref),
64 .free_list_head = NULL,
65 .alloc_ref = alloc_ref,
66 .derive_c_slaballoc = {},
67 };
68}

◆ reallocate()

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

Definition at line 153 of file template.h.

154 {
155 DC_ASSUME(self);
156 DC_ASSUME(ptr);
157 DC_ASSERT(old_size > 0, "Cannot reallocate zero sized");
158 DC_ASSERT(new_size > 0, "Cannot allocate zero sized");
159
160 if (old_size > BLOCK_SIZE && new_size > BLOCK_SIZE) {
161 return NS(ALLOC, reallocate)(self->alloc_ref, ptr, old_size, new_size);
162 }
163
164 void* new_ptr = NS(SELF, allocate_uninit)(self, new_size);
165
166 size_t copy_size = (old_size < new_size) ? old_size : new_size;
167 memcpy(new_ptr, ptr, copy_size);
168
169 if (new_size <= old_size) {
171 new_ptr, new_size);
172 } else {
174 new_ptr, copy_size);
175 }
176
177 NS(SELF, deallocate)(self, ptr, old_size);
178
179 return new_ptr;
180}
static DC_PUBLIC void * reallocate(SELF *self, void *ptr, size_t old_size, size_t new_size)
Definition template.h:137

◆ reset()

DC_PUBLIC void reset ( SELF * self)
static

Definition at line 182 of file template.h.

182 {
183 DC_ASSUME(self);
184
185 size_t num_slabs = NS(SLAB_VECTOR, size)(&self->slabs);
186 for (size_t i = 0; i < num_slabs; i++) {
187 NS(NAME, slab_info) const* info = NS(SLAB_VECTOR, read)(&self->slabs, i);
189 SLAB_SIZE);
190 NS(ALLOC, deallocate)(self->alloc_ref, info->ptr, SLAB_SIZE);
191 }
192
193 NS(SLAB_VECTOR, remove_at)(&self->slabs, 0, num_slabs);
194 self->free_list_head = NULL;
195}
static DC_PUBLIC VALUE const * read(SELF const *self, INDEX index)
Definition template.h:199
static DC_PUBLIC void remove_at(SELF *self, size_t at, size_t count)
Definition template.h:211

◆ slab_info_clone()

slab_info slab_info_clone ( slab_info const * self)
static

Definition at line 38 of file template.h.

38 {
39 return *self;
40}

◆ slab_info_debug()

void slab_info_debug ( slab_info const * ,
dc_debug_fmt ,
FILE *  )
static

Definition at line 42 of file template.h.

43 {}

◆ slab_info_delete()

void slab_info_delete ( slab_info * )
static

Definition at line 41 of file template.h.

41{}