@@ -89,7 +89,6 @@ int elf_data_start;
8989
9090/**
9191 * arena_block_create() - Creates a new arena block with given capacity.
92- * The created arena block is guaranteed to be zero-initialized.
9392 * @capacity: The capacity of the arena block. Must be positive.
9493 *
9594 * Return: The pointer of created arena block. NULL if failed to allocate.
@@ -99,16 +98,16 @@ arena_block_t *arena_block_create(int capacity)
9998 arena_block_t * block = malloc (sizeof (arena_block_t ));
10099
101100 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 ( );
104103 }
105104
106- block -> memory = calloc (capacity , sizeof (char ));
105+ block -> memory = malloc (capacity * sizeof (char ));
107106
108107 if (!block -> memory ) {
109- printf ("Failed to allocate memory for arena block\n" );
108+ printf ("Failed to allocate memory for arena block buffer \n" );
110109 free (block );
111- exit ( 1 );
110+ abort ( );
112111 }
113112
114113 block -> capacity = capacity ;
@@ -117,6 +116,16 @@ arena_block_t *arena_block_create(int capacity)
117116 return block ;
118117}
119118
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+
120129/**
121130 * arena_init() - Initializes the given arena with initial capacity.
122131 * @initial_capacity: The initial capacity of the arena. Must be positive.
@@ -126,6 +135,10 @@ arena_block_t *arena_block_create(int capacity)
126135arena_t * arena_init (int initial_capacity )
127136{
128137 arena_t * arena = malloc (sizeof (arena_t ));
138+ if (!arena ) {
139+ printf ("Failed to allocate memory for arena structure\n" );
140+ abort ();
141+ }
129142 arena -> head = arena_block_create (initial_capacity );
130143 return arena ;
131144}
@@ -141,47 +154,147 @@ arena_t *arena_init(int initial_capacity)
141154 */
142155void * arena_alloc (arena_t * arena , int size )
143156{
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+ }
146161
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 ;
156172 }
157173
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+ }
163178
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 ;
166210
167- block -> next = new_block ;
168- ptr = new_block -> memory + new_block -> offset ;
169- new_block -> offset += size ;
170211 return ptr ;
171212}
172213
173214/**
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.
176230 */
177- void arena_reset (arena_t * arena )
231+ void * arena_realloc (arena_t * arena , char * oldptr , int oldsz , int newsz )
178232{
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+ }
180245
181- while ( block ) {
182- block -> offset = 0 ;
183- block = block -> next ;
246+ /* return oldptr immediately */
247+ if ( newsz <= oldsz ) {
248+ return oldptr ;
184249 }
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 );
185298}
186299
187300/**
@@ -194,8 +307,7 @@ void arena_free(arena_t *arena)
194307
195308 while (block ) {
196309 next = block -> next ;
197- free (block -> memory );
198- free (block );
310+ arena_block_free (block );
199311 block = next ;
200312 }
201313
0 commit comments