#ifndef INCLUDED__CMMM__ARENA__H #define INCLUDED__CMMM__ARENA__H // NOTE(cmmm): this implementation assumes that allocations are made // at the end, so that we can take advantage of checkpoints. The // downside is that we can't allocate from previous chunks even if // there is space left in them... // NOTE(cmmm): coalescing is nice, but while you're building an // "object", it may be split across multiple chunks #include // #define CMMM__ARENA__NO_STDIO // #define CMMM__ARENA__STRIP_VENDOR #ifndef CMMM__ARENA__FIRST_CHUNK_SIZE #define CMMM__ARENA__FIRST_CHUNK_SIZE (4 << 10) #endif #ifndef CMMM__ARENA__CHUNK_GROWTH_FACTOR #define CMMM__ARENA__CHUNK_GROWTH_FACTOR 2 #endif struct cmmm__arena__chunk { struct cmmm__arena__chunk *next; char *free; char *end; char data[]; }; #define CMMM__ARENA struct cmmm__arena * struct cmmm__arena { struct cmmm__arena__chunk *head; struct cmmm__arena__chunk *tail; }; struct cmmm__arena__checkpoint { struct cmmm__arena__chunk *tail; char *free; }; #ifndef ALIGNOF #if __STDC_VERSION__ >= 202311L #define ALIGNOF alignof #elif __STDC_VERSION__ >= 201112L #define ALIGNOF _Alignof #else #define ALIGNOF(O) offsetof (struct { char _; typeof (O) x; }, x) #endif #endif #define CMMM__ARENA__RESERVE( A, T) cmmm__arena__reserve ((A), sizeof (T), ALIGNOF (T)) #define CMMM__ARENA__RESERVE_ARRAY( A, N, T) cmmm__arena__reserve ((A), (N)*sizeof (T), ALIGNOF (T)) #define CMMM__ARENA__ALLOCATE( A, T) cmmm__arena__allocate ((A), sizeof (T), ALIGNOF (T)) #define CMMM__ARENA__ALLOCATE_ARRAY( A, N, T) cmmm__arena__allocate ((A), (N)*sizeof (T), ALIGNOF (T)) #define CMMM__ARENA__ALLOCATE_FAST( A, T) cmmm__arena__allocate_fast ((A), sizeof (T), ALIGNOF (T)) #define CMMM__ARENA__ALLOCATE_ARRAY_FAST(A, N, T) cmmm__arena__allocate_fast ((A), (N)*sizeof (T), ALIGNOF (T)) #define CMMM__ARENA__ZERO( A, T) cmmm__arena__zero ((A), sizeof (T), ALIGNOF (T)) #define CMMM__ARENA__ZERO_ARRAY( A, N, T) cmmm__arena__zero ((A), (N)*sizeof (T), ALIGNOF (T)) void *cmmm__arena__reserve (struct cmmm__arena *, size_t size, size_t alignment); void *cmmm__arena__allocate (struct cmmm__arena *, size_t size, size_t alignment); void *cmmm__arena__allocate_fast (struct cmmm__arena *, size_t size, size_t alignment); void *cmmm__arena__zero (struct cmmm__arena *, size_t size, size_t alignment); size_t cmmm__arena__room (const struct cmmm__arena *, size_t alignment); void *cmmm__arena__next_free (const struct cmmm__arena *, size_t alignment); #define CMMM__ARENA__COPY( A, F, T) cmmm__arena__copy ((A), (F), sizeof (T), ALIGNOF (T)) #define CMMM__ARENA__COPY_ARRAY(A, F, N, T) cmmm__arena__copy ((A), (F), (N)*sizeof (T), ALIGNOF (T)) void *cmmm__arena__copy (struct cmmm__arena *, const void *, size_t size, size_t alignment); char *cmmm__arena__copy_cstr (struct cmmm__arena *, const char *); void cmmm__arena__reset (struct cmmm__arena *); struct cmmm__arena__checkpoint cmmm__arena__checkpoint (struct cmmm__arena *); size_t cmmm__arena__checkpoint__size_from (struct cmmm__arena__checkpoint); void cmmm__arena__rollback_to (struct cmmm__arena *, struct cmmm__arena__checkpoint); void *cmmm__arena__coalesce_from (struct cmmm__arena *, struct cmmm__arena__checkpoint); void *cmmm__arena__coalesce_from_fast (struct cmmm__arena *, struct cmmm__arena__checkpoint, size_t size); void cmmm__arena__trim (struct cmmm__arena *); void cmmm__arena__free (struct cmmm__arena *); #ifndef CMMM__ARENA__NO_STDIO #include char *cmmm__arena__printf (struct cmmm__arena *, const char *format, ...); char *cmmm__arena__vprintf (struct cmmm__arena *, const char *format, va_list ap); #endif #ifdef CMMM__ARENA__STRIP_VENDOR #define ARENA__NO_STDIO CMMM__ARENA__NO_STDIO #define ARENA__STRIP_VENDOR CMMM__ARENA__STRIP_VENDOR #define ARENA__FIRST_CHUNK_SIZE CMMM__ARENA__FIRST_CHUNK_SIZE #define ARENA__CHUNK_GROWTH_FACTOR CMMM__ARENA__CHUNK_GROWTH_FACTOR #define arena__chunk cmmm__arena__chunk #define ARENA CMMM__ARENA #define arena__checkpoint cmmm__arena__checkpoint #define ARENA__RESERVE CMMM__ARENA__RESERVE #define ARENA__RESERVE_ARRAY CMMM__ARENA__RESERVE_ARRAY #define ARENA__ALLOCATE CMMM__ARENA__ALLOCATE #define ARENA__ALLOCATE_ARRAY CMMM__ARENA__ALLOCATE_ARRAY #define ARENA__ALLOCATE_FAST CMMM__ARENA__ALLOCATE_FAST #define ARENA__ALLOCATE_ARRAY_FAST CMMM__ARENA__ALLOCATE_ARRAY_FAST #define ARENA__ZERO CMMM__ARENA__ZERO #define ARENA__ZERO_ARRAY CMMM__ARENA__ZERO_ARRAY #define arena__reserve cmmm__arena__reserve #define arena__allocate cmmm__arena__allocate #define arena__allocate_fast cmmm__arena__allocate_fast #define arena__zero cmmm__arena__zero #define arena__room cmmm__arena__room #define arena__next_free cmmm__arena__next_free #define ARENA__COPY CMMM__ARENA__COPY #define ARENA__COPY_ARRAY CMMM__ARENA__COPY_ARRAY #define arena__copy cmmm__arena__copy #define arena__copy_cstr cmmm__arena__copy_cstr #define arena__reset cmmm__arena__reset #define arena__checkpoint cmmm__arena__checkpoint #define arena__rollback_to cmmm__arena__rollback_to #define arena__size_from cmmm__arena__size_from #define arena__coalesce_from cmmm__arena__coalesce_from #define arena__coalesce_from_fast cmmm__arena__coalesce_from_fast #define arena__trim cmmm__arena__trim #define arena__free cmmm__arena__free #ifndef CMMM__ARENA__NO_STDIO #define arena__printf cmmm__arena__printf #define arena__vprintf cmmm__arena__vprintf #endif #endif #endif // INCLUDED__CMMM__ARENA__H