Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| a21311de7b | |||
| 0fbe5e8255 |
+5
-5
@@ -38,7 +38,7 @@ void arena_init(Arena *arena, const ArenaOptions *opts)
|
||||
MemoryBlock *block = memoryblock_allocate(aligned_size, aligned_commit_size, page_size);
|
||||
|
||||
arena->flags = opts->flags;
|
||||
arena->checkpoint_level = 0;
|
||||
arena->temp_level = 0;
|
||||
arena->current = block;
|
||||
arena->block_size = aligned_size;
|
||||
arena->commit_size = aligned_commit_size;
|
||||
@@ -48,7 +48,7 @@ void arena_init(Arena *arena, const ArenaOptions *opts)
|
||||
void arena_free(Arena *arena)
|
||||
{
|
||||
MemoryBlock *block = arena->current;
|
||||
Assert(arena->checkpoint_level == 0);
|
||||
Assert(arena->temp_level == 0);
|
||||
while (block != NULL) {
|
||||
MemoryBlock *prev = block->prev;
|
||||
memory_free(block->base, block->size);
|
||||
@@ -137,7 +137,7 @@ ATemp arena_temp_begin(Arena *arena)
|
||||
ATemp checkpoint = {};
|
||||
checkpoint.arena = arena;
|
||||
checkpoint.total_offset = arena_used(arena);
|
||||
arena->checkpoint_level++;
|
||||
arena->temp_level++;
|
||||
|
||||
return checkpoint;
|
||||
}
|
||||
@@ -145,9 +145,9 @@ ATemp arena_temp_begin(Arena *arena)
|
||||
void arena_temp_end(ATemp *checkpoint)
|
||||
{
|
||||
Arena *arena = checkpoint->arena;
|
||||
Assert(arena->checkpoint_level > 0);
|
||||
Assert(arena->temp_level > 0);
|
||||
arena_reset_to(arena, checkpoint->total_offset);
|
||||
arena->checkpoint_level--;
|
||||
arena->temp_level--;
|
||||
}
|
||||
|
||||
void arena_reset(Arena *arena)
|
||||
|
||||
+1
-1
@@ -27,7 +27,7 @@ struct Arena {
|
||||
U32 commit_size; // requested commit size
|
||||
U32 page_size; // cached page size
|
||||
ArenaFlags flags;
|
||||
S32 checkpoint_level;
|
||||
S32 temp_level;
|
||||
};
|
||||
|
||||
typedef struct ATemp ATemp;
|
||||
|
||||
+37
-6
@@ -104,12 +104,43 @@ typedef unsigned __int128 U128;
|
||||
(const type *)((const void *)(const unsigned char *)__mptr - offsetof(const type, member)); \
|
||||
})
|
||||
|
||||
// align needs to be pow2
|
||||
#define AlignUp(val, align) (((val) + (align) - 1UL) & ~((align) - 1UL))
|
||||
#define AlignDown(val, align) ((val) & ~((align) - 1UL))
|
||||
#define IsPow2(x) ((x) && !((x) & ((x) - 1UL)))
|
||||
#define IsPow2OrZero(x) (!((x) & ((x) - 1UL)))
|
||||
#define IsAlignedTo(x, align) (IsPow2(align) && !((x) & ((align) - 1UL)))
|
||||
// `align` must be a power of two.
|
||||
//
|
||||
// These keep the result in the *same integer type as the first argument*
|
||||
#define AlignUp(val, align) \
|
||||
({ \
|
||||
__typeof__(val) AlignUp_v_ = (val); \
|
||||
__typeof__(val) AlignUp_a_ = (__typeof__(val))(align); \
|
||||
(__typeof__(val))((AlignUp_v_ + (AlignUp_a_ - 1)) & \
|
||||
~(__typeof__(val))(AlignUp_a_ - 1)); \
|
||||
})
|
||||
|
||||
#define AlignDown(val, align) \
|
||||
({ \
|
||||
__typeof__(val) AlignDown_v_ = (val); \
|
||||
__typeof__(val) AlignDown_a_ = (__typeof__(val))(align); \
|
||||
(__typeof__(val))(AlignDown_v_ & ~(__typeof__(val))(AlignDown_a_ - 1));\
|
||||
})
|
||||
|
||||
#define IsPow2(x) \
|
||||
({ \
|
||||
__typeof__(x) IsPow2_x_ = (x); \
|
||||
IsPow2_x_ && !(IsPow2_x_ & (__typeof__(x))(IsPow2_x_ - 1)); \
|
||||
})
|
||||
|
||||
#define IsPow2OrZero(x) \
|
||||
({ \
|
||||
__typeof__(x) IsPow2OrZero_x_ = (x); \
|
||||
!(IsPow2OrZero_x_ & (__typeof__(x))(IsPow2OrZero_x_ - 1)); \
|
||||
})
|
||||
|
||||
#define IsAlignedTo(x, align) \
|
||||
({ \
|
||||
__typeof__(x) IsAlignedTo_x_ = (x); \
|
||||
__typeof__(x) IsAlignedTo_a_ = (__typeof__(x))(align); \
|
||||
IsPow2(IsAlignedTo_a_) && \
|
||||
!(IsAlignedTo_x_ & (__typeof__(x))(IsAlignedTo_a_ - 1)); \
|
||||
})
|
||||
|
||||
#define GetBit(val, idx) (((val) >> (idx)) & 1)
|
||||
// Get n_bits starting at idx going left
|
||||
|
||||
+11
-9
@@ -6,9 +6,9 @@
|
||||
typedef struct MArena MArena;
|
||||
struct MArena {
|
||||
U8 *base; // start of buffer
|
||||
U32 first_free; // next alloc point
|
||||
U32 first_free;
|
||||
U32 size;
|
||||
S32 checkpoint_level; // level of marena_temp_begin nesting
|
||||
S32 temp_level; // level of marena_temp_begin nesting
|
||||
};
|
||||
|
||||
typedef struct MTemp MTemp;
|
||||
@@ -18,7 +18,7 @@ struct MTemp {
|
||||
};
|
||||
|
||||
#define MARENA_STATIC_INITIALIZER(data) MARENA_INITIALIZER((data), sizeof(data))
|
||||
#define MARENA_INITIALIZER(data, size_) {.base = (data), .first_free = 0, .size = (U32)size_, .checkpoint_level = 0}
|
||||
#define MARENA_INITIALIZER(data, size_) {.base = (data), .first_free = 0, .size = (U32)size_, .temp_level = 0}
|
||||
#define MARENA_DEFINE(var_name, size, alignment_) \
|
||||
struct { \
|
||||
_Alignas(alignment_) U8 memory[size];\
|
||||
@@ -41,7 +41,7 @@ static INLINE MTemp marena_temp_begin(MArena *arena)
|
||||
|
||||
checkpoint.arena = arena;
|
||||
checkpoint.offset = arena->first_free;
|
||||
arena->checkpoint_level++;
|
||||
arena->temp_level++;
|
||||
|
||||
return checkpoint;
|
||||
}
|
||||
@@ -49,13 +49,15 @@ static INLINE MTemp marena_temp_begin(MArena *arena)
|
||||
static INLINE void marena_temp_end(MTemp *state)
|
||||
{
|
||||
MArena *arena = state->arena;
|
||||
Assert(arena->checkpoint_level > 0);
|
||||
Assert(arena->temp_level > 0);
|
||||
arena->first_free = state->offset;
|
||||
arena->checkpoint_level--;
|
||||
arena->temp_level--;
|
||||
}
|
||||
|
||||
#define marena_push_type(allocator, type_) marenaalloc_aligned((allocator), sizeof(type_), _Alignof(type_))
|
||||
#define marena_push_array(allocator, type_, nr_elements_) marenaalloc_aligned((allocator), (nr_elements_) * (U32)sizeof(type_), _Alignof(type_))
|
||||
#define marena_push_type(allocator, type_)\
|
||||
marenaalloc_aligned((allocator), sizeof(type_), _Alignof(type_))
|
||||
#define marena_push_array(allocator, type_, nr_elements_)\
|
||||
marenaalloc_aligned((allocator), (nr_elements_) * (U32)sizeof(type_), _Alignof(type_))
|
||||
|
||||
|
||||
static INLINE void *marena_push(MArena *arena, U32 size)
|
||||
@@ -74,7 +76,7 @@ static INLINE void *maren_push_aligned(MArena *arena, U32 size, U32 align)
|
||||
Assert(IsPow2(align));
|
||||
|
||||
U32 aligned = AlignUp(arena->first_free, align);
|
||||
if (aligned < arena->first_free) { // align wrapped
|
||||
if (aligned < arena->first_free) { // aligned wrapped around
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user