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