Csilk 0.2.1
A lightweight, high-performance C HTTP web framework
Loading...
Searching...
No Matches
arena.c File Reference

Arena (bump) allocator for request-scoped memory management. More...

#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include "context_internal.h"
#include "csilk/core/internal.h"
Include dependency graph for arena.c:

Data Structures

struct  csilk_arena_chunk_t
 A single chunk in the arena linked list. More...
 
struct  csilk_arena_t
 Arena allocator for request-scoped memory. More...
 

Macros

#define CSILK_CACHE_LINE_SIZE   64
 Cache line size (typically 64 bytes on modern CPUs). Used for padding structures to prevent false sharing and improve memory alignment.
 

Functions

static void * arena_aligned_alloc (size_t size)
 Helper for cache-line aligned allocations. Ensures the returned pointer starts at a 64-byte boundary. Respects TEST_OOM for unit testing.
 
csilk_arena_tcsilk_arena_new (size_t default_chunk_size)
 Create a new arena allocator.
 
void * csilk_arena_alloc (csilk_arena_t *arena, size_t size)
 Allocate memory from the arena with 8-byte alignment.
 
char * csilk_arena_strdup (csilk_arena_t *arena, const char *s)
 Duplicate a null-terminated string using the arena allocator.
 
char * csilk_arena_strndup (csilk_arena_t *arena, const char *s, size_t n)
 Duplicate n bytes of a string using the arena allocator.
 
void csilk_arena_free (csilk_arena_t *arena)
 Free all arena chunks and the arena structure itself.
 
void csilk_arena_reset (csilk_arena_t *arena)
 Reset arena for reuse without freeing underlying chunks.
 
void csilk_arena_get_stats (csilk_arena_t *arena, size_t *total_size, size_t *total_used)
 Get total allocated size and used bytes in the arena.
 

Detailed Description

Arena (bump) allocator for request-scoped memory management.

The arena allocator is the cornerstone of csilk's zero-freedown model. Instead of freeing individual allocations (which causes fragmentation and overhead), the arena allocates from large contiguous chunks and resets all memory at once when the request completes.

Benefits over malloc/free per allocation:

  • O(1) allocation (pointer bump, no free list search)
  • Zero fragmentation within a chunk
  • Cache-friendly (sequential access pattern)
  • Perfect for request-scoped data (headers, params, storage values)

Chunk structure: Each chunk is a linked-list node with a flexible array member (data[]) containing the usable memory. When the current chunk runs out of space, a new chunk (at least default_chunk_size bytes) is prepended to the list. This means allocation always happens in the head chunk (most recently added), which typically has good cache residency.


Data Structure Documentation

◆ csilk_arena_chunk_t

struct csilk_arena_chunk_t

A single chunk in the arena linked list.

Arena allocator manages memory in chunks. When a chunk is full, a new chunk is allocated. All memory is freed at once when the arena is freed, making it ideal for request-scoped allocations.

Note
This structure is padded to CSILK_CACHE_LINE_SIZE to ensure that the data starts on a cache line boundary and to prevent false sharing between arenas assigned to different threads.
Data Fields
uint8_t _padding[CSILK_CACHE_LINE_SIZE -(3 *sizeof(size_t))]
uint8_t data[]

Flexible array for chunk data.

struct csilk_arena_chunk_s * next

Pointer to next chunk.

size_t size

Total size of this chunk.

size_t used

Bytes used in this chunk.

◆ csilk_arena_t

struct csilk_arena_t

Arena allocator for request-scoped memory.

Arena allocators allocate memory in large chunks and never free individual allocations until the entire arena is freed. This eliminates fragmentation and is ideal for per-request memory management where all allocations are discarded together after processing.

Note
This structure is padded to CSILK_CACHE_LINE_SIZE to prevent false sharing when multiple arena headers are allocated close to each other in memory.
Collaboration diagram for csilk_arena_t:
Data Fields
uint8_t _padding[CSILK_CACHE_LINE_SIZE -(2 *sizeof(size_t))]
size_t default_chunk_size

Default size for new chunks.

csilk_arena_chunk_t * head

Head of chunk linked list.

Macro Definition Documentation

◆ CSILK_CACHE_LINE_SIZE

#define CSILK_CACHE_LINE_SIZE   64

Cache line size (typically 64 bytes on modern CPUs). Used for padding structures to prevent false sharing and improve memory alignment.

Function Documentation

◆ arena_aligned_alloc()

static void * arena_aligned_alloc ( size_t  size)
static

Helper for cache-line aligned allocations. Ensures the returned pointer starts at a 64-byte boundary. Respects TEST_OOM for unit testing.

◆ csilk_arena_alloc()

void * csilk_arena_alloc ( csilk_arena_t arena,
size_t  size 
)

Allocate memory from the arena with 8-byte alignment.

Allocate zero-initialised memory from an arena.

Returns memory from the current chunk if there is room; otherwise allocates a new chunk large enough to satisfy the request. The returned memory is zero-initialized only by virtue of being freshly allocated from the OS.

Parameters
arenaThe arena allocator (must not be NULL).
sizeNumber of bytes to allocate. The actual allocation is rounded up to the nearest multiple of 8 for alignment.
Returns
Pointer to the allocated block, or NULL on allocation failure.
Note
The returned pointer must NOT be freed individually; all arena memory is reclaimed via csilk_arena_free() or csilk_arena_reset().

◆ csilk_arena_free()

void csilk_arena_free ( csilk_arena_t arena)

Free all arena chunks and the arena structure itself.

Free all memory chunks owned by the arena.

Walks the linked list of chunks, frees each one, then frees the arena header. After this call the arena pointer is invalid and must not be used.

Parameters
arenaThe arena to destroy (may be NULL).
Note
Safe to call with NULL — it is a no-op.

◆ csilk_arena_get_stats()

void csilk_arena_get_stats ( csilk_arena_t arena,
size_t *  total_size,
size_t *  total_used 
)

Get total allocated size and used bytes in the arena.

Walks the chunk list and sums the total allocated size and total used bytes.

Parameters
arenaThe arena to query (must not be NULL).
[out]total_sizePointer to receive the total allocated size in bytes.
[out]total_usedPointer to receive the total used bytes in the arena.
Note
Safe to call with NULL pointers for total_size or total_used — they will simply be ignored.

◆ csilk_arena_new()

csilk_arena_t * csilk_arena_new ( size_t  default_chunk_size)

Create a new arena allocator.

Allocates and initializes an arena memory manager. The arena allocates memory in chunks of at least default_chunk_size bytes. Individual allocations within the arena are never freed separately; instead, all memory is reclaimed at once by calling csilk_arena_free() or csilk_arena_reset().

Parameters
default_chunk_sizeMinimum size in bytes for each new chunk. Pass 0 to let the implementation choose a default.
Returns
Pointer to the new arena, or NULL on allocation failure.
Note
The returned arena must be freed with csilk_arena_free().
This function is not thread-safe; each thread should use its own arena.

◆ csilk_arena_reset()

void csilk_arena_reset ( csilk_arena_t arena)

Reset arena for reuse without freeing underlying chunks.

Reset the arena without freeing its chunks.

Sets the used counter to zero on every chunk in the chain, making all arena memory available for new allocations. No system calls (malloc/free) are performed, making this much cheaper than csilk_arena_free() + _new().

Parameters
arenaThe arena to reset (may be NULL).
Note
Useful for request-scoped arenas that are recycled between requests.
Safe to call with NULL — it is a no-op.

◆ csilk_arena_strdup()

char * csilk_arena_strdup ( csilk_arena_t arena,
const char *  s 
)

Duplicate a null-terminated string using the arena allocator.

Duplicate a NUL-terminated string using the arena allocator.

Allocates enough arena memory for a copy of s, including the null terminator, and copies the string contents.

Parameters
arenaThe arena allocator.
sSource string to duplicate.
Returns
Pointer to the new string in arena memory, or NULL if s is NULL or on allocation failure.
Note
The result is subject to the same lifetime rules as other arena allocations — it lives until the arena is freed or reset.

◆ csilk_arena_strndup()

char * csilk_arena_strndup ( csilk_arena_t arena,
const char *  s,
size_t  n 
)

Duplicate n bytes of a string using the arena allocator.

Allocates n + 1 bytes of arena memory, copies n bytes from s, and adds a null terminator.

Parameters
arenaThe arena allocator.
sSource string to duplicate.
nNumber of bytes to copy.
Returns
Pointer to the new string in arena memory, or NULL if s is NULL or on allocation failure.