Cthulhu  0.2.10
Cthulhu compiler collection
arena.c
Go to the documentation of this file.
1 // SPDX-License-Identifier: LGPL-3.0-only
2 
3 #include "arena/arena.h"
4 
5 #include "base/panic.h"
6 #include "base/util.h"
7 
9 
11 char *arena_opt_strdup(const char *str, arena_t *arena)
12 {
13  CTASSERT(str != NULL);
14 
15  size_t len = ctu_strlen(str);
16  return arena_opt_strndup(str, len, arena);
17 }
18 
20 char *arena_opt_strndup(const char *str, size_t len, arena_t *arena)
21 {
22  CTASSERT(str != NULL);
23 
24  char *out = ARENA_OPT_MALLOC(len + 1, "strndup", NULL, arena);
25  if (out == NULL) return NULL;
26 
27  ctu_memcpy(out, str, len);
28  out[len] = '\0';
29 
30  return out;
31 }
32 
34 void *arena_opt_memdup(const void *ptr, size_t size, arena_t *arena)
35 {
36  CTASSERT(ptr != NULL);
37 
38  void *out = ARENA_OPT_MALLOC(size, "memdup", NULL, arena);
39  if (out == NULL) return NULL;
40 
41  ctu_memcpy(out, ptr, size);
42 
43  return out;
44 }
45 
47 void *arena_opt_malloc(size_t size, arena_t *arena)
48 {
49  CTASSERT(arena != NULL);
50  CTASSERTF(arena->fn_malloc != NULL, "malloc is not implemented for %s", arena->name);
51 
52  return arena->fn_malloc(size, arena_data(arena));
53 }
54 
56 void *arena_opt_malloc_info(size_t size, const char *name, const void *parent, arena_t *arena)
57 {
58  void *ptr = arena_opt_malloc(size, arena);
59  if (ptr == NULL) return NULL;
60 
61  if (name != NULL)
62  {
63  arena_rename(ptr, name, arena);
64  }
65 
66  if (parent != NULL)
67  {
68  arena_reparent(ptr, parent, arena);
69  }
70 
71  return ptr;
72 }
73 
75 void *arena_opt_realloc(void *ptr, size_t new_size, size_t old_size, arena_t *arena)
76 {
77  CTASSERT(arena != NULL);
78  CTASSERTF(arena->fn_realloc != NULL, "realloc is not implemented for %s", arena->name);
79 
80  return arena->fn_realloc(ptr, new_size, old_size, arena_data(arena));
81 }
82 
84 void arena_opt_free(void *ptr, size_t size, arena_t *arena)
85 {
86  CTASSERT(arena != NULL);
87  CTASSERTF(arena->fn_free != NULL, "free is not implemented for %s", arena->name);
88 
89  arena->fn_free(ptr, size, arena_data(arena));
90 }
91 
93 
95 char *arena_strdup(const char *str, arena_t *arena)
96 {
97  char *out = arena_opt_strdup(str, arena);
98  CTASSERT(out != NULL);
99  return out;
100 }
101 
102 STA_DECL
103 char *arena_strndup(const char *str, size_t len, arena_t *arena)
104 {
105  char *out = arena_opt_strndup(str, len, arena);
106  CTASSERT(out != NULL);
107  return out;
108 }
109 
110 STA_DECL
111 void *arena_memdup(const void *ptr, size_t size, arena_t *arena)
112 {
113  void *out = arena_opt_memdup(ptr, size, arena);
114  CTASSERT(out != NULL);
115  return out;
116 }
117 
118 STA_DECL
119 void *arena_malloc(size_t size, arena_t *arena)
120 {
121  CTASSERT(size > 0);
122 
123  void *ptr = arena_opt_malloc(size, arena);
124  CTASSERT(ptr != NULL);
125  return ptr;
126 }
127 
128 STA_DECL
129 void *arena_malloc_info(size_t size, const char *name, const void *parent, arena_t *arena)
130 {
131  CTASSERT(size > 0);
132 
133  void *ptr = arena_opt_malloc_info(size, name, parent, arena);
134  CTASSERTF(ptr != NULL, "failed to allocate %zu bytes in %s", size, arena->name);
135  return ptr;
136 }
137 
138 STA_DECL
139 void *arena_realloc(void *ptr, size_t new_size, size_t old_size, arena_t *arena)
140 {
141  CTASSERT(ptr != NULL);
142  CTASSERT(new_size > 0);
143  CTASSERT(old_size > 0);
144 
145  void *out = arena_opt_realloc(ptr, new_size, old_size, arena);
146  CTASSERT(out != NULL);
147  return out;
148 }
149 
150 STA_DECL
151 void arena_free(void *ptr, size_t size, arena_t *arena)
152 {
153  CTASSERT(ptr != NULL);
154  CTASSERT(size > 0);
155 
156  arena_opt_free(ptr, size, arena);
157 }
158 
159 STA_DECL
160 void arena_rename(const void *ptr, const char *name, arena_t *arena)
161 {
162  CTASSERT(arena != NULL);
163  CTASSERT(ptr != NULL);
164  CTASSERT(name != NULL);
165 
166  if (arena->fn_rename != NULL)
167  {
168  arena->fn_rename(ptr, name, arena_data(arena));
169  }
170 }
171 
172 STA_DECL
173 void arena_reparent(const void *ptr, const void *parent, arena_t *arena)
174 {
175  CTASSERT(arena != NULL);
176  CTASSERT(ptr != NULL);
177  CTASSERT(parent != NULL);
178 
179  if (arena->fn_reparent != NULL)
180  {
181  arena->fn_reparent(ptr, parent, arena_data(arena));
182  }
183 }
184 
185 STA_DECL
186 void *arena_data(arena_t *arena)
187 {
188  CTASSERT(arena != NULL);
189 
190  return arena->user;
191 }
STA_DECL void arena_opt_free(void *ptr, size_t size, arena_t *arena)
Definition: arena.c:84
STA_DECL void * arena_memdup(const void *ptr, size_t size, arena_t *arena)
Definition: arena.c:111
STA_DECL void arena_free(void *ptr, size_t size, arena_t *arena)
Definition: arena.c:151
STA_DECL char * arena_opt_strndup(const char *str, size_t len, arena_t *arena)
Definition: arena.c:20
STA_DECL void * arena_realloc(void *ptr, size_t new_size, size_t old_size, arena_t *arena)
Definition: arena.c:139
STA_DECL char * arena_strndup(const char *str, size_t len, arena_t *arena)
Definition: arena.c:103
STA_DECL void * arena_opt_memdup(const void *ptr, size_t size, arena_t *arena)
Definition: arena.c:34
STA_DECL void * arena_opt_realloc(void *ptr, size_t new_size, size_t old_size, arena_t *arena)
Definition: arena.c:75
CT_NODISCARD size_t size
Definition: scan.h:128
#define STA_DECL
sal2 annotation on function implementations to copy annotations from the declaration
CT_NOALIAS CT_BASE_API void * ctu_memcpy(STA_WRITES(size) void *CT_RESTRICT dst, STA_READS(size) const void *CT_RESTRICT src, size_t size)
copy memory from one location to another equivalent to memcpy but with safety checks
CT_NODISCARD CT_PUREFN CT_BASE_API size_t ctu_strlen(const char *str)
get the length of a string not including the null terminator equivalent to strlen but with safety che...
Definition: util.c:87
STA_DECL void * arena_opt_malloc_info(size_t size, const char *name, const void *parent, arena_t *arena)
allocate memory from a custom allocator
Definition: arena.c:56
STA_DECL void * arena_opt_malloc(size_t size, arena_t *arena)
allocate memory from a custom allocator
Definition: arena.c:47
STA_DECL char * arena_opt_strdup(const char *str, arena_t *arena)
these return NULL on failure
Definition: arena.c:11
STA_DECL void * arena_malloc_info(size_t size, const char *name, const void *parent, arena_t *arena)
allocate memory from a custom allocator
Definition: arena.c:129
STA_DECL void * arena_data(arena_t *arena)
get the user data pointer from an arena
Definition: arena.c:186
#define ARENA_OPT_MALLOC(size, name, parent, arena)
Definition: arena.h:393
STA_DECL void * arena_malloc(size_t size, arena_t *arena)
allocate memory from a custom allocator
Definition: arena.c:119
STA_DECL void arena_reparent(const void *ptr, const void *parent, arena_t *arena)
reparent a pointer in a custom allocator
Definition: arena.c:173
STA_DECL char * arena_strdup(const char *str, arena_t *arena)
strong oom handling
Definition: arena.c:95
STA_DECL void arena_rename(const void *ptr, const char *name, arena_t *arena)
rename a pointer in a custom allocator
Definition: arena.c:160
#define CTASSERT(expr)
assert a condition, prints the condition as a message
Definition: panic.h:130
#define CTASSERTF(expr,...)
assert a condition with a message and optional format arguments
Definition: panic.h:116
an allocator object
Definition: arena.h:86
mem_resize_t fn_realloc
the realloc function
Definition: arena.h:94
const char * name
the name of the allocator
Definition: arena.h:88
mem_release_t fn_free
the free function
Definition: arena.h:97
void * user
user data pointer
Definition: arena.h:108
mem_reparent_t fn_reparent
the reparent function
Definition: arena.h:105
mem_rename_t fn_rename
the rename function
Definition: arena.h:101
mem_alloc_t fn_malloc
the malloc function
Definition: arena.h:91