@@ -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,16 +98,16 @@ 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" );
103
- exit ( 1 );
101
+ printf ("Failed to allocate memory for arena block structure \n" );
102
+ abort ( );
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
- exit ( 1 );
110
+ abort ( );
112
111
}
113
112
114
113
block -> capacity = capacity ;
@@ -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
+ abort ();
141
+ }
129
142
arena -> head = arena_block_create (initial_capacity );
130
143
return arena ;
131
144
}
@@ -141,47 +154,147 @@ 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 ;
157
+ if (size <= 0 ) {
158
+ printf ("arena_alloc: size must be positive\n" );
159
+ abort ();
160
+ }
146
161
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 ;
162
+ /* Align to PTR_SIZE bytes */
163
+ size = (size + PTR_SIZE - 1 ) & ~(PTR_SIZE - 1 );
164
+
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 ;
156
172
}
157
173
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 );
174
+ void * ptr = arena -> head -> memory + arena -> head -> offset ;
175
+ arena -> head -> offset += size ;
176
+ return ptr ;
177
+ }
163
178
164
- if (!new_block )
165
- return NULL ;
179
+ /**
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.
189
+ */
190
+ void * arena_calloc (arena_t * arena , int n , int size )
191
+ {
192
+ if (n * size == 0 ) {
193
+ printf ("arena_calloc: cannot allocate 0 bytes\n" );
194
+ abort ();
195
+ }
196
+
197
+ int total = n * size ;
198
+ void * ptr = arena_alloc (arena , total );
199
+
200
+ int * w_ptr = ptr ;
201
+ int w_count = total >> 2 ;
202
+ int b_index = w_count << 2 ;
203
+
204
+ for (int i = 0 ; i < w_count ; ++ i )
205
+ w_ptr [i ] = 0 ;
206
+
207
+ char * b_ptr = ptr ;
208
+ while (b_index < total )
209
+ b_ptr [b_index ++ ] = 0 ;
166
210
167
- block -> next = new_block ;
168
- ptr = new_block -> memory + new_block -> offset ;
169
- new_block -> offset += size ;
170
211
return ptr ;
171
212
}
172
213
173
214
/**
174
- * arena_reset() - Resets the given arena by resetting all blocks' offset to 0.
175
- * @arena: The arena to reset. Must not be NULL.
215
+ * arena_realloc() - Reallocate a previously allocated region within the arena
216
+ * to a different size.
217
+ *
218
+ * Behaviors:
219
+ * 1. If oldptr == NULL and oldsz == 0, act like malloc.
220
+ * 2. If newsz <= oldsz, return oldptr immediately.
221
+ * 3. Grow in place if oldptr is the last allocation in the current block.
222
+ * 4. Otherwise, allocate a new region and copy old data.
223
+ *
224
+ * @arena: Pointer to the arena. Must not be NULL.
225
+ * @oldptr: Pointer to the previously allocated memory in the arena.
226
+ * @oldsz: Original size (in bytes) of that allocation.
227
+ * @newsz: New desired size (in bytes).
228
+ *
229
+ * Return: Pointer to the reallocated (resized) memory region.
176
230
*/
177
- void arena_reset (arena_t * arena )
231
+ void * arena_realloc (arena_t * arena , char * oldptr , int oldsz , int newsz )
178
232
{
179
- arena_block_t * block = arena -> head ;
233
+ /* act like malloc */
234
+ if (oldptr == NULL ) {
235
+ if (oldsz != 0 ) {
236
+ printf ("arena_realloc: oldptr == NULL requires oldsz == 0\n" );
237
+ abort ();
238
+ }
239
+ return arena_alloc (arena , newsz );
240
+ }
241
+ if (oldsz == 0 ) {
242
+ printf ("arena_realloc: oldptr != NULL requires oldsz > 0\n" );
243
+ abort ();
244
+ }
180
245
181
- while ( block ) {
182
- block -> offset = 0 ;
183
- block = block -> next ;
246
+ /* return oldptr immediately */
247
+ if ( newsz <= oldsz ) {
248
+ return oldptr ;
184
249
}
250
+
251
+ /* From here on, oldptr != NULL and newsz > oldsz and oldsz != 0 */
252
+ int delta = newsz - oldsz ;
253
+ arena_block_t * blk = arena -> head ;
254
+ char * block_end = blk -> memory + blk -> offset ;
255
+
256
+ /* grow in place if oldptr is the last allocation in the current block */
257
+ if (oldptr + oldsz == block_end && blk -> offset + delta <= blk -> capacity ) {
258
+ blk -> offset += delta ;
259
+ return oldptr ;
260
+ }
261
+
262
+ /* allocate a new region and copy old data */
263
+ void * newptr = arena_alloc (arena , newsz );
264
+ memcpy (newptr , oldptr , oldsz );
265
+ return newptr ;
266
+ }
267
+
268
+ /**
269
+ * arena_strdup() - Duplicate a NULL-terminated string into the arena.
270
+ *
271
+ * @arena: a Pointer to the arena. Must not be NULL.
272
+ * @str: NULL-terminated input string to duplicate. Must not be NULL.
273
+ *
274
+ * Return: Pointer to the duplicated string stored in the arena.
275
+ */
276
+ char * arena_strdup (arena_t * arena , char * str )
277
+ {
278
+ int n = strlen (str );
279
+ char * dup = arena_alloc (arena , n + 1 );
280
+ memcpy (dup , str , n );
281
+ dup [n ] = '\0' ;
282
+ return dup ;
283
+ }
284
+
285
+ /**
286
+ * arena_memdup() - Duplicate a block of memory into the arena.
287
+ * Allocates size bytes within the arena and copies data from the input pointer.
288
+ *
289
+ * @arena: a Pointer to the arena. Must not be NULL.
290
+ * @data: data Pointer to the source memory. Must not be NULL.
291
+ * @size: size Number of bytes to copy. Must be non-negative.
292
+ *
293
+ * Return: The pointer to the duplicated memory stored in the arena.
294
+ */
295
+ void * arena_memdup (arena_t * arena , void * data , int size )
296
+ {
297
+ return memcpy (arena_alloc (arena , size ), data , size );
185
298
}
186
299
187
300
/**
@@ -194,8 +307,7 @@ void arena_free(arena_t *arena)
194
307
195
308
while (block ) {
196
309
next = block -> next ;
197
- free (block -> memory );
198
- free (block );
310
+ arena_block_free (block );
199
311
block = next ;
200
312
}
201
313
0 commit comments