@@ -89,7 +89,6 @@ int elf_data_start;
89
89
90
90
/**
91
91
* arena_block_create() - Creates a new arena block with given capacity.
92
- * The created arena block is guaranteed to be zero-initialized.
93
92
* @capacity: The capacity of the arena block. Must be positive.
94
93
*
95
94
* Return: The pointer of created arena block. NULL if failed to allocate.
@@ -99,14 +98,14 @@ arena_block_t *arena_block_create(int capacity)
99
98
arena_block_t * block = malloc (sizeof (arena_block_t ));
100
99
101
100
if (!block ) {
102
- printf ("Failed to allocate memory for arena block\n" );
101
+ printf ("Failed to allocate memory for arena block structure \n" );
103
102
exit (1 );
104
103
}
105
104
106
- block -> memory = calloc (capacity , sizeof (char ));
105
+ block -> memory = malloc (capacity * sizeof (char ));
107
106
108
107
if (!block -> memory ) {
109
- printf ("Failed to allocate memory for arena block\n" );
108
+ printf ("Failed to allocate memory for arena block buffer \n" );
110
109
free (block );
111
110
exit (1 );
112
111
}
@@ -117,6 +116,16 @@ arena_block_t *arena_block_create(int capacity)
117
116
return block ;
118
117
}
119
118
119
+ /**
120
+ * arena_block_free() - Free a single arena block and its memory buffer.
121
+ * @block: Pointer to the arena_block_t to free. Must not be NULL.
122
+ */
123
+ void arena_block_free (arena_block_t * block )
124
+ {
125
+ free (block -> memory );
126
+ free (block );
127
+ }
128
+
120
129
/**
121
130
* arena_init() - Initializes the given arena with initial capacity.
122
131
* @initial_capacity: The initial capacity of the arena. Must be positive.
@@ -126,6 +135,10 @@ arena_block_t *arena_block_create(int capacity)
126
135
arena_t * arena_init (int initial_capacity )
127
136
{
128
137
arena_t * arena = malloc (sizeof (arena_t ));
138
+ if (!arena ) {
139
+ printf ("Failed to allocate memory for arena structure\n" );
140
+ exit (1 );
141
+ }
129
142
arena -> head = arena_block_create (initial_capacity );
130
143
return arena ;
131
144
}
@@ -141,47 +154,123 @@ arena_t *arena_init(int initial_capacity)
141
154
*/
142
155
void * arena_alloc (arena_t * arena , int size )
143
156
{
144
- char * ptr ;
145
- arena_block_t * block = arena -> head ;
146
-
147
- while (block ) {
148
- if (block -> offset + size <= block -> capacity ) {
149
- ptr = block -> memory + block -> offset ;
150
- block -> offset += size ;
151
- return ptr ;
152
- }
153
- if (!block -> next )
154
- break ;
155
- block = block -> next ;
157
+ if (size <= 0 ) {
158
+ printf ("arena_alloc: size must be positive" );
159
+ exit (1 );
156
160
}
157
161
158
- /* If no space is available, create a new block
159
- * Allocate at least 256 KiB or the requested size
160
- */
161
- int new_capacity = size > DEFAULT_ARENA_SIZE ? size : DEFAULT_ARENA_SIZE ;
162
- arena_block_t * new_block = arena_block_create (new_capacity );
162
+ /* Align to PTR_SIZE bytes */
163
+ size = (size + PTR_SIZE - 1 ) & ~(PTR_SIZE - 1 );
163
164
164
- if (!new_block )
165
- return NULL ;
165
+ if (!arena -> head || arena -> head -> offset + size > arena -> head -> capacity ) {
166
+ /* Need a new block: choose capacity = max(DEFAULT_ARENA_SIZE, size) */
167
+ int new_capacity =
168
+ (size > DEFAULT_ARENA_SIZE ? size : DEFAULT_ARENA_SIZE );
169
+ arena_block_t * new_block = arena_block_create (new_capacity );
170
+ new_block -> next = arena -> head ;
171
+ arena -> head = new_block ;
172
+ }
166
173
167
- block -> next = new_block ;
168
- ptr = new_block -> memory + new_block -> offset ;
169
- new_block -> offset += size ;
174
+ void * ptr = arena -> head -> memory + arena -> head -> offset ;
175
+ arena -> head -> offset += size ;
170
176
return ptr ;
171
177
}
172
178
173
179
/**
174
- * arena_reset() - Resets the given arena by resetting all blocks' offset to 0.
175
- * @arena: The arena to reset. Must not be NULL.
180
+ * arena_calloc() - arena_alloc() plus explicit zero‑initialization.
181
+ * @arena: The arena to allocate memory from. Must not be NULL.
182
+ * @n: Number of elements.
183
+ * @size: Size of each element in bytes.
184
+ *
185
+ * Internally calls arena_alloc(n * size) and then fills the entire region
186
+ * with zero bytes.
187
+ *
188
+ * Return: Pointer to zero-initialized memory.
176
189
*/
177
- void arena_reset (arena_t * arena )
190
+ void * arena_calloc (arena_t * arena , int n , int size )
178
191
{
179
- arena_block_t * block = arena -> head ;
192
+ int total = n * size ;
193
+ void * ptr = arena_alloc (arena , total );
180
194
181
- while (block ) {
182
- block -> offset = 0 ;
183
- block = block -> next ;
195
+ int * w_ptr = ptr ;
196
+ int w_count = total >> 2 ;
197
+ int b_index = w_count << 2 ;
198
+
199
+ for (int i = 0 ; i < w_count ; ++ i )
200
+ w_ptr [i ] = 0 ;
201
+
202
+ char * b_ptr = ptr ;
203
+ while (b_index < total )
204
+ b_ptr [b_index ++ ] = 0 ;
205
+
206
+ return ptr ;
207
+ }
208
+
209
+ /**
210
+ * arena_realloc() - Reallocate a previously allocated region within the arena
211
+ * to a different size.
212
+ *
213
+ * If existing region is the most recent allocation in the current block
214
+ * and there is enough space to expand in place, simply extend the offset.
215
+ * Otherwise, allocate a new region of the requested size and copy the old data.
216
+ *
217
+ * @arena: Pointer to the arena. Must not be NULL.
218
+ * @oldptr: Pointer to the previously allocated memory in the arena.
219
+ * @oldsz: Original size (in bytes) of that allocation.
220
+ * @newsz: New desired size (in bytes).
221
+ *
222
+ * Return: Pointer to the reallocated (resized) memory region.
223
+ */
224
+ void * arena_realloc (arena_t * arena , char * oldptr , int oldsz , int newsz )
225
+ {
226
+ /* No need to grow; existing pointer is sufficient. */
227
+ if (newsz <= oldsz )
228
+ return oldptr ;
229
+
230
+ /* Check if oldptr is at the end of the current block's allocations */
231
+ if (oldptr + oldsz == arena -> head -> memory + arena -> head -> offset &&
232
+ arena -> head -> offset + (newsz - oldsz ) <= arena -> head -> capacity ) {
233
+ /* Grow in place */
234
+ arena -> head -> offset += (newsz - oldsz );
235
+ return oldptr ;
184
236
}
237
+
238
+ /* Otherwise, allocate new region and copy */
239
+ void * newptr = arena_alloc (arena , newsz );
240
+ memcpy (newptr , oldptr , oldsz );
241
+ return newptr ;
242
+ }
243
+
244
+ /**
245
+ * arena_strdup() - Duplicate a NULL-terminated string into the arena.
246
+ *
247
+ * @arena: a Pointer to the arena. Must not be NULL.
248
+ * @str: NULL-terminated input string to duplicate. Must not be NULL.
249
+ *
250
+ * Return: Pointer to the duplicated string stored in the arena.
251
+ */
252
+ char * arena_strdup (arena_t * arena , char * str )
253
+ {
254
+ int n = strlen (str );
255
+ char * dup = arena_alloc (arena , n + 1 );
256
+ memcpy (dup , str , n );
257
+ dup [n ] = '\0' ;
258
+ return dup ;
259
+ }
260
+
261
+ /**
262
+ * arena_memdup() - Duplicate a block of memory into the arena.
263
+ * Allocates size bytes within the arena and copies data from the input pointer.
264
+ *
265
+ * @arena: a Pointer to the arena. Must not be NULL.
266
+ * @data: data Pointer to the source memory. Must not be NULL.
267
+ * @size: size Number of bytes to copy. Must be non-negative.
268
+ *
269
+ * Return: The pointer to the duplicated memory stored in the arena.
270
+ */
271
+ void * arena_memdup (arena_t * arena , void * data , int size )
272
+ {
273
+ return memcpy (arena_alloc (arena , size ), data , size );
185
274
}
186
275
187
276
/**
@@ -194,8 +283,7 @@ void arena_free(arena_t *arena)
194
283
195
284
while (block ) {
196
285
next = block -> next ;
197
- free (block -> memory );
198
- free (block );
286
+ arena_block_free (block );
199
287
block = next ;
200
288
}
201
289
0 commit comments