Derive-C
Loading...
Searching...
No Matches
template.h File Reference
#include <stdint.h>
#include <string.h>
#include <derive-c/core.h>
#include <derive-c/panic.h>
#include <derive-c/self.h>
Include dependency graph for template.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  SELF

Macros

#define CAPACITY   1024
 A very simple bump allocator making use of a provided fixed size buffer (e.g. statically allocated).
#define USED   uint8_t

Functions

static SELF new ()
static void clear (SELF *self)
 Clear the allocator, note that all data should be freed before this occurs.
static USED get_used (SELF const *self)
static void * malloc (SELF *self, size_t size)
static void free (SELF *DEBUG_UNUSED(self), void *DEBUG_UNUSED(ptr))
static void * realloc (SELF *self, void *ptr, size_t new_size)
static void * calloc (SELF *self, size_t count, size_t size)

Variables

static size_t metadata_size = sizeof(USED)

Macro Definition Documentation

◆ CAPACITY

#define CAPACITY   1024

A very simple bump allocator making use of a provided fixed size buffer (e.g. statically allocated).

  • Useful when an upper bound for allocation size is known at compile time
  • Can be used when no global allocator is available (e.g. embedded systems, kernel dev)

Definition at line 16 of file template.h.

◆ USED

#define USED   uint8_t

Definition at line 24 of file template.h.

Function Documentation

◆ calloc()

void * calloc ( SELF * self,
size_t count,
size_t size )
static

Definition at line 134 of file template.h.

134 {
135 // JUSTIFY:
136 // - We already zeroed the buffer in `new()`
137 return NAME(SELF, malloc)(self, count * size);
138}
static void * malloc(SELF *self, size_t size)
Definition template.h:29
#define SELF
Definition template.h:70
#define NAME(pre, post)
Definition core.h:5
static INDEX_TYPE size(SELF const *self)
Definition template.h:207
Here is the call graph for this function:

◆ clear()

void clear ( SELF * self)
static

Clear the allocator, note that all data should be freed before this occurs.

Definition at line 51 of file template.h.

51 {
52 DEBUG_ASSERT(self);
53
54#ifndef NDEBUG
55 // JUSTIFY: Allocations & sizes zeroed on free in debug, we check all data has been freed.
56 for (size_t i = 0; i < self->used; i++) {
57 if (self->buffer[i] != 0) {
58 PANIC("Data not freed before clearing the static bump allocator");
59 }
60 }
61#endif
62 memset(self->buffer, 0, self->used);
63 self->used = 0;
64}
#define DEBUG_ASSERT(expr)
Definition panic.h:23
#define PANIC(...)
Definition panic.h:8
size_t used
Definition template.h:34
char buffer[CAPACITY]
Definition template.h:35
Here is the call graph for this function:
Here is the caller graph for this function:

◆ free()

void free ( SELF * DEBUG_UNUSEDself,
void * DEBUG_UNUSEDptr )
static

Definition at line 83 of file template.h.

83 {
84 DEBUG_ASSERT(self);
85 DEBUG_ASSERT(ptr);
86
87#ifndef NDEBUG
88 // JUSTIFY: Zero memory in debug.
89 // - Expensive for release, but helpful when debugging
90 // NOTE: This means that users should free, before they clear and reuse the buffer.
91 USED* used_ptr = (USED*)((char*)ptr - sizeof(USED));
92 memset(ptr, 0, *used_ptr);
93 *used_ptr = 0;
94#endif
95}
#define USED
Definition template.h:24
Here is the call graph for this function:

◆ get_used()

USED get_used ( SELF const * self)
static

Definition at line 66 of file template.h.

66 {
67 DEBUG_ASSERT(self);
68 return self->used;
69}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ malloc()

void * malloc ( SELF * self,
size_t size )
static

Definition at line 71 of file template.h.

71 {
72 DEBUG_ASSERT(self);
73 if (self->used + (size + sizeof(USED)) > CAPACITY) {
74 return NULL;
75 }
76 char* ptr = &self->buffer[self->used];
77 USED* used_ptr = (USED*)ptr;
78 *used_ptr = size;
79 self->used += size + sizeof(USED);
80 return ptr + sizeof(USED);
81}
#define CAPACITY
A very simple bump allocator making use of a provided fixed size buffer (e.g. statically allocated).
Definition template.h:16
Here is the call graph for this function:

◆ new()

SELF new ( )
static

Definition at line 41 of file template.h.

41 {
42 SELF self = {.used = 0, .derive_c_staticbumpalloc = {}};
43 // JUSTIFY: Zeroed buffer
44 // - For easier debugging & view in gdb.
45 // - Additionally allows for calloc to be malloc.
46 memset(self.buffer, 0, CAPACITY);
47 return self;
48}

◆ realloc()

void * realloc ( SELF * self,
void * ptr,
size_t new_size )
static

Definition at line 97 of file template.h.

97 {
98 DEBUG_ASSERT(self);
99 DEBUG_ASSERT(ptr);
100
101 char* byte_ptr = (char*)ptr;
102 USED* old_size = (USED*)(byte_ptr - sizeof(USED));
103 const bool was_last_alloc = (byte_ptr + *old_size == self->buffer + self->used);
104
105 if (was_last_alloc) {
106 if (self->used + (new_size - *old_size) > CAPACITY) {
107 return NULL;
108 }
109
110 self->used += (new_size - *old_size);
111 *old_size = new_size;
112 return ptr;
113 }
114
115 if (new_size < *old_size) {
116 // JUSTIFY: Shrinking an allocation
117 // - Can become a noop - as we cannot re-extend the allocation
118 // afterwards - no metadata for unused capacity not at end of buffer.
119 *old_size = new_size;
120 return ptr;
121 }
122
123 void* new_buff = NAME(SELF, malloc)(self, new_size);
124 if (!new_buff) {
125 return NULL;
126 }
127
128 memcpy(new_buff, ptr, *old_size);
129
130 NAME(SELF, free)(self, ptr);
131 return new_buff;
132}
static void free(SELF *self, void *ptr)
Definition template.h:62
Here is the call graph for this function:

Variable Documentation

◆ metadata_size

size_t metadata_size = sizeof(USED)
static

Definition at line 39 of file template.h.