mirror of
https://github.com/Ed94/metadesk.git
synced 2026-06-12 23:51:37 -07:00
adding prefixes to source
They'll be removed on demand in libgen repo
This commit is contained in:
+79
-79
@@ -7,82 +7,82 @@
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Arena Functions
|
||||
//~ rjf: MD_Arena Functions
|
||||
|
||||
//- rjf: arena creation/destruction
|
||||
|
||||
Arena*
|
||||
arena__alloc(ArenaParams* optional_params)
|
||||
MD_Arena*
|
||||
md_arena__alloc(MD_ArenaParams* optional_params)
|
||||
{
|
||||
ArenaParams params = optional_params ? *optional_params : (ArenaParams){0};
|
||||
MD_ArenaParams params = optional_params ? *optional_params : (MD_ArenaParams){0};
|
||||
|
||||
SPTR const varena_header_size = align_pow2(size_of(VArena), MD_DEFAULT_MEMORY_ALIGNMENT);
|
||||
SPTR const header_size = align_pow2(size_of(Arena), MD_DEFAULT_MEMORY_ALIGNMENT);
|
||||
MD_SPTR const varena_header_size = md_align_pow2(size_of(MD_VArena), MD_DEFAULT_MEMORY_ALIGNMENT);
|
||||
MD_SPTR const header_size = md_align_pow2(size_of(MD_Arena), MD_DEFAULT_MEMORY_ALIGNMENT);
|
||||
|
||||
U64 const varena_reserve_size = VARENA_DEFAULT_RESERVE;
|
||||
MD_U64 const varena_reserve_size = MD_VARENA_DEFAULT_RESERVE;
|
||||
|
||||
B32 is_virtual = allocator_type(params.backing) & AllocatorType_VArena;
|
||||
params.flags |= ArenaFlag_Virtual * is_virtual;
|
||||
MD_B32 is_virtual = md_allocator_type(params.backing) & MD_AllocatorType_VArena;
|
||||
params.flags |= MD_ArenaFlag_Virtual * is_virtual;
|
||||
|
||||
|
||||
if (params.backing.proc == nullptr) params.backing = default_allocator();
|
||||
if (params.block_size == 0 ) params.block_size = ARENA_DEFAULT_BLOCK_SIZE;
|
||||
if (params.backing.proc == md_nullptr) params.backing = md_default_allocator();
|
||||
if (params.block_size == 0 ) params.block_size = MD_ARENA_DEFAULT_BLOCK_SIZE;
|
||||
|
||||
SSIZE alloc_size = is_virtual ? header_size : params.block_size;
|
||||
MD_SSIZE md_alloc_size = is_virtual ? header_size : params.block_size;
|
||||
|
||||
void* base = alloc(params.backing, alloc_size);
|
||||
void* base = md_alloc(params.backing, md_alloc_size);
|
||||
// rjf: extract arena header & fill
|
||||
Arena* arena = (Arena*) base;
|
||||
arena->prev = nullptr;
|
||||
MD_Arena* arena = (MD_Arena*) base;
|
||||
arena->prev = md_nullptr;
|
||||
arena->current = arena;
|
||||
arena->backing = params.backing;
|
||||
arena->base_pos = 0;
|
||||
arena->pos = header_size;
|
||||
arena->block_size = params.block_size;
|
||||
arena->flags = params.flags;
|
||||
asan_unpoison_memory_region(base, sizeof(Arena));
|
||||
md_asan_unpoison_memory_region(base, sizeof(MD_Arena));
|
||||
return arena;
|
||||
}
|
||||
|
||||
//- rjf: arena push/pop core functions
|
||||
|
||||
void*
|
||||
arena_push(Arena* arena, SSIZE size, SSIZE align)
|
||||
md_arena_push(MD_Arena* arena, MD_SSIZE size, MD_SSIZE align)
|
||||
{
|
||||
SPTR const header_size = align_pow2(size_of(Arena), MD_DEFAULT_MEMORY_ALIGNMENT);
|
||||
MD_SPTR const header_size = md_align_pow2(size_of(MD_Arena), MD_DEFAULT_MEMORY_ALIGNMENT);
|
||||
|
||||
Arena* current = arena->current;
|
||||
SPTR curr_sptr = scast(SPTR, current);
|
||||
MD_Arena* current = arena->current;
|
||||
MD_SPTR curr_sptr = md_scast(MD_SPTR, current);
|
||||
|
||||
SSIZE aligned_size = align_pow2(size, align);
|
||||
MD_SSIZE aligned_size = md_align_pow2(size, align);
|
||||
|
||||
SPTR pos_pre = current->pos;
|
||||
SPTR pos_pst = pos_pre + aligned_size;
|
||||
MD_SPTR pos_pre = current->pos;
|
||||
MD_SPTR pos_pst = pos_pre + aligned_size;
|
||||
|
||||
B32 is_virtual = arena->flags & ArenaFlag_Virtual;
|
||||
MD_B32 is_virtual = arena->flags & MD_ArenaFlag_Virtual;
|
||||
|
||||
// rjf: chain, if needed
|
||||
if ( current->block_size < pos_pst && ! (arena->flags & ArenaFlag_NoChain) )
|
||||
if ( current->block_size < pos_pst && ! (arena->flags & MD_ArenaFlag_NoChain) )
|
||||
{
|
||||
Arena* new_block = nullptr;
|
||||
MD_Arena* new_block = md_nullptr;
|
||||
|
||||
B32 vmem_chain = is_virtual && (arena->flags & ArenaFlag_NoChainVirtual);
|
||||
MD_B32 vmem_chain = is_virtual && (arena->flags & MD_ArenaFlag_NoChainVirtual);
|
||||
if (vmem_chain) {
|
||||
SPTR const varena_header_size = align_pow2(size_of(VArena), MD_DEFAULT_MEMORY_ALIGNMENT);
|
||||
SPTR const arena_block_size = VARENA_DEFAULT_RESERVE - varena_header_size;
|
||||
MD_SPTR const varena_header_size = md_align_pow2(size_of(MD_VArena), MD_DEFAULT_MEMORY_ALIGNMENT);
|
||||
MD_SPTR const md_arena_block_size = MD_VARENA_DEFAULT_RESERVE - varena_header_size;
|
||||
|
||||
VArena* vcurrent = rcast(VArena*, arena->backing.data);
|
||||
MD_VArena* vcurrent = md_rcast(MD_VArena*, arena->backing.data);
|
||||
|
||||
VArena* new_vm = varena_alloc(.reserve_size = vcurrent->reserve, .commit_size = vcurrent->commit_size);
|
||||
new_block = arena_alloc(.backing = varena_allocator(new_vm), .block_size = arena_block_size);
|
||||
MD_VArena* new_vm = md_varena_alloc(.reserve_size = vcurrent->reserve, .commit_size = vcurrent->commit_size);
|
||||
new_block = md_arena_alloc(.backing = md_varena_allocator(new_vm), .block_size = md_arena_block_size);
|
||||
}
|
||||
else {
|
||||
SPTR const arena_block_size = arena->block_size + header_size;
|
||||
new_block = arena_alloc(.backing = arena->backing, .block_size = arena_block_size);
|
||||
MD_SPTR const md_arena_block_size = arena->block_size + header_size;
|
||||
new_block = md_arena_alloc(.backing = arena->backing, .block_size = md_arena_block_size);
|
||||
}
|
||||
new_block->base_pos = current->base_pos + current->block_size;
|
||||
|
||||
sll_stack_push_n(arena->current, new_block, prev);
|
||||
md_sll_stack_push_n(arena->current, new_block, prev);
|
||||
|
||||
current = new_block;
|
||||
pos_pre = current->pos;
|
||||
@@ -92,23 +92,23 @@ arena_push(Arena* arena, SSIZE size, SSIZE align)
|
||||
// rjf: push onto current block
|
||||
void* result = 0;
|
||||
{
|
||||
result = scast(void*, curr_sptr + pos_pre);
|
||||
result = md_scast(void*, curr_sptr + pos_pre);
|
||||
current->pos = pos_pst;
|
||||
asan_unpoison_memory_region(result, size);
|
||||
md_asan_unpoison_memory_region(result, size);
|
||||
}
|
||||
|
||||
if (is_virtual) {
|
||||
// Sync virtual arena
|
||||
void* vresult = alloc_align(arena->backing, size, align);
|
||||
assert(vresult == result);
|
||||
void* vresult = md_alloc_align(arena->backing, size, align);
|
||||
md_assert(vresult == result);
|
||||
}
|
||||
|
||||
// rjf: panic on failure
|
||||
#if OS_FEATURE_GRAPHICAL
|
||||
if(unlikely(result == 0))
|
||||
#if MD_OS_FEATURE_GRAPHICAL
|
||||
if(md_unlikely(result == 0))
|
||||
{
|
||||
os_graphical_message(1, str8_lit("Fatal Allocation Failure"), str8_lit("Unexpected memory allocation failure."));
|
||||
os_abort(1);
|
||||
md_os_graphical_message(1, md_str8_lit("Fatal Allocation Failure"), md_str8_lit("Unexpected memory allocation failure."));
|
||||
md_os_abort(1);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -116,77 +116,77 @@ arena_push(Arena* arena, SSIZE size, SSIZE align)
|
||||
}
|
||||
|
||||
void
|
||||
arena_pop_to(Arena *arena, SSIZE pos)
|
||||
md_arena_pop_to(MD_Arena *arena, MD_SSIZE pos)
|
||||
{
|
||||
SPTR const header_size = align_pow2(size_of(Arena), MD_DEFAULT_MEMORY_ALIGNMENT);
|
||||
MD_SPTR const header_size = md_align_pow2(size_of(MD_Arena), MD_DEFAULT_MEMORY_ALIGNMENT);
|
||||
|
||||
Arena* current = arena->current;
|
||||
AllocatorInfo backing = current->backing;
|
||||
B32 is_virtual = allocator_type(backing) & AllocatorType_VArena;
|
||||
MD_Arena* current = arena->current;
|
||||
MD_AllocatorInfo backing = current->backing;
|
||||
MD_B32 is_virtual = md_allocator_type(backing) & MD_AllocatorType_VArena;
|
||||
|
||||
SSIZE big_pos = clamp_bot(header_size, pos);
|
||||
MD_SSIZE big_pos = md_clamp_bot(header_size, pos);
|
||||
// If base position is larger than the position to pop to:
|
||||
// We are in a previous arena and msut free the current
|
||||
for(Arena* prev = 0; current->base_pos >= big_pos; current = prev)
|
||||
for(MD_Arena* prev = 0; current->base_pos >= big_pos; current = prev)
|
||||
{
|
||||
prev = current->prev;
|
||||
|
||||
if (is_virtual) {
|
||||
varena_release(rcast(VArena*, current->backing.data));
|
||||
md_varena_release(md_rcast(MD_VArena*, current->backing.data));
|
||||
}
|
||||
else if (allocator_query_support(backing) & AllocatorQuery_Free) {
|
||||
alloc_free(current->backing, current);
|
||||
else if (md_allocator_query_support(backing) & MD_AllocatorQuery_Free) {
|
||||
md_alloc_free(current->backing, current);
|
||||
}
|
||||
}
|
||||
arena->current = current;
|
||||
SSIZE new_pos = big_pos - current->base_pos;
|
||||
assert_always(new_pos <= current->pos);
|
||||
asan_poison_memory_region((U8*)current + new_pos, (current->pos - new_pos));
|
||||
MD_SSIZE new_pos = big_pos - current->base_pos;
|
||||
md_assert_always(new_pos <= current->pos);
|
||||
md_asan_poison_memory_region((MD_U8*)current + new_pos, (current->pos - new_pos));
|
||||
current->pos = new_pos;
|
||||
if (is_virtual) {
|
||||
varena_rewind(rcast(VArena*, current->backing.data), current->pos);
|
||||
varena_rewind(md_rcast(MD_VArena*, current->backing.data), current->pos);
|
||||
}
|
||||
}
|
||||
|
||||
void* arena_allocator_proc(void* allocator_data, AllocatorMode mode, SSIZE size, SSIZE alignment, void* old_memory, SSIZE old_size, U64 flags)
|
||||
void* md_arena_allocator_proc(void* allocator_data, MD_AllocatorMode mode, MD_SSIZE size, MD_SSIZE alignment, void* old_memory, MD_SSIZE old_size, MD_U64 flags)
|
||||
{
|
||||
Arena* arena = rcast(Arena*, allocator_data);
|
||||
MD_Arena* arena = md_rcast(MD_Arena*, allocator_data);
|
||||
|
||||
void* allocated_ptr = nullptr;
|
||||
void* allocated_ptr = md_nullptr;
|
||||
switch (mode)
|
||||
{
|
||||
case AllocatorMode_Alloc:
|
||||
case MD_AllocatorMode_Alloc:
|
||||
{
|
||||
allocated_ptr = arena_push(arena, size, alignment);
|
||||
allocated_ptr = md_arena_push(arena, size, alignment);
|
||||
}
|
||||
break;
|
||||
|
||||
case AllocatorMode_Free:
|
||||
case MD_AllocatorMode_Free:
|
||||
{
|
||||
}
|
||||
break;
|
||||
|
||||
case AllocatorMode_FreeAll:
|
||||
case MD_AllocatorMode_FreeAll:
|
||||
{
|
||||
arena_release(arena);
|
||||
md_arena_release(arena);
|
||||
}
|
||||
break;
|
||||
|
||||
case AllocatorMode_Resize:
|
||||
case MD_AllocatorMode_Resize:
|
||||
{
|
||||
assert(old_memory != nullptr);
|
||||
assert(old_size > 0);
|
||||
assert_msg(old_size == size, "Requested resize when none needed");
|
||||
md_assert(old_memory != md_nullptr);
|
||||
md_assert(old_size > 0);
|
||||
md_assert_msg(old_size == size, "Requested md_resize when none needed");
|
||||
|
||||
size = align_pow2(size, alignment);
|
||||
old_size = align_pow2(size, alignment);
|
||||
size = md_align_pow2(size, alignment);
|
||||
old_size = md_align_pow2(size, alignment);
|
||||
|
||||
SPTR old_memory_offset = scast(SPTR, old_memory) + old_size;
|
||||
SPTR current_offset = arena->pos;
|
||||
MD_SPTR old_memory_offset = md_scast(MD_SPTR, old_memory) + old_size;
|
||||
MD_SPTR current_offset = arena->pos;
|
||||
|
||||
assert_msg(old_memory_offset == current_offset, "Cannot resize existing allocation in VArena unless it was the last allocated");
|
||||
md_assert_msg(old_memory_offset == current_offset, "Cannot md_resize existing allocation in MD_VArena unless it was the last allocated");
|
||||
|
||||
B32 requested_shrink = size >= old_size;
|
||||
MD_B32 requested_shrink = size >= old_size;
|
||||
if (requested_shrink) {
|
||||
arena->pos -= size;
|
||||
allocated_ptr = old_memory;
|
||||
@@ -198,15 +198,15 @@ void* arena_allocator_proc(void* allocator_data, AllocatorMode mode, SSIZE size,
|
||||
}
|
||||
break;
|
||||
|
||||
case AllocatorMode_QueryType:
|
||||
case MD_AllocatorMode_QueryType:
|
||||
{
|
||||
return (void*) AllocatorType_Arena;
|
||||
return (void*) MD_AllocatorType_Arena;
|
||||
}
|
||||
break;
|
||||
|
||||
case AllocatorMode_QuerySupport:
|
||||
case MD_AllocatorMode_QuerySupport:
|
||||
{
|
||||
return (void*) (AllocatorQuery_Alloc | AllocatorQuery_Resize | AllocatorQuery_FreeAll);
|
||||
return (void*) (MD_AllocatorQuery_Alloc | MD_AllocatorQuery_Resize | MD_AllocatorQuery_FreeAll);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
+79
-79
@@ -11,27 +11,27 @@
|
||||
////////////////////////////////
|
||||
//~ rjf: Types
|
||||
|
||||
typedef U32 ArenaFlags;
|
||||
typedef MD_U32 MD_ArenaFlags;
|
||||
enum
|
||||
{
|
||||
// Don't chain this arena
|
||||
ArenaFlag_NoChain = (1 << 0),
|
||||
// Only relevant if backing is virtual memory, will prevent allocating a new backing VArena when the current block exhausts
|
||||
// Will assume backing can chain multiple block_size arenas however. If there is an allocation failure it will assert.
|
||||
ArenaFlag_NoChainVirtual = (1 << 1),
|
||||
// Backing allocator identified as VArena during initialization
|
||||
ArenaFlag_Virtual = (1 << 2),
|
||||
MD_ArenaFlag_NoChain = (1 << 0),
|
||||
// Only relevant if backing is virtual memory, will prevent allocating a new backing MD_VArena when the current block exhausts
|
||||
// Will assume backing can chain multiple block_size arenas however. If there is an allocation failure it will md_assert.
|
||||
MD_ArenaFlag_NoChainVirtual = (1 << 1),
|
||||
// Backing allocator identified as MD_VArena during initialization
|
||||
MD_ArenaFlag_Virtual = (1 << 2),
|
||||
};
|
||||
|
||||
typedef struct ArenaParams ArenaParams;
|
||||
struct ArenaParams
|
||||
typedef struct MD_ArenaParams MD_ArenaParams;
|
||||
struct MD_ArenaParams
|
||||
{
|
||||
AllocatorInfo backing;
|
||||
ArenaFlags flags;
|
||||
U64 block_size; // If chaining VArenas set this to the reserve size
|
||||
MD_AllocatorInfo backing;
|
||||
MD_ArenaFlags flags;
|
||||
MD_U64 block_size; // If chaining VArenas set this to the reserve size
|
||||
};
|
||||
|
||||
#define ARENA_DEFAULT_BLOCK_SIZE VARENA_DEFAULT_RESERVE - align_pow2(size_of(VArena), MD_DEFAULT_MEMORY_ALIGNMENT)
|
||||
#define MD_ARENA_DEFAULT_BLOCK_SIZE MD_VARENA_DEFAULT_RESERVE - md_align_pow2(size_of(MD_VArena), MD_DEFAULT_MEMORY_ALIGNMENT)
|
||||
|
||||
/* NOTE(Ed): The original metadesk arena is a combination of several concepts into a single interface
|
||||
* An OS virtual memory allocation scheme
|
||||
@@ -40,136 +40,136 @@ struct ArenaParams
|
||||
|
||||
The virtual memory has been abstracted into a backing allocator,
|
||||
and chaining still supports reserving new virtual address regions .
|
||||
(can be disabled with ArenaFlag_NoChainVirtual)
|
||||
(can be disabled with MD_ArenaFlag_NoChainVirtual)
|
||||
|
||||
If large pages are desired, see VArena.
|
||||
If large pages are desired, see MD_VArena.
|
||||
*/
|
||||
|
||||
typedef struct Arena Arena;
|
||||
struct Arena
|
||||
typedef struct MD_Arena MD_Arena;
|
||||
struct MD_Arena
|
||||
{
|
||||
Arena* prev; // Previous arena in chain
|
||||
Arena* current; // Current arena in chain
|
||||
AllocatorInfo backing;
|
||||
SSIZE base_pos; // Tracks how main arenas have been chained
|
||||
SSIZE pos;
|
||||
SSIZE block_size;
|
||||
ArenaFlags flags;
|
||||
MD_Arena* prev; // Previous arena in chain
|
||||
MD_Arena* current; // Current arena in chain
|
||||
MD_AllocatorInfo backing;
|
||||
MD_SSIZE base_pos; // Tracks how main arenas have been chained
|
||||
MD_SSIZE pos;
|
||||
MD_SSIZE block_size;
|
||||
MD_ArenaFlags flags;
|
||||
};
|
||||
// static_assert(size_of(Arena) <= ARENA_HEADER_SIZE, "sizeof(Arena) <= ARENA_HEADER_SIZE");
|
||||
// static_assert(size_of(MD_Arena) <= ARENA_HEADER_SIZE, "sizeof(MD_Arena) <= ARENA_HEADER_SIZE");
|
||||
|
||||
typedef struct TempArena TempArena;
|
||||
struct TempArena
|
||||
typedef struct MD_TempArena MD_TempArena;
|
||||
struct MD_TempArena
|
||||
{
|
||||
Arena* arena;
|
||||
SSIZE pos;
|
||||
MD_Arena* arena;
|
||||
MD_SSIZE pos;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Arena Functions
|
||||
//~ rjf: MD_Arena Functions
|
||||
|
||||
MD_API void* arena_allocator_proc(void* allocator_data, AllocatorMode mode, SSIZE size, SSIZE alignment, void* old_memory, SSIZE old_size, U64 flags);
|
||||
MD_API void* md_arena_allocator_proc(void* allocator_data, MD_AllocatorMode mode, MD_SSIZE size, MD_SSIZE alignment, void* old_memory, MD_SSIZE old_size, MD_U64 flags);
|
||||
|
||||
force_inline AllocatorInfo arena_allocator(Arena* arena) { AllocatorInfo info = { arena_allocator_proc, arena}; return info; }
|
||||
md_force_inline MD_AllocatorInfo md_arena_allocator(MD_Arena* arena) { MD_AllocatorInfo info = { md_arena_allocator_proc, arena}; return info; }
|
||||
|
||||
// Useful for providing an arena to scratch_begin_alloc
|
||||
force_inline Arena*
|
||||
extract_arena(AllocatorInfo ainfo) {
|
||||
if (allocator_type(ainfo) == AllocatorType_Arena) {
|
||||
return (Arena*) ainfo.data;
|
||||
// Useful for providing an arena to md_scratch_begin_alloc
|
||||
md_force_inline MD_Arena*
|
||||
md_extract_arena(MD_AllocatorInfo ainfo) {
|
||||
if (md_allocator_type(ainfo) == MD_AllocatorType_Arena) {
|
||||
return (MD_Arena*) ainfo.data;
|
||||
}
|
||||
return nullptr;
|
||||
return md_nullptr;
|
||||
}
|
||||
|
||||
//- rjf: arena creation/destruction
|
||||
|
||||
MD_API Arena* arena__alloc(ArenaParams* params);
|
||||
#define arena_alloc(...) arena__alloc( &(ArenaParams){ __VA_ARGS__ } )
|
||||
MD_API MD_Arena* md_arena__alloc(MD_ArenaParams* params);
|
||||
#define md_arena_alloc(...) md_arena__alloc( &(MD_ArenaParams){ __VA_ARGS__ } )
|
||||
|
||||
void arena_release(Arena *arena);
|
||||
void md_arena_release(MD_Arena *arena);
|
||||
|
||||
//- rjf: arena push/pop/pos core functions
|
||||
|
||||
MD_API void* arena_push (Arena* arena, SSIZE size, SSIZE align);
|
||||
U64 arena_pos (Arena* arena);
|
||||
MD_API void arena_pop_to(Arena* arena, SSIZE pos);
|
||||
MD_API void* md_arena_push (MD_Arena* arena, MD_SSIZE size, MD_SSIZE align);
|
||||
MD_U64 md_arena_pos (MD_Arena* arena);
|
||||
MD_API void md_arena_pop_to(MD_Arena* arena, MD_SSIZE pos);
|
||||
|
||||
//- rjf: arena push/pop helpers
|
||||
|
||||
void arena_clear(Arena* arena);
|
||||
void arena_pop (Arena* arena, SSIZE amt);
|
||||
void md_arena_clear(MD_Arena* arena);
|
||||
void md_arena_pop (MD_Arena* arena, MD_SSIZE amt);
|
||||
|
||||
//- rjf: temporary arena scopes
|
||||
|
||||
TempArena temp_arena_begin(Arena* arena);
|
||||
void temp_arena_end(TempArena temp);
|
||||
MD_TempArena temp_arena_begin(MD_Arena* arena);
|
||||
void temp_arena_end(MD_TempArena temp);
|
||||
|
||||
//- rjf: push helper macros
|
||||
|
||||
#ifndef push_array
|
||||
#define push_array_no_zero_aligned(a, T, c, align) (T *)arena_push((a), sizeof(T) * (c), (align))
|
||||
#define push_array_aligned(a, T, c, align) (T *)memory_zero(push_array_no_zero_aligned(a, T, c, align), sizeof(T) * (c))
|
||||
#define push_array_no_zero(a, T, c) push_array_no_zero_aligned(a, T, c, max(8, align_of(T)))
|
||||
#define push_array(a, T, c) push_array_aligned (a, T, c, max(8, align_of(T)))
|
||||
#ifndef md_push_array_
|
||||
#define md_push_array__no_zero_aligned(a, T, c, align) (T *)md_arena_push((a), sizeof(T) * (c), (align))
|
||||
#define md_push_array__aligned(a, T, c, align) (T *)md_memory_zero(md_push_array__no_zero_aligned(a, T, c, align), sizeof(T) * (c))
|
||||
#define md_push_array__no_zero(a, T, c) md_push_array__no_zero_aligned(a, T, c, md_max(8, md_align_of(T)))
|
||||
#define md_push_array_(a, T, c) md_push_array__aligned (a, T, c, md_max(8, md_align_of(T)))
|
||||
#endif
|
||||
|
||||
// Inlines
|
||||
|
||||
inline void
|
||||
arena_release(Arena* arena) {
|
||||
for (Arena* n = arena->current, *prev = 0; n != 0; n = prev) {
|
||||
md_arena_release(MD_Arena* arena) {
|
||||
for (MD_Arena* n = arena->current, *prev = 0; n != 0; n = prev) {
|
||||
prev = n->prev;
|
||||
alloc_free(arena->backing, n);
|
||||
md_alloc_free(arena->backing, n);
|
||||
}
|
||||
}
|
||||
|
||||
inline U64
|
||||
arena_pos(Arena *arena) {
|
||||
Arena* current = arena->current;
|
||||
U64 pos = current->base_pos + current->pos;
|
||||
inline MD_U64
|
||||
md_arena_pos(MD_Arena *arena) {
|
||||
MD_Arena* current = arena->current;
|
||||
MD_U64 pos = current->base_pos + current->pos;
|
||||
return pos;
|
||||
}
|
||||
|
||||
//- rjf: arena push/pop helpers
|
||||
|
||||
force_inline void arena_clear(Arena* arena) { arena_pop_to(arena, 0); }
|
||||
md_force_inline void md_arena_clear(MD_Arena* arena) { md_arena_pop_to(arena, 0); }
|
||||
|
||||
inline void
|
||||
arena_pop(Arena* arena, SSIZE amt) {
|
||||
SSIZE pos_old = arena_pos(arena);
|
||||
SSIZE pos_new = pos_old;
|
||||
md_arena_pop(MD_Arena* arena, MD_SSIZE amt) {
|
||||
MD_SSIZE pos_old = md_arena_pos(arena);
|
||||
MD_SSIZE pos_new = pos_old;
|
||||
if (amt < pos_old)
|
||||
{
|
||||
pos_new = pos_old - amt;
|
||||
}
|
||||
arena_pop_to(arena, pos_new);
|
||||
md_arena_pop_to(arena, pos_new);
|
||||
}
|
||||
|
||||
//- rjf: temporary arena scopes
|
||||
|
||||
inline TempArena
|
||||
temp_begin(Arena* arena) {
|
||||
U64 pos = arena_pos(arena);
|
||||
TempArena temp = {arena, pos};
|
||||
inline MD_TempArena
|
||||
md_temp_begin(MD_Arena* arena) {
|
||||
MD_U64 pos = md_arena_pos(arena);
|
||||
MD_TempArena temp = {arena, pos};
|
||||
return temp;
|
||||
}
|
||||
|
||||
force_inline void temp_end(TempArena temp) { arena_pop_to(temp.arena, temp.pos); }
|
||||
md_force_inline void md_temp_end(MD_TempArena temp) { md_arena_pop_to(temp.arena, temp.pos); }
|
||||
|
||||
// ======================================== DEFAULT_ALLOCATOR =====================================================
|
||||
|
||||
#ifndef MD_OVERRIDE_DEFAULT_ALLOCATOR
|
||||
// The default allocator for this base module is the Arena allocator with a VArena backing
|
||||
// NOTE(Ed): In order for this to work, either the os entry_point must have been utilized or os_init needs to be called.
|
||||
inline AllocatorInfo
|
||||
default_allocator()
|
||||
// The default allocator for this base module is the MD_Arena allocator with a MD_VArena backing
|
||||
// NOTE(Ed): In order for this to work, either the os md_entry_point must have been utilized or md_os_init needs to be called.
|
||||
inline MD_AllocatorInfo
|
||||
md_default_allocator()
|
||||
{
|
||||
local_persist thread_local Arena* arena = nullptr;
|
||||
if (arena == nullptr) {
|
||||
VArena* backing_vmem = varena_alloc(.flags = 0, .base_addr = 0x0, .reserve_size = VARENA_DEFAULT_RESERVE, .commit_size = VARENA_DEFAULT_COMMIT);
|
||||
arena = arena_alloc(.backing = varena_allocator(backing_vmem), .block_size = VARENA_DEFAULT_RESERVE);
|
||||
md_local_persist md_thread_local MD_Arena* arena = md_nullptr;
|
||||
if (arena == md_nullptr) {
|
||||
MD_VArena* backing_vmem = md_varena_alloc(.flags = 0, .base_addr = 0x0, .reserve_size = MD_VARENA_DEFAULT_RESERVE, .commit_size = MD_VARENA_DEFAULT_COMMIT);
|
||||
arena = md_arena_alloc(.backing = md_varena_allocator(backing_vmem), .block_size = MD_VARENA_DEFAULT_RESERVE);
|
||||
}
|
||||
AllocatorInfo info = { arena_allocator_proc, arena };
|
||||
MD_AllocatorInfo info = { md_arena_allocator_proc, arena };
|
||||
return info;
|
||||
}
|
||||
#endif
|
||||
|
||||
+236
-236
@@ -7,65 +7,65 @@
|
||||
# include "platform.h"
|
||||
#endif
|
||||
|
||||
#if defined( COMPILER_MSVC )
|
||||
#if defined( MD_COMPILER_MSVC )
|
||||
# if _MSC_VER < 1300
|
||||
typedef unsigned char, U8;
|
||||
typedef signed char, S8;
|
||||
typedef unsigned short, U16;
|
||||
typedef signed short, S16;
|
||||
typedef unsigned int, U32;
|
||||
typedef signed int, S32;
|
||||
typedef unsigned char, MD_U8;
|
||||
typedef signed char, MD_S8;
|
||||
typedef unsigned short, MD_U16;
|
||||
typedef signed short, MD_S16;
|
||||
typedef unsigned int, MD_U32;
|
||||
typedef signed int, MD_S32;
|
||||
# else
|
||||
typedef unsigned __int8 U8;
|
||||
typedef signed __int8 S8;
|
||||
typedef unsigned __int16 U16;
|
||||
typedef signed __int16 S16;
|
||||
typedef unsigned __int32 U32;
|
||||
typedef signed __int32 S32;
|
||||
typedef unsigned __int8 MD_U8;
|
||||
typedef signed __int8 MD_S8;
|
||||
typedef unsigned __int16 MD_U16;
|
||||
typedef signed __int16 MD_S16;
|
||||
typedef unsigned __int32 MD_U32;
|
||||
typedef signed __int32 MD_S32;
|
||||
# endif
|
||||
typedef unsigned __int64 U64;
|
||||
typedef signed __int64 S64;
|
||||
typedef unsigned __int64 MD_U64;
|
||||
typedef signed __int64 MD_S64;
|
||||
#else
|
||||
# include <stdint.h>
|
||||
|
||||
typedef uint8_t, U8;
|
||||
typedef int8_t, S8;
|
||||
typedef uint16_t, U16;
|
||||
typedef int16_t, S16;
|
||||
typedef uint32_t, U32;
|
||||
typedef int32_t, S32;
|
||||
typedef uint64_t, U64;
|
||||
typedef int64_t, S64;
|
||||
typedef uint8_t, MD_U8;
|
||||
typedef int8_t, MD_S8;
|
||||
typedef uint16_t, MD_U16;
|
||||
typedef int16_t, MD_S16;
|
||||
typedef uint32_t, MD_U32;
|
||||
typedef int32_t, MD_S32;
|
||||
typedef uint64_t, MD_U64;
|
||||
typedef int64_t, MD_S64;
|
||||
#endif
|
||||
|
||||
typedef struct U128 U128;
|
||||
struct U128 {
|
||||
U64 data[2];
|
||||
MD_U64 data[2];
|
||||
};
|
||||
|
||||
static_assert( sizeof( U8 ) == sizeof( S8 ), "sizeof(U8) != sizeof(S8)" );
|
||||
static_assert( sizeof( U16 ) == sizeof( S16 ), "sizeof(U16) != sizeof(sS6)" );
|
||||
static_assert( sizeof( U32 ) == sizeof( S32 ), "sizeof(U32) != sizeof(sS2)" );
|
||||
static_assert( sizeof( U64 ) == sizeof( S64 ), "sizeof(U64) != sizeof(sS4)" );
|
||||
static_assert( sizeof( MD_U8 ) == sizeof( MD_S8 ), "sizeof(MD_U8) != sizeof(MD_S8)" );
|
||||
static_assert( sizeof( MD_U16 ) == sizeof( MD_S16 ), "sizeof(MD_U16) != sizeof(sS6)" );
|
||||
static_assert( sizeof( MD_U32 ) == sizeof( MD_S32 ), "sizeof(MD_U32) != sizeof(sS2)" );
|
||||
static_assert( sizeof( MD_U64 ) == sizeof( MD_S64 ), "sizeof(MD_U64) != sizeof(sS4)" );
|
||||
|
||||
static_assert( sizeof( U8 ) == 1, "sizeof(U8) != 1" );
|
||||
static_assert( sizeof( U16 ) == 2, "sizeof(U16) != 2" );
|
||||
static_assert( sizeof( U32 ) == 4, "sizeof(U32) != 4" );
|
||||
static_assert( sizeof( U64 ) == 8, "sizeof(U64) != 8" );
|
||||
static_assert( sizeof( MD_U8 ) == 1, "sizeof(MD_U8) != 1" );
|
||||
static_assert( sizeof( MD_U16 ) == 2, "sizeof(MD_U16) != 2" );
|
||||
static_assert( sizeof( MD_U32 ) == 4, "sizeof(MD_U32) != 4" );
|
||||
static_assert( sizeof( MD_U64 ) == 8, "sizeof(MD_U64) != 8" );
|
||||
|
||||
typedef size_t USIZE;
|
||||
typedef ptrdiff_t SSIZE;
|
||||
typedef size_t MD_USIZE;
|
||||
typedef ptrdiff_t MD_SSIZE;
|
||||
|
||||
static_assert( sizeof( USIZE ) == sizeof( SSIZE ), "sizeof(USIZE) != sizeof(SSIZE)" );
|
||||
static_assert( sizeof( MD_USIZE ) == sizeof( MD_SSIZE ), "sizeof(MD_USIZE) != sizeof(MD_SSIZE)" );
|
||||
|
||||
#ifndef size_of
|
||||
#define size_of( x ) ( SSIZE )( sizeof( x ) )
|
||||
#define size_of( x ) ( MD_SSIZE )( sizeof( x ) )
|
||||
#endif
|
||||
|
||||
// NOTE: (u)zpl_intptr is only here for semantic reasons really as this library will only support 32/64 bit OSes.
|
||||
#if defined( _WIN64 )
|
||||
typedef signed __int64 SPTR;
|
||||
typedef unsigned __int64 UPTR;
|
||||
typedef signed __int64 MD_SPTR;
|
||||
typedef unsigned __int64 MD_UPTR;
|
||||
#elif defined( _WIN32 )
|
||||
// NOTE; To mark types changing their size, e.g. zpl_intptr
|
||||
# ifndef _W64
|
||||
@@ -75,254 +75,254 @@ typedef unsigned __int64 UPTR;
|
||||
# define _W64
|
||||
# endif
|
||||
# endif
|
||||
typedef _W64 signed int SPTR;
|
||||
typedef _W64 unsigned int UPTR;
|
||||
typedef _W64 signed int MD_SPTR;
|
||||
typedef _W64 unsigned int MD_UPTR;
|
||||
#else
|
||||
typedef uintptr_t UPTR;
|
||||
typedef intptr_t SPTR;
|
||||
typedef uintptr_t MD_UPTR;
|
||||
typedef intptr_t MD_SPTR;
|
||||
#endif
|
||||
|
||||
static_assert( sizeof( UPTR ) == sizeof( SPTR ), "sizeof(UPTR) != sizeof(SPTR)" );
|
||||
static_assert( sizeof( MD_UPTR ) == sizeof( MD_SPTR ), "sizeof(MD_UPTR) != sizeof(MD_SPTR)" );
|
||||
|
||||
typedef float F32;
|
||||
typedef double F64;
|
||||
typedef float MD_F32;
|
||||
typedef double MD_F64;
|
||||
|
||||
static_assert( sizeof( F32 ) == 4, "sizeof(F32) != 4" );
|
||||
static_assert( sizeof( F64 ) == 8, "sizeof(F64) != 8" );
|
||||
static_assert( sizeof( MD_F32 ) == 4, "sizeof(MD_F32) != 4" );
|
||||
static_assert( sizeof( MD_F64 ) == 8, "sizeof(MD_F64) != 8" );
|
||||
|
||||
typedef S8 B8;
|
||||
typedef S16 B16;
|
||||
typedef S32 B32;
|
||||
typedef MD_S8 MD_B8;
|
||||
typedef MD_S16 MD_B16;
|
||||
typedef MD_S32 MD_B32;
|
||||
|
||||
typedef void VoidProc(void);
|
||||
distinct_register_selector(VoidProc);
|
||||
typedef void MD_VoidProc(void);
|
||||
md_distinct_register_selector(MD_VoidProc);
|
||||
|
||||
////////////////////////////////
|
||||
//~ NOTE(allen): Constants
|
||||
|
||||
#define SIGN32 0x80000000
|
||||
#define EXPONENT32 0x7F800000
|
||||
#define MANTISSA32 0x007FFFFF
|
||||
#define MD_SIGN32 0x80000000
|
||||
#define MD_EXPONENT32 0x7F800000
|
||||
#define MD_MANTISSA32 0x007FFFFF
|
||||
|
||||
#define BIG_GOLDEN32 1.61803398875f
|
||||
#define SMALL_GOLDEN32 0.61803398875f
|
||||
#define MD_BIG_GOLDEN32 1.61803398875f
|
||||
#define MD_SMALL_GOLDEN32 0.61803398875f
|
||||
|
||||
#define PI32 3.1415926535897f
|
||||
#define MD_PI32 3.1415926535897f
|
||||
|
||||
#define MACHINE_EPSILON64 4.94065645841247e-324
|
||||
#define MD_MACHINE_EPSILON64 4.94065645841247e-324
|
||||
|
||||
#define MIN_U8 0u
|
||||
#define MAX_U8 0xffu
|
||||
#define MIN_S8 ( -0x7f - 1 )
|
||||
#define MAX_S8 0x7f
|
||||
#define MD_MIN_U8 0u
|
||||
#define MD_MAX_U8 0xffu
|
||||
#define MD_MIN_S8 ( -0x7f - 1 )
|
||||
#define MD_MAX_S8 0x7f
|
||||
|
||||
#define MIN_U16 0u
|
||||
#define MAX_U16 0xffffu
|
||||
#define MIN_S16 ( -0x7fff - 1 )
|
||||
#define MAX_S16 0x7fff
|
||||
#define MD_MIN_U16 0u
|
||||
#define MD_MAX_U16 0xffffu
|
||||
#define MD_MIN_S16 ( -0x7fff - 1 )
|
||||
#define MD_MAX_S16 0x7fff
|
||||
|
||||
#define MIN_U32 0u
|
||||
#define MAX_U32 0xffffffffu
|
||||
#define MIN_S32 ( -0x7fffffff - 1 )
|
||||
#define MAX_S32 0x7fffffff
|
||||
#define MD_MIN_U32 0u
|
||||
#define MD_MAX_U32 0xffffffffu
|
||||
#define MD_MIN_S32 ( -0x7fffffff - 1 )
|
||||
#define MD_MAX_S32 0x7fffffff
|
||||
|
||||
#define MIN_U64 0ull
|
||||
#define MAX_U64 0xffffffffffffffffull
|
||||
#define MIN_S64 ( -0x7fffffffffffffffll - 1 )
|
||||
#define MAX_S64 0x7fffffffffffffffll
|
||||
#define MD_MIN_U64 0ull
|
||||
#define MD_MAX_U64 0xffffffffffffffffull
|
||||
#define MD_MIN_S64 ( -0x7fffffffffffffffll - 1 )
|
||||
#define MD_MAX_S64 0x7fffffffffffffffll
|
||||
|
||||
#if ARCH_32BIT
|
||||
# define MIN_USIZE U32_MIN
|
||||
# define MAX_USIZE U32_MAX
|
||||
#if MD_ARCH_32BIT
|
||||
# define MD_MIN_USIZE U32_MIN
|
||||
# define MD_MAX_USIZE U32_MAX
|
||||
# define MIN_SSIZE S32_MIN
|
||||
# define MAX_SSIZE S32_MAX
|
||||
#elif ARCH_64BIT
|
||||
# define MIN_USIZE U64_MIN
|
||||
# define MAX_USIZE U64_MAX
|
||||
#elif MD_ARCH_64BIT
|
||||
# define MD_MIN_USIZE U64_MIN
|
||||
# define MD_MAX_USIZE U64_MAX
|
||||
# define MIN_SSIZE S64_MIN
|
||||
# define MAX_SSIZE S64_MAX
|
||||
#else
|
||||
# error Unknown architecture size. This library only supports 32 bit and 64 bit architectures.
|
||||
#endif
|
||||
|
||||
#define MIN_F32 1.17549435e-38f
|
||||
#define MAX_F32 3.40282347e+38f
|
||||
#define MIN_F64 2.2250738585072014e-308
|
||||
#define MAX_F64 1.7976931348623157e+308
|
||||
#define MD_MIN_F32 1.17549435e-38f
|
||||
#define MD_MAX_F32 3.40282347e+38f
|
||||
#define MD_MIN_F64 2.2250738585072014e-308
|
||||
#define MD_MAX_F64 1.7976931348623157e+308
|
||||
|
||||
#define BITMASK1 0x00000001
|
||||
#define BITMASK2 0x00000003
|
||||
#define BITMASK3 0x00000007
|
||||
#define BITMASK4 0x0000000f
|
||||
#define BITMASK5 0x0000001f
|
||||
#define BITMASK6 0x0000003f
|
||||
#define BITMASK7 0x0000007f
|
||||
#define BITMASK8 0x000000ff
|
||||
#define BITMASK9 0x000001ff
|
||||
#define BITMASK10 0x000003ff
|
||||
#define BITMASK11 0x000007ff
|
||||
#define BITMASK12 0x00000fff
|
||||
#define BITMASK13 0x00001fff
|
||||
#define BITMASK14 0x00003fff
|
||||
#define BITMASK15 0x00007fff
|
||||
#define BITMASK16 0x0000ffff
|
||||
#define BITMASK17 0x0001ffff
|
||||
#define BITMASK18 0x0003ffff
|
||||
#define BITMASK19 0x0007ffff
|
||||
#define BITMASK20 0x000fffff
|
||||
#define BITMASK21 0x001fffff
|
||||
#define BITMASK22 0x003fffff
|
||||
#define BITMASK23 0x007fffff
|
||||
#define BITMASK24 0x00ffffff
|
||||
#define BITMASK25 0x01ffffff
|
||||
#define BITMASK26 0x03ffffff
|
||||
#define BITMASK27 0x07ffffff
|
||||
#define BITMASK28 0x0fffffff
|
||||
#define BITMASK29 0x1fffffff
|
||||
#define BITMASK30 0x3fffffff
|
||||
#define BITMASK31 0x7fffffff
|
||||
#define BITMASK32 0xffffffff
|
||||
#define MD_BITMASK1 0x00000001
|
||||
#define MD_BITMASK2 0x00000003
|
||||
#define MD_BITMASK3 0x00000007
|
||||
#define MD_BITMASK4 0x0000000f
|
||||
#define MD_BITMASK5 0x0000001f
|
||||
#define MD_BITMASK6 0x0000003f
|
||||
#define MD_BITMASK7 0x0000007f
|
||||
#define MD_BITMASK8 0x000000ff
|
||||
#define MD_BITMASK9 0x000001ff
|
||||
#define MD_BITMASK10 0x000003ff
|
||||
#define MD_BITMASK11 0x000007ff
|
||||
#define MD_BITMASK12 0x00000fff
|
||||
#define MD_BITMASK13 0x00001fff
|
||||
#define MD_BITMASK14 0x00003fff
|
||||
#define MD_BITMASK15 0x00007fff
|
||||
#define MD_BITMASK16 0x0000ffff
|
||||
#define MD_BITMASK17 0x0001ffff
|
||||
#define MD_BITMASK18 0x0003ffff
|
||||
#define MD_BITMASK19 0x0007ffff
|
||||
#define MD_BITMASK20 0x000fffff
|
||||
#define MD_BITMASK21 0x001fffff
|
||||
#define MD_BITMASK22 0x003fffff
|
||||
#define MD_BITMASK23 0x007fffff
|
||||
#define MD_BITMASK24 0x00ffffff
|
||||
#define MD_BITMASK25 0x01ffffff
|
||||
#define MD_BITMASK26 0x03ffffff
|
||||
#define MD_BITMASK27 0x07ffffff
|
||||
#define MD_BITMASK28 0x0fffffff
|
||||
#define MD_BITMASK29 0x1fffffff
|
||||
#define MD_BITMASK30 0x3fffffff
|
||||
#define MD_BITMASK31 0x7fffffff
|
||||
#define MD_BITMASK32 0xffffffff
|
||||
|
||||
#define BITMASK33 0x00000001ffffffffull
|
||||
#define BITMASK34 0x00000003ffffffffull
|
||||
#define BITMASK35 0x00000007ffffffffull
|
||||
#define BITMASK36 0x0000000fffffffffull
|
||||
#define BITMASK37 0x0000001fffffffffull
|
||||
#define BITMASK38 0x0000003fffffffffull
|
||||
#define BITMASK39 0x0000007fffffffffull
|
||||
#define BITMASK40 0x000000ffffffffffull
|
||||
#define BITMASK41 0x000001ffffffffffull
|
||||
#define BITMASK42 0x000003ffffffffffull
|
||||
#define BITMASK43 0x000007ffffffffffull
|
||||
#define BITMASK44 0x00000fffffffffffull
|
||||
#define BITMASK45 0x00001fffffffffffull
|
||||
#define BITMASK46 0x00003fffffffffffull
|
||||
#define BITMASK47 0x00007fffffffffffull
|
||||
#define BITMASK48 0x0000ffffffffffffull
|
||||
#define BITMASK49 0x0001ffffffffffffull
|
||||
#define BITMASK50 0x0003ffffffffffffull
|
||||
#define BITMASK51 0x0007ffffffffffffull
|
||||
#define BITMASK52 0x000fffffffffffffull
|
||||
#define BITMASK53 0x001fffffffffffffull
|
||||
#define BITMASK54 0x003fffffffffffffull
|
||||
#define BITMASK55 0x007fffffffffffffull
|
||||
#define BITMASK56 0x00ffffffffffffffull
|
||||
#define BITMASK57 0x01ffffffffffffffull
|
||||
#define BITMASK58 0x03ffffffffffffffull
|
||||
#define BITMASK59 0x07ffffffffffffffull
|
||||
#define BITMASK60 0x0fffffffffffffffull
|
||||
#define BITMASK61 0x1fffffffffffffffull
|
||||
#define BITMASK62 0x3fffffffffffffffull
|
||||
#define BITMASK63 0x7fffffffffffffffull
|
||||
#define BITMASK64 0xffffffffffffffffull
|
||||
#define MD_BITMASK33 0x00000001ffffffffull
|
||||
#define MD_BITMASK34 0x00000003ffffffffull
|
||||
#define MD_BITMASK35 0x00000007ffffffffull
|
||||
#define MD_BITMASK36 0x0000000fffffffffull
|
||||
#define MD_BITMASK37 0x0000001fffffffffull
|
||||
#define MD_BITMASK38 0x0000003fffffffffull
|
||||
#define MD_BITMASK39 0x0000007fffffffffull
|
||||
#define MD_BITMASK40 0x000000ffffffffffull
|
||||
#define MD_BITMASK41 0x000001ffffffffffull
|
||||
#define MD_BITMASK42 0x000003ffffffffffull
|
||||
#define MD_BITMASK43 0x000007ffffffffffull
|
||||
#define MD_BITMASK44 0x00000fffffffffffull
|
||||
#define MD_BITMASK45 0x00001fffffffffffull
|
||||
#define MD_BITMASK46 0x00003fffffffffffull
|
||||
#define MD_BITMASK47 0x00007fffffffffffull
|
||||
#define MD_BITMASK48 0x0000ffffffffffffull
|
||||
#define MD_BITMASK49 0x0001ffffffffffffull
|
||||
#define MD_BITMASK50 0x0003ffffffffffffull
|
||||
#define MD_BITMASK51 0x0007ffffffffffffull
|
||||
#define MD_BITMASK52 0x000fffffffffffffull
|
||||
#define MD_BITMASK53 0x001fffffffffffffull
|
||||
#define MD_BITMASK54 0x003fffffffffffffull
|
||||
#define MD_BITMASK55 0x007fffffffffffffull
|
||||
#define MD_BITMASK56 0x00ffffffffffffffull
|
||||
#define MD_BITMASK57 0x01ffffffffffffffull
|
||||
#define MD_BITMASK58 0x03ffffffffffffffull
|
||||
#define MD_BITMASK59 0x07ffffffffffffffull
|
||||
#define MD_BITMASK60 0x0fffffffffffffffull
|
||||
#define MD_BITMASK61 0x1fffffffffffffffull
|
||||
#define MD_BITMASK62 0x3fffffffffffffffull
|
||||
#define MD_BITMASK63 0x7fffffffffffffffull
|
||||
#define MD_BITMASK64 0xffffffffffffffffull
|
||||
|
||||
#define BIT1 (1 << 0)
|
||||
#define BIT2 (1 << 1)
|
||||
#define BIT3 (1 << 2)
|
||||
#define BIT4 (1 << 3)
|
||||
#define BIT5 (1 << 4)
|
||||
#define BIT6 (1 << 5)
|
||||
#define BIT7 (1 << 6)
|
||||
#define BIT8 (1 << 7)
|
||||
#define BIT9 (1 << 8)
|
||||
#define BIT10 (1 << 9)
|
||||
#define BIT11 (1 << 10)
|
||||
#define BIT12 (1 << 11)
|
||||
#define BIT13 (1 << 12)
|
||||
#define BIT14 (1 << 13)
|
||||
#define BIT15 (1 << 14)
|
||||
#define BIT16 (1 << 15)
|
||||
#define BIT17 (1 << 16)
|
||||
#define BIT18 (1 << 17)
|
||||
#define BIT19 (1 << 18)
|
||||
#define BIT20 (1 << 19)
|
||||
#define BIT21 (1 << 20)
|
||||
#define BIT22 (1 << 21)
|
||||
#define BIT23 (1 << 22)
|
||||
#define BIT24 (1 << 23)
|
||||
#define BIT25 (1 << 24)
|
||||
#define BIT26 (1 << 25)
|
||||
#define BIT27 (1 << 26)
|
||||
#define BIT28 (1 << 27)
|
||||
#define BIT29 (1 << 28)
|
||||
#define BIT30 (1 << 29)
|
||||
#define BIT31 (1 << 30)
|
||||
#define BIT32 (1 << 31)
|
||||
#define MD_BIT1 (1 << 0)
|
||||
#define MD_BIT2 (1 << 1)
|
||||
#define MD_BIT3 (1 << 2)
|
||||
#define MD_BIT4 (1 << 3)
|
||||
#define MD_BIT5 (1 << 4)
|
||||
#define MD_BIT6 (1 << 5)
|
||||
#define MD_BIT7 (1 << 6)
|
||||
#define MD_BIT8 (1 << 7)
|
||||
#define MD_BIT9 (1 << 8)
|
||||
#define MD_BIT10 (1 << 9)
|
||||
#define MD_BIT11 (1 << 10)
|
||||
#define MD_BIT12 (1 << 11)
|
||||
#define MD_BIT13 (1 << 12)
|
||||
#define MD_BIT14 (1 << 13)
|
||||
#define MD_BIT15 (1 << 14)
|
||||
#define MD_BIT16 (1 << 15)
|
||||
#define MD_BIT17 (1 << 16)
|
||||
#define MD_BIT18 (1 << 17)
|
||||
#define MD_BIT19 (1 << 18)
|
||||
#define MD_BIT20 (1 << 19)
|
||||
#define MD_BIT21 (1 << 20)
|
||||
#define MD_BIT22 (1 << 21)
|
||||
#define MD_BIT23 (1 << 22)
|
||||
#define MD_BIT24 (1 << 23)
|
||||
#define MD_BIT25 (1 << 24)
|
||||
#define MD_BIT26 (1 << 25)
|
||||
#define MD_BIT27 (1 << 26)
|
||||
#define MD_BIT28 (1 << 27)
|
||||
#define MD_BIT29 (1 << 28)
|
||||
#define MD_BIT30 (1 << 29)
|
||||
#define MD_BIT31 (1 << 30)
|
||||
#define MD_BIT32 (1 << 31)
|
||||
|
||||
#define BIT33 (1ull << 32)
|
||||
#define BIT34 (1ull << 33)
|
||||
#define BIT35 (1ull << 34)
|
||||
#define BIT36 (1ull << 35)
|
||||
#define BIT37 (1ull << 36)
|
||||
#define BIT38 (1ull << 37)
|
||||
#define BIT39 (1ull << 38)
|
||||
#define BIT40 (1ull << 39)
|
||||
#define BIT41 (1ull << 40)
|
||||
#define BIT42 (1ull << 41)
|
||||
#define BIT43 (1ull << 42)
|
||||
#define BIT44 (1ull << 43)
|
||||
#define BIT45 (1ull << 44)
|
||||
#define BIT46 (1ull << 45)
|
||||
#define BIT47 (1ull << 46)
|
||||
#define BIT48 (1ull << 47)
|
||||
#define BIT49 (1ull << 48)
|
||||
#define BIT50 (1ull << 49)
|
||||
#define BIT51 (1ull << 50)
|
||||
#define BIT52 (1ull << 51)
|
||||
#define BIT53 (1ull << 52)
|
||||
#define BIT54 (1ull << 53)
|
||||
#define BIT55 (1ull << 54)
|
||||
#define BIT56 (1ull << 55)
|
||||
#define BIT57 (1ull << 56)
|
||||
#define BIT58 (1ull << 57)
|
||||
#define BIT59 (1ull << 58)
|
||||
#define BIT60 (1ull << 59)
|
||||
#define BIT61 (1ull << 60)
|
||||
#define BIT62 (1ull << 61)
|
||||
#define BIT63 (1ull << 62)
|
||||
#define BIT64 (1ull << 63)
|
||||
#define MD_BIT33 (1ull << 32)
|
||||
#define MD_BIT34 (1ull << 33)
|
||||
#define MD_BIT35 (1ull << 34)
|
||||
#define MD_BIT36 (1ull << 35)
|
||||
#define MD_BIT37 (1ull << 36)
|
||||
#define MD_BIT38 (1ull << 37)
|
||||
#define MD_BIT39 (1ull << 38)
|
||||
#define MD_BIT40 (1ull << 39)
|
||||
#define MD_BIT41 (1ull << 40)
|
||||
#define MD_BIT42 (1ull << 41)
|
||||
#define MD_BIT43 (1ull << 42)
|
||||
#define MD_BIT44 (1ull << 43)
|
||||
#define MD_BIT45 (1ull << 44)
|
||||
#define MD_BIT46 (1ull << 45)
|
||||
#define MD_BIT47 (1ull << 46)
|
||||
#define MD_BIT48 (1ull << 47)
|
||||
#define MD_BIT49 (1ull << 48)
|
||||
#define MD_BIT50 (1ull << 49)
|
||||
#define MD_BIT51 (1ull << 50)
|
||||
#define MD_BIT52 (1ull << 51)
|
||||
#define MD_BIT53 (1ull << 52)
|
||||
#define MD_BIT54 (1ull << 53)
|
||||
#define MD_BIT55 (1ull << 54)
|
||||
#define MD_BIT56 (1ull << 55)
|
||||
#define MD_BIT57 (1ull << 56)
|
||||
#define MD_BIT58 (1ull << 57)
|
||||
#define MD_BIT59 (1ull << 58)
|
||||
#define MD_BIT60 (1ull << 59)
|
||||
#define MD_BIT61 (1ull << 60)
|
||||
#define MD_BIT62 (1ull << 61)
|
||||
#define MD_BIT63 (1ull << 62)
|
||||
#define MD_BIT64 (1ull << 63)
|
||||
|
||||
////////////////////////////////
|
||||
//~ Globally Unique Ids
|
||||
|
||||
typedef union Guid Guid;
|
||||
union Guid
|
||||
typedef union MD_Guid MD_Guid;
|
||||
union MD_Guid
|
||||
{
|
||||
struct
|
||||
{
|
||||
U32 data1;
|
||||
U16 data2;
|
||||
U16 data3;
|
||||
U8 data4[8];
|
||||
MD_U32 data1;
|
||||
MD_U16 data2;
|
||||
MD_U16 data3;
|
||||
MD_U8 data4[8];
|
||||
};
|
||||
U8 v[16];
|
||||
MD_U8 v[16];
|
||||
};
|
||||
static_assert(size_of(Guid) == 16, "Guid is not 16 bytes");
|
||||
static_assert(size_of(MD_Guid) == 16, "MD_Guid is not 16 bytes");
|
||||
|
||||
////////////////////////////////
|
||||
//~ Arrays
|
||||
|
||||
typedef struct U16Array U16Array;
|
||||
struct U16Array
|
||||
typedef struct MD_U16Array MD_U16Array;
|
||||
struct MD_U16Array
|
||||
{
|
||||
U64 count;
|
||||
U16* v;
|
||||
MD_U64 count;
|
||||
MD_U16* v;
|
||||
};
|
||||
typedef struct U32Array U32Array;
|
||||
struct U32Array
|
||||
typedef struct MD_U32Array MD_U32Array;
|
||||
struct MD_U32Array
|
||||
{
|
||||
U64 count;
|
||||
U32* v;
|
||||
MD_U64 count;
|
||||
MD_U32* v;
|
||||
};
|
||||
typedef struct U64Array U64Array;
|
||||
struct U64Array
|
||||
typedef struct MD_U64Array MD_U64Array;
|
||||
struct MD_U64Array
|
||||
{
|
||||
U64 count;
|
||||
U64* v;
|
||||
MD_U64 count;
|
||||
MD_U64* v;
|
||||
};
|
||||
typedef struct U128Array U128Array;
|
||||
struct U128Array
|
||||
typedef struct MD_U128Array MD_U128Array;
|
||||
struct MD_U128Array
|
||||
{
|
||||
U64 count;
|
||||
MD_U64 count;
|
||||
U128* v;
|
||||
};
|
||||
|
||||
+55
-55
@@ -8,24 +8,24 @@
|
||||
////////////////////////////////
|
||||
//~ NOTE(rjf): Command Line Option Parsing
|
||||
|
||||
CmdLineOpt**
|
||||
cmd_line_slot_from_string(CmdLine* cmd_line, String8 string) {
|
||||
CmdLineOpt** slot = 0;
|
||||
MD_CmdLineOpt**
|
||||
md_cmd_line_slot_from_string(MD_CmdLine* cmd_line, MD_String8 string) {
|
||||
MD_CmdLineOpt** slot = 0;
|
||||
if (cmd_line->option_table_size != 0)
|
||||
{
|
||||
U64 hash = cmd_line_hash_from_string(string);
|
||||
U64 bucket = hash % cmd_line->option_table_size;
|
||||
MD_U64 hash = md_cmd_line_hash_from_string(string);
|
||||
MD_U64 bucket = hash % cmd_line->option_table_size;
|
||||
slot = &cmd_line->option_table[bucket];
|
||||
}
|
||||
return slot;
|
||||
}
|
||||
|
||||
CmdLineOpt*
|
||||
cmd_line_opt_from_slot(CmdLineOpt** slot, String8 string) {
|
||||
CmdLineOpt* result = 0;
|
||||
for (CmdLineOpt* var = *slot; var; var = var->hash_next)
|
||||
MD_CmdLineOpt*
|
||||
md_cmd_line_opt_from_slot(MD_CmdLineOpt** slot, MD_String8 string) {
|
||||
MD_CmdLineOpt* result = 0;
|
||||
for (MD_CmdLineOpt* var = *slot; var; var = var->hash_next)
|
||||
{
|
||||
if (str8_match(string, var->string, 0)) {
|
||||
if (md_str8_match(string, var->string, 0)) {
|
||||
result = var;
|
||||
break;
|
||||
}
|
||||
@@ -33,73 +33,73 @@ cmd_line_opt_from_slot(CmdLineOpt** slot, String8 string) {
|
||||
return result;
|
||||
}
|
||||
|
||||
CmdLineOpt*
|
||||
cmd_line_insert_opt__ainfo(AllocatorInfo ainfo, CmdLine* cmd_line, String8 string, String8List values)
|
||||
MD_CmdLineOpt*
|
||||
md_cmd_line_insert_opt__ainfo(MD_AllocatorInfo ainfo, MD_CmdLine* cmd_line, MD_String8 string, MD_String8List values)
|
||||
{
|
||||
CmdLineOpt *var = 0;
|
||||
CmdLineOpt **slot = cmd_line_slot_from_string(cmd_line, string);
|
||||
CmdLineOpt *existing_var = cmd_line_opt_from_slot(slot, string);
|
||||
MD_CmdLineOpt *var = 0;
|
||||
MD_CmdLineOpt **slot = md_cmd_line_slot_from_string(cmd_line, string);
|
||||
MD_CmdLineOpt *existing_var = md_cmd_line_opt_from_slot(slot, string);
|
||||
if(existing_var != 0)
|
||||
{
|
||||
var = existing_var;
|
||||
}
|
||||
else
|
||||
{
|
||||
var = alloc_array(ainfo, CmdLineOpt, 1);
|
||||
var = md_alloc_array(ainfo, MD_CmdLineOpt, 1);
|
||||
var->hash_next = *slot;
|
||||
var->hash = cmd_line_hash_from_string(string);
|
||||
var->string = str8_copy(ainfo, string);
|
||||
var->hash = md_cmd_line_hash_from_string(string);
|
||||
var->string = md_str8_copy(ainfo, string);
|
||||
var->value_strings = values;
|
||||
|
||||
StringJoin join = {0};
|
||||
join.pre = str8_lit("");
|
||||
join.sep = str8_lit(",");
|
||||
join.post = str8_lit("");
|
||||
MD_StringJoin join = {0};
|
||||
join.pre = md_str8_lit("");
|
||||
join.sep = md_str8_lit(",");
|
||||
join.post = md_str8_lit("");
|
||||
|
||||
var->value_string = str8_list_join(ainfo, &var->value_strings, &join);
|
||||
var->value_string = md_str8_list_join(ainfo, &var->value_strings, &join);
|
||||
*slot = var;
|
||||
cmd_line_push_opt(&cmd_line->options, var);
|
||||
md_cmd_line_push_opt(&cmd_line->options, var);
|
||||
}
|
||||
return var;
|
||||
}
|
||||
|
||||
|
||||
|
||||
CmdLine
|
||||
cmd_line_from_string_list__ainfo(AllocatorInfo ainfo, String8List command_line)
|
||||
MD_CmdLine
|
||||
md_cmd_line_from_string_list__ainfo(MD_AllocatorInfo ainfo, MD_String8List command_line)
|
||||
{
|
||||
CmdLine parsed = {0};
|
||||
MD_CmdLine parsed = {0};
|
||||
parsed.exe_name = command_line.first->string;
|
||||
|
||||
// NOTE(rjf): Set up config option table.
|
||||
{
|
||||
parsed.option_table_size = 4096;
|
||||
parsed.option_table = alloc_array(ainfo, CmdLineOpt*, parsed.option_table_size);
|
||||
parsed.option_table = md_alloc_array(ainfo, MD_CmdLineOpt*, parsed.option_table_size);
|
||||
}
|
||||
|
||||
// NOTE(rjf): Parse command line.
|
||||
B32 after_passthrough_option = 0;
|
||||
B32 first_passthrough = 1;
|
||||
for (String8Node* node = command_line.first->next, *next = 0; node != 0; node = next)
|
||||
MD_B32 after_passthrough_option = 0;
|
||||
MD_B32 first_passthrough = 1;
|
||||
for (MD_String8Node* node = command_line.first->next, *next = 0; node != 0; node = next)
|
||||
{
|
||||
next = node->next;
|
||||
String8 option_name = node->string;
|
||||
MD_String8 option_name = node->string;
|
||||
|
||||
// NOTE(rjf): Look at -- or - at the start of an argument to determine if it's
|
||||
// a flag option. All arguments after a single "--" (with no trailing string
|
||||
// on the command line will be considered as input files.
|
||||
B32 is_option = 1;
|
||||
MD_B32 is_option = 1;
|
||||
if(after_passthrough_option == 0)
|
||||
{
|
||||
if (str8_match(node->string, str8_lit("--"), 0)) {
|
||||
if (md_str8_match(node->string, md_str8_lit("--"), 0)) {
|
||||
after_passthrough_option = 1;
|
||||
is_option = 0;
|
||||
}
|
||||
else if (str8_match(str8_prefix(node->string, 2), str8_lit("--"), 0)) {
|
||||
option_name = str8_skip(option_name, 2);
|
||||
else if (md_str8_match(md_str8_prefix(node->string, 2), md_str8_lit("--"), 0)) {
|
||||
option_name = md_str8_skip(option_name, 2);
|
||||
}
|
||||
else if (str8_match(str8_prefix(node->string, 1), str8_lit("-"), 0)) {
|
||||
option_name = str8_skip(option_name, 1);
|
||||
else if (md_str8_match(md_str8_prefix(node->string, 1), md_str8_lit("-"), 0)) {
|
||||
option_name = md_str8_skip(option_name, 1);
|
||||
}
|
||||
else {
|
||||
is_option = 0;
|
||||
@@ -113,49 +113,49 @@ cmd_line_from_string_list__ainfo(AllocatorInfo ainfo, String8List command_line)
|
||||
// NOTE(rjf): This string is an option.
|
||||
if(is_option)
|
||||
{
|
||||
B32 has_arguments = 0;
|
||||
U64 arg_signifier_position1 = str8_find_needle(option_name, 0, str8_lit(":"), 0);
|
||||
U64 arg_signifier_position2 = str8_find_needle(option_name, 0, str8_lit("="), 0);
|
||||
U64 arg_signifier_position = min(arg_signifier_position1, arg_signifier_position2);
|
||||
String8 arg_portion_this_string = str8_skip(option_name, arg_signifier_position+1);
|
||||
MD_B32 has_arguments = 0;
|
||||
MD_U64 arg_signifier_position1 = md_str8_find_needle(option_name, 0, md_str8_lit(":"), 0);
|
||||
MD_U64 arg_signifier_position2 = md_str8_find_needle(option_name, 0, md_str8_lit("="), 0);
|
||||
MD_U64 arg_signifier_position = md_min(arg_signifier_position1, arg_signifier_position2);
|
||||
MD_String8 arg_portion_this_string = md_str8_skip(option_name, arg_signifier_position+1);
|
||||
if (arg_signifier_position < option_name.size) {
|
||||
has_arguments = 1;
|
||||
}
|
||||
option_name = str8_prefix(option_name, arg_signifier_position);
|
||||
option_name = md_str8_prefix(option_name, arg_signifier_position);
|
||||
|
||||
String8List arguments = {0};
|
||||
MD_String8List arguments = {0};
|
||||
|
||||
// NOTE(rjf): Parse arguments.
|
||||
if (has_arguments)
|
||||
{
|
||||
for (String8Node* n = node; n; n = n->next)
|
||||
for (MD_String8Node* n = node; n; n = n->next)
|
||||
{
|
||||
next = n->next;
|
||||
|
||||
String8 string = n->string;
|
||||
MD_String8 string = n->string;
|
||||
if (n == node) {
|
||||
string = arg_portion_this_string;
|
||||
}
|
||||
|
||||
U8 splits[] = { ',' };
|
||||
String8List args_in_this_string = str8_split(ainfo, string, splits, array_count(splits), 0);
|
||||
for (String8Node* sub_arg = args_in_this_string.first; sub_arg; sub_arg = sub_arg->next) {
|
||||
str8_list_push(ainfo, &arguments, sub_arg->string);
|
||||
MD_U8 splits[] = { ',' };
|
||||
MD_String8List args_in_this_string = md_str8_split(ainfo, string, splits, md_array_count(splits), 0);
|
||||
for (MD_String8Node* sub_arg = args_in_this_string.first; sub_arg; sub_arg = sub_arg->next) {
|
||||
md_str8_list_push(ainfo, &arguments, sub_arg->string);
|
||||
}
|
||||
if ( !str8_match(str8_postfix(n->string, 1), str8_lit(","), 0) && (n != node || arg_portion_this_string.size != 0)) {
|
||||
if ( !md_str8_match(md_str8_postfix(n->string, 1), md_str8_lit(","), 0) && (n != node || arg_portion_this_string.size != 0)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE(rjf): Register config variable.
|
||||
cmd_line_insert_opt(ainfo, &parsed, option_name, arguments);
|
||||
md_cmd_line_insert_opt(ainfo, &parsed, option_name, arguments);
|
||||
}
|
||||
|
||||
// NOTE(rjf): Default path, treat as a passthrough config option to be
|
||||
// handled by tool-specific code.
|
||||
else if ( !str8_match(node->string, str8_lit("--"), 0) || !first_passthrough) {
|
||||
str8_list_push(ainfo, &parsed.inputs, node->string);
|
||||
else if ( !md_str8_match(node->string, md_str8_lit("--"), 0) || !first_passthrough) {
|
||||
md_str8_list_push(ainfo, &parsed.inputs, node->string);
|
||||
after_passthrough_option = 1;
|
||||
first_passthrough = 0;
|
||||
}
|
||||
|
||||
+61
-61
@@ -9,98 +9,98 @@
|
||||
////////////////////////////////
|
||||
//~ rjf: Parsed Command Line Types
|
||||
|
||||
typedef struct CmdLineOpt CmdLineOpt;
|
||||
struct CmdLineOpt
|
||||
typedef struct MD_CmdLineOpt MD_CmdLineOpt;
|
||||
struct MD_CmdLineOpt
|
||||
{
|
||||
CmdLineOpt* next;
|
||||
CmdLineOpt* hash_next;
|
||||
U64 hash;
|
||||
String8 string;
|
||||
String8List value_strings;
|
||||
String8 value_string;
|
||||
MD_CmdLineOpt* next;
|
||||
MD_CmdLineOpt* hash_next;
|
||||
MD_U64 hash;
|
||||
MD_String8 string;
|
||||
MD_String8List value_strings;
|
||||
MD_String8 value_string;
|
||||
};
|
||||
|
||||
typedef struct CmdLineOptList CmdLineOptList;
|
||||
struct CmdLineOptList
|
||||
typedef struct MD_CmdLineOptList MD_CmdLineOptList;
|
||||
struct MD_CmdLineOptList
|
||||
{
|
||||
U64 count;
|
||||
CmdLineOpt* first;
|
||||
CmdLineOpt* last;
|
||||
MD_U64 count;
|
||||
MD_CmdLineOpt* first;
|
||||
MD_CmdLineOpt* last;
|
||||
};
|
||||
|
||||
typedef struct CmdLine CmdLine;
|
||||
struct CmdLine
|
||||
typedef struct MD_CmdLine MD_CmdLine;
|
||||
struct MD_CmdLine
|
||||
{
|
||||
String8 exe_name;
|
||||
CmdLineOptList options;
|
||||
String8List inputs;
|
||||
U64 option_table_size;
|
||||
CmdLineOpt** option_table;
|
||||
MD_String8 exe_name;
|
||||
MD_CmdLineOptList options;
|
||||
MD_String8List inputs;
|
||||
MD_U64 option_table_size;
|
||||
MD_CmdLineOpt** option_table;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ NOTE(rjf): Command Line Option Parsing
|
||||
|
||||
U64 cmd_line_hash_from_string(String8 string);
|
||||
MD_API CmdLineOpt** cmd_line_slot_from_string(CmdLine* cmd_line, String8 string);
|
||||
MD_API CmdLineOpt* cmd_line_opt_from_slot (CmdLineOpt** slot, String8 string);
|
||||
void cmd_line_push_opt (CmdLineOptList* list, CmdLineOpt* var);
|
||||
MD_U64 md_cmd_line_hash_from_string(MD_String8 string);
|
||||
MD_API MD_CmdLineOpt** md_cmd_line_slot_from_string(MD_CmdLine* cmd_line, MD_String8 string);
|
||||
MD_API MD_CmdLineOpt* md_cmd_line_opt_from_slot (MD_CmdLineOpt** slot, MD_String8 string);
|
||||
void md_cmd_line_push_opt (MD_CmdLineOptList* list, MD_CmdLineOpt* var);
|
||||
|
||||
CmdLineOpt* cmd_line_opt_from_string (CmdLine* cmd_line, String8 name);
|
||||
String8List cmd_line_strings (CmdLine* cmd_line, String8 name);
|
||||
String8 cmd_line_string (CmdLine* cmd_line, String8 name);
|
||||
B32 cmd_line_has_flag (CmdLine* cmd_line, String8 name);
|
||||
B32 cmd_line_has_argument (CmdLine* cmd_line, String8 name);
|
||||
MD_CmdLineOpt* md_cmd_line_opt_from_string (MD_CmdLine* cmd_line, MD_String8 name);
|
||||
MD_String8List md_cmd_line_strings (MD_CmdLine* cmd_line, MD_String8 name);
|
||||
MD_String8 md_cmd_line_string (MD_CmdLine* cmd_line, MD_String8 name);
|
||||
MD_B32 md_cmd_line_has_flag (MD_CmdLine* cmd_line, MD_String8 name);
|
||||
MD_B32 md_cmd_line_has_argument (MD_CmdLine* cmd_line, MD_String8 name);
|
||||
|
||||
inline CmdLineOpt* cmd_line_insert_opt__arena (Arena* arena, CmdLine* cmd_line, String8 string, String8List values);
|
||||
MD_API CmdLineOpt* cmd_line_insert_opt__ainfo (AllocatorInfo ainfo, CmdLine* cmd_line, String8 string, String8List values);
|
||||
inline CmdLine cmd_line_from_string_list__arena(Arena* arena, String8List arguments);
|
||||
MD_API CmdLine cmd_line_from_string_list__ainfo(AllocatorInfo ainfo, String8List arguments);
|
||||
inline MD_CmdLineOpt* md_cmd_line_insert_opt__arena (MD_Arena* arena, MD_CmdLine* cmd_line, MD_String8 string, MD_String8List values);
|
||||
MD_API MD_CmdLineOpt* md_cmd_line_insert_opt__ainfo (MD_AllocatorInfo ainfo, MD_CmdLine* cmd_line, MD_String8 string, MD_String8List values);
|
||||
inline MD_CmdLine md_cmd_line_from_string_list__arena(MD_Arena* arena, MD_String8List arguments);
|
||||
MD_API MD_CmdLine md_cmd_line_from_string_list__ainfo(MD_AllocatorInfo ainfo, MD_String8List arguments);
|
||||
|
||||
#define cmd_line_insert_opt(allocator, cmd_line, string, values) \
|
||||
#define md_cmd_line_insert_opt(allocator, cmd_line, string, values) \
|
||||
_Generic(allocator, \
|
||||
Arena*: cmd_line_insert_opt__arena, \
|
||||
AllocatorInfo: cmd_line_insert_opt__ainfo, \
|
||||
default: assert_generic_sel_fail \
|
||||
) generic_call(allocator, cmd_line, string, values)
|
||||
MD_Arena*: md_cmd_line_insert_opt__arena, \
|
||||
MD_AllocatorInfo: md_cmd_line_insert_opt__ainfo, \
|
||||
default: md_assert_generic_sel_fail \
|
||||
) md_generic_call(allocator, cmd_line, string, values)
|
||||
|
||||
#define cmd_line_from_string_list(allocator, arguments) \
|
||||
#define md_cmd_line_from_string_list(allocator, arguments) \
|
||||
_Generic(allocator, \
|
||||
Arena*: cmd_line_from_string_list__arena, \
|
||||
AllocatorInfo: cmd_line_from_string_list__ainfo, \
|
||||
default: assert_generic_sel_fail \
|
||||
) generic_call(allocator, arguments)
|
||||
MD_Arena*: md_cmd_line_from_string_list__arena, \
|
||||
MD_AllocatorInfo: md_cmd_line_from_string_list__ainfo, \
|
||||
default: md_assert_generic_sel_fail \
|
||||
) md_generic_call(allocator, arguments)
|
||||
|
||||
inline U64
|
||||
cmd_line_hash_from_string(String8 string) {
|
||||
U64 result = 5381;
|
||||
for(U64 i = 0; i < string.size; i += 1) {
|
||||
inline MD_U64
|
||||
md_cmd_line_hash_from_string(MD_String8 string) {
|
||||
MD_U64 result = 5381;
|
||||
for(MD_U64 i = 0; i < string.size; i += 1) {
|
||||
result = ((result << 5) + result) + string.str[i];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
force_inline CmdLineOpt* cmd_line_insert_opt__arena (Arena* arena, CmdLine* cmd_line, String8 string, String8List values) { return cmd_line_insert_opt__ainfo (arena_allocator(arena), cmd_line, string, values); }
|
||||
force_inline CmdLine cmd_line_from_string_list__arena(Arena* arena, String8List command_line) { return cmd_line_from_string_list__ainfo(arena_allocator(arena), command_line); }
|
||||
md_force_inline MD_CmdLineOpt* md_cmd_line_insert_opt__arena (MD_Arena* arena, MD_CmdLine* cmd_line, MD_String8 string, MD_String8List values) { return md_cmd_line_insert_opt__ainfo (md_arena_allocator(arena), cmd_line, string, values); }
|
||||
md_force_inline MD_CmdLine md_cmd_line_from_string_list__arena(MD_Arena* arena, MD_String8List command_line) { return md_cmd_line_from_string_list__ainfo(md_arena_allocator(arena), command_line); }
|
||||
|
||||
inline CmdLineOpt* cmd_line_opt_from_string(CmdLine *cmd_line, String8 name) { return cmd_line_opt_from_slot(cmd_line_slot_from_string(cmd_line, name), name); }
|
||||
inline B32 cmd_line_has_flag (CmdLine *cmd_line, String8 name) { CmdLineOpt *var = cmd_line_opt_from_string(cmd_line, name); return(var != 0); }
|
||||
inline B32 cmd_line_has_argument (CmdLine *cmd_line, String8 name) { CmdLineOpt *var = cmd_line_opt_from_string(cmd_line, name); return(var != 0 && var->value_strings.node_count > 0); }
|
||||
inline MD_CmdLineOpt* md_cmd_line_opt_from_string(MD_CmdLine *cmd_line, MD_String8 name) { return md_cmd_line_opt_from_slot(md_cmd_line_slot_from_string(cmd_line, name), name); }
|
||||
inline MD_B32 md_cmd_line_has_flag (MD_CmdLine *cmd_line, MD_String8 name) { MD_CmdLineOpt *var = md_cmd_line_opt_from_string(cmd_line, name); return(var != 0); }
|
||||
inline MD_B32 md_cmd_line_has_argument (MD_CmdLine *cmd_line, MD_String8 name) { MD_CmdLineOpt *var = md_cmd_line_opt_from_string(cmd_line, name); return(var != 0 && var->value_strings.md_node_count > 0); }
|
||||
|
||||
inline String8List
|
||||
cmd_line_strings(CmdLine *cmd_line, String8 name) {
|
||||
String8List result = {0};
|
||||
CmdLineOpt* var = cmd_line_opt_from_string(cmd_line, name);
|
||||
inline MD_String8List
|
||||
md_cmd_line_strings(MD_CmdLine *cmd_line, MD_String8 name) {
|
||||
MD_String8List result = {0};
|
||||
MD_CmdLineOpt* var = md_cmd_line_opt_from_string(cmd_line, name);
|
||||
if (var != 0) { result = var->value_strings; }
|
||||
return result;
|
||||
}
|
||||
|
||||
inline String8
|
||||
cmd_line_string(CmdLine *cmd_line, String8 name) {
|
||||
String8 result = {0};
|
||||
CmdLineOpt* var = cmd_line_opt_from_string(cmd_line, name);
|
||||
inline MD_String8
|
||||
md_cmd_line_string(MD_CmdLine *cmd_line, MD_String8 name) {
|
||||
MD_String8 result = {0};
|
||||
MD_CmdLineOpt* var = md_cmd_line_opt_from_string(cmd_line, name);
|
||||
if (var != 0) { result = var->value_string; }
|
||||
return result;
|
||||
}
|
||||
|
||||
inline void cmd_line_push_opt(CmdLineOptList* list, CmdLineOpt* var) { sll_queue_push(list->first, list->last, var); list->count += 1; }
|
||||
inline void md_cmd_line_push_opt(MD_CmdLineOptList* list, MD_CmdLineOpt* var) { md_sll_queue_push(list->first, list->last, var); list->count += 1; }
|
||||
|
||||
+140
-140
@@ -7,68 +7,68 @@
|
||||
////////////////////////////////
|
||||
//~ rjf: Build Options
|
||||
|
||||
#if ! defined(BUILD_DEBUG)
|
||||
# define BUILD_DEBUG 1
|
||||
#if ! defined(MD_BUILD_DEBUG)
|
||||
# define MD_BUILD_DEBUG 1
|
||||
#endif
|
||||
|
||||
#if ! defined(BUILD_STATIC)
|
||||
# define BUILD_STATIC 0
|
||||
#if ! defined(MD_BUILD_STATIC)
|
||||
# define MD_BUILD_STATIC 0
|
||||
#endif
|
||||
|
||||
#if ! defined(BUILD_DYANMIC)
|
||||
# define BUILD_DYANMIC 0
|
||||
#if ! defined(MD_BUILD_DYANMIC)
|
||||
# define MD_BUILD_DYANMIC 0
|
||||
#endif
|
||||
|
||||
#if ! defined(BUILD_API_EXPORT)
|
||||
# define BUILD_API_EXPORT 0
|
||||
#if ! defined(MD_BUILD_API_EXPORT)
|
||||
# define MD_BUILD_API_EXPORT 0
|
||||
#endif
|
||||
|
||||
#if !defined(BUILD_ENTRY_DEFINING_UNIT)
|
||||
# define BUILD_ENTRY_DEFINING_UNIT 0
|
||||
#if !defined(MD_BUILD_ENTRY_DEFINING_UNIT)
|
||||
# define MD_BUILD_ENTRY_DEFINING_UNIT 0
|
||||
#endif
|
||||
|
||||
#if !defined(BUILD_CONSOLE_INTERFACE)
|
||||
# define BUILD_CONSOLE_INTERFACE 0
|
||||
#if !defined(MD_BUILD_CONSOLE_INTERFACE)
|
||||
# define MD_BUILD_CONSOLE_INTERFACE 0
|
||||
#endif
|
||||
|
||||
#if !defined(BUILD_VERSION_MAJOR)
|
||||
# define BUILD_VERSION_MAJOR 0
|
||||
#if !defined(MD_BUILD_VERSION_MAJOR)
|
||||
# define MD_BUILD_VERSION_MAJOR 0
|
||||
#endif
|
||||
|
||||
#if !defined(BUILD_VERSION_MINOR)
|
||||
# define BUILD_VERSION_MINOR 1
|
||||
#if !defined(MD_BUILD_VERSION_MINOR)
|
||||
# define MD_BUILD_VERSION_MINOR 1
|
||||
#endif
|
||||
|
||||
#if !defined(BUILD_VERSION_PATCH)
|
||||
# define BUILD_VERSION_PATCH 0
|
||||
#if !defined(MD_BUILD_VERSION_PATCH)
|
||||
# define MD_BUILD_VERSION_PATCH 0
|
||||
#endif
|
||||
|
||||
#define BUILD_VERSION_STRING_LITERAL stringify(BUILD_VERSION_MAJOR) "." stringify(BUILD_VERSION_MINOR) "." stringify(BUILD_VERSION_PATCH)
|
||||
#define MD_BUILD_VERSION_STRING_LITERAL md_stringify(MD_BUILD_VERSION_MAJOR) "." md_stringify(MD_BUILD_VERSION_MINOR) "." md_stringify(MD_BUILD_VERSION_PATCH)
|
||||
|
||||
#if BUILD_DEBUG
|
||||
# define BUILD_MODE_STRING_LITERAL_APPEND " [Debug]"
|
||||
#if MD_BUILD_DEBUG
|
||||
# define MD_BUILD_MODE_STRING_LITERAL_APPEND " [Debug]"
|
||||
#else
|
||||
# define BUILD_MODE_STRING_LITERAL_APPEND ""
|
||||
# define MD_BUILD_MODE_STRING_LITERAL_APPEND ""
|
||||
#endif
|
||||
#if defined(BUILD_GIT_HASH)
|
||||
# define BUILD_GIT_HASH_STRING_LITERAL_APPEND " [" BUILD_GIT_HASH "]"
|
||||
#if defined(MD_BUILD_GIT_HASH)
|
||||
# define MD_BUILD_GIT_HASH_STRING_LITERAL_APPEND " [" MD_BUILD_GIT_HASH "]"
|
||||
#else
|
||||
# define BUILD_GIT_HASH_STRING_LITERAL_APPEND ""
|
||||
# define MD_BUILD_GIT_HASH_STRING_LITERAL_APPEND ""
|
||||
#endif
|
||||
|
||||
#if !defined(BUILD_TITLE)
|
||||
# define BUILD_TITLE "Untitled"
|
||||
#if !defined(MD_BUILD_TITLE)
|
||||
# define MD_BUILD_TITLE "Untitled"
|
||||
#endif
|
||||
|
||||
#if !defined(BUILD_RELEASE_PHASE_STRING_LITERAL)
|
||||
# define BUILD_RELEASE_PHASE_STRING_LITERAL "ALPHA"
|
||||
#if !defined(MD_BUILD_RELEASE_PHASE_STRING_LITERAL)
|
||||
# define MD_BUILD_RELEASE_PHASE_STRING_LITERAL "ALPHA"
|
||||
#endif
|
||||
|
||||
#if !defined(BUILD_ISSUES_LINK_STRING_LITERAL)
|
||||
# define BUILD_ISSUES_LINK_STRING_LITERAL "ADD_BUILD_ISSUES_LINK"
|
||||
#if !defined(MD_BUILD_ISSUES_LINK_STRING_LITERAL)
|
||||
# define MD_BUILD_ISSUES_LINK_STRING_LITERAL "ADD_BUILD_ISSUES_LINK"
|
||||
#endif
|
||||
|
||||
#define BUILD_TITLE_STRING_LITERAL BUILD_TITLE " (" BUILD_VERSION_STRING_LITERAL " " BUILD_RELEASE_PHASE_STRING_LITERAL ") - " __DATE__ "" BUILD_GIT_HASH_STRING_LITERAL_APPEND BUILD_MODE_STRING_LITERAL_APPEND
|
||||
#define MD_BUILD_TITLE_STRING_LITERAL MD_BUILD_TITLE " (" MD_BUILD_VERSION_STRING_LITERAL " " MD_BUILD_RELEASE_PHASE_STRING_LITERAL ") - " __DATE__ "" MD_BUILD_GIT_HASH_STRING_LITERAL_APPEND MD_BUILD_MODE_STRING_LITERAL_APPEND
|
||||
|
||||
#pragma endregion Build Options
|
||||
|
||||
@@ -76,83 +76,83 @@
|
||||
|
||||
#if defined( _MSC_VER )
|
||||
# pragma message("Detected MSVC")
|
||||
// # define COMPILER_CLANG 0
|
||||
# define COMPILER_MSVC 1
|
||||
// # define COMPILER_GCC 0
|
||||
// # define MD_COMPILER_CLANG 0
|
||||
# define MD_COMPILER_MSVC 1
|
||||
// # define MD_COMPILER_GCC 0
|
||||
# if _MSC_VER >= 1920
|
||||
# define COMPILER_MSVC_YEAR 2019
|
||||
# define MD_COMPILER_MSVC_YEAR 2019
|
||||
# elif _MSC_VER >= 1910
|
||||
# define COMPILER_MSVC_YEAR 2017
|
||||
# define MD_COMPILER_MSVC_YEAR 2017
|
||||
# elif _MSC_VER >= 1900
|
||||
# define COMPILER_MSVC_YEAR 2015
|
||||
# define MD_COMPILER_MSVC_YEAR 2015
|
||||
# elif _MSC_VER >= 1800
|
||||
# define COMPILER_MSVC_YEAR 2013
|
||||
# define MD_COMPILER_MSVC_YEAR 2013
|
||||
# elif _MSC_VER >= 1700
|
||||
# define COMPILER_MSVC_YEAR 2012
|
||||
# define MD_COMPILER_MSVC_YEAR 2012
|
||||
# elif _MSC_VER >= 1600
|
||||
# define COMPILER_MSVC_YEAR 2010
|
||||
# define MD_COMPILER_MSVC_YEAR 2010
|
||||
# elif _MSC_VER >= 1500
|
||||
# define M_DCOMPILER_MSVC_YEAR 2008
|
||||
# elif _MSC_VER >= 1400
|
||||
# define COMPILER_MSVC_YEAR 2005
|
||||
# define MD_COMPILER_MSVC_YEAR 2005
|
||||
# else
|
||||
# define COMPILER_MSVC_YEAR 0
|
||||
# define MD_COMPILER_MSVC_YEAR 0
|
||||
# endif
|
||||
|
||||
#elif defined( __GNUC__ )
|
||||
# pragma message("Detected GCC")
|
||||
// # define COMPILER_CLANG 0
|
||||
// # define COMPILER_MSVC 0
|
||||
# define COMPILER_GCC 1
|
||||
// # define MD_COMPILER_CLANG 0
|
||||
// # define MD_COMPILER_MSVC 0
|
||||
# define MD_COMPILER_GCC 1
|
||||
#elif defined( __clang__ )
|
||||
# pragma message("Detected CLANG")
|
||||
# define COMPILER_CLANG 1
|
||||
// # define COMPILER_MSVC 0
|
||||
// # define COMPILER_GCC 0
|
||||
# define MD_COMPILER_CLANG 1
|
||||
// # define MD_COMPILER_MSVC 0
|
||||
// # define MD_COMPILER_GCC 0
|
||||
#else
|
||||
# error Unknown compiler
|
||||
#endif
|
||||
|
||||
#if defined( __has_attribute )
|
||||
# define HAS_ATTRIBUTE( attribute ) __has_attribute( attribute )
|
||||
# define MD_HAS_ATTRIBUTE( attribute ) __has_attribute( attribute )
|
||||
#else
|
||||
# define HAS_ATTRIBUTE( attribute ) ( 0 )
|
||||
# define MD_HAS_ATTRIBUTE( attribute ) ( 0 )
|
||||
#endif
|
||||
|
||||
#if defined(GCC_VERSION_CHECK)
|
||||
# undef GCC_VERSION_CHECK
|
||||
#if defined(MD_GCC_VERSION_CHECK)
|
||||
# undef MD_GCC_VERSION_CHECK
|
||||
#endif
|
||||
#if defined(GEN_GCC_VERSION)
|
||||
# define GCC_VERSION_CHECK(major,minor,patch) (GEN_GCC_VERSION >= GEN_VERSION_ENCODE(major, minor, patch))
|
||||
# define MD_GCC_VERSION_CHECK(major,minor,patch) (GEN_GCC_VERSION >= GEN_VERSION_ENCODE(major, minor, patch))
|
||||
#else
|
||||
# define GCC_VERSION_CHECK(major,minor,patch) (0)
|
||||
# define MD_GCC_VERSION_CHECK(major,minor,patch) (0)
|
||||
#endif
|
||||
|
||||
#pragma endregion Vendor
|
||||
|
||||
#pragma region Language
|
||||
|
||||
#if ! defined(LANG_C)
|
||||
#if ! defined(MD_LANG_C)
|
||||
# ifdef __cplusplus
|
||||
# define LANG_C 0
|
||||
# define LANG_CPP 1
|
||||
# define MD_LANG_C 0
|
||||
# define MD_LANG_CPP 1
|
||||
# else
|
||||
# if defined(__STDC__)
|
||||
# define LANG_C 1
|
||||
# define LANG_CPP 0
|
||||
# define MD_LANG_C 1
|
||||
# define MD_LANG_CPP 0
|
||||
# else
|
||||
// Fallback for very old C compilers
|
||||
# define LANG_C 1
|
||||
# define LANG_CPP 0
|
||||
# define MD_LANG_C 1
|
||||
# define MD_LANG_CPP 0
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if LANG_C
|
||||
#if MD_LANG_C
|
||||
# pragma message("MD: Detected C")
|
||||
#endif
|
||||
|
||||
#if LANG_CPP
|
||||
#if MD_LANG_CPP
|
||||
# pragma message("MD: Detected CPP")
|
||||
#endif
|
||||
|
||||
@@ -160,56 +160,56 @@
|
||||
|
||||
#pragma region Hardware Architecture
|
||||
|
||||
#if COMPILER_CLANG
|
||||
#if MD_COMPILER_CLANG
|
||||
# if defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64)
|
||||
# define ARCH_X64 1
|
||||
# define MD_ARCH_X64 1
|
||||
# elif defined(i386) || defined(__i386) || defined(__i386__)
|
||||
# define ARCH_X86 1
|
||||
# define MD_ARCH_X86 1
|
||||
# elif defined(__aarch64__)
|
||||
# define ARCH_ARM64 1
|
||||
# define MD_ARCH_ARM64 1
|
||||
# elif defined(__arm__)
|
||||
# define ARCH_ARM32 1
|
||||
# define MD_ARCH_ARM32 1
|
||||
# else
|
||||
# error Architecture not supported.
|
||||
# endif
|
||||
#endif // COMPILER_CLANG
|
||||
#endif // MD_COMPILER_CLANG
|
||||
|
||||
#if COMPILER_MSVC
|
||||
#if MD_COMPILER_MSVC
|
||||
# if defined(_M_AMD64)
|
||||
# define ARCH_X64 1
|
||||
# define MD_ARCH_X64 1
|
||||
# elif defined(_M_IX86)
|
||||
# define ARCH_X86 1
|
||||
# define MD_ARCH_X86 1
|
||||
# elif defined(_M_ARM64)
|
||||
# define ARCH_ARM64 1
|
||||
# define MD_ARCH_ARM64 1
|
||||
# elif defined(_M_ARM)
|
||||
# define ARCH_ARM32 1
|
||||
# define MD_ARCH_ARM32 1
|
||||
# else
|
||||
# error Architecture not supported.
|
||||
# endif
|
||||
#endif // COMPILER_MSVC
|
||||
#endif // MD_COMPILER_MSVC
|
||||
|
||||
#if COMPILER_GCC
|
||||
#if MD_COMPILER_GCC
|
||||
# if defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64)
|
||||
# define ARCH_X64 1
|
||||
# define MD_ARCH_X64 1
|
||||
# elif defined(i386) || defined(__i386) || defined(__i386__)
|
||||
# define ARCH_X86 1
|
||||
# define MD_ARCH_X86 1
|
||||
# elif defined(__aarch64__)
|
||||
# define ARCH_ARM64 1
|
||||
# define MD_ARCH_ARM64 1
|
||||
# elif defined(__arm__)
|
||||
# define ARCH_ARM32 1
|
||||
# define MD_ARCH_ARM32 1
|
||||
# else
|
||||
# error Architecture not supported.
|
||||
# endif
|
||||
#endif // COMPILER_GCC
|
||||
#endif // MD_COMPILER_GCC
|
||||
|
||||
#if defined(ARCH_X64)
|
||||
# define ARCH_64BIT 1
|
||||
#elif defined(ARCH_X86)
|
||||
# define ARCH_32BIT 1
|
||||
#if defined(MD_ARCH_X64)
|
||||
# define MD_ARCH_64BIT 1
|
||||
#elif defined(MD_ARCH_X86)
|
||||
# define MD_ARCH_32BIT 1
|
||||
#endif
|
||||
|
||||
#if ARCH_ARM32 || ARCH_ARM64 || ARCH_X64 || ARCH_X86
|
||||
# define ARCH_LITTLE_ENDIAN 1
|
||||
#if MD_ARCH_ARM32 || MD_ARCH_ARM64 || MD_ARCH_X64 || MD_ARCH_X86
|
||||
# define MD_ARCH_LITTLE_ENDIAN 1
|
||||
#else
|
||||
# error Endianness of this architecture not understood by context cracker.
|
||||
#endif
|
||||
@@ -219,46 +219,46 @@
|
||||
#pragma region Operating System
|
||||
|
||||
#if defined( _WIN32 ) || defined( _WIN64 )
|
||||
# ifndef OS_WINDOWS
|
||||
# define OS_WINDOWS 1
|
||||
# ifndef MD_OS_WINDOWS
|
||||
# define MD_OS_WINDOWS 1
|
||||
# endif
|
||||
#elif defined( __APPLE__ ) && defined( __MACH__ )
|
||||
# ifndef OS_OSX
|
||||
# define OS_OSX 1
|
||||
# ifndef MD_OS_OSX
|
||||
# define MD_OS_OSX 1
|
||||
# endif
|
||||
# ifndef OS_MACOS
|
||||
# define OS_MACOS 1
|
||||
# ifndef MD_OS_MACOS
|
||||
# define MD_OS_MACOS 1
|
||||
# endif
|
||||
#elif defined( __unix__ )
|
||||
# ifndef OS_UNIX
|
||||
# define OS_UNIX 1
|
||||
# ifndef MD_OS_UNIX
|
||||
# define MD_OS_UNIX 1
|
||||
# endif
|
||||
# if defined( ANDROID ) || defined( __ANDROID__ )
|
||||
# ifndef OS_ANDROID
|
||||
# define OS_ANDROID 1
|
||||
# ifndef MD_OS_ANDROID
|
||||
# define MD_OS_ANDROID 1
|
||||
# endif
|
||||
# ifndef OS_LINUX
|
||||
# define OS_LINUX 1
|
||||
# ifndef MD_OS_LINUX
|
||||
# define MD_OS_LINUX 1
|
||||
# endif
|
||||
# elif defined( __linux__ )
|
||||
# ifndef OS_LINUX
|
||||
# define OS_LINUX 1
|
||||
# ifndef MD_OS_LINUX
|
||||
# define MD_OS_LINUX 1
|
||||
# endif
|
||||
# elif defined( __FreeBSD__ ) || defined( __FreeBSD_kernel__ )
|
||||
# ifndef OS_FREEBSD
|
||||
# define OS_FREEBSD 1
|
||||
# ifndef MD_OS_FREEBSD
|
||||
# define MD_OS_FREEBSD 1
|
||||
# endif
|
||||
# elif defined( __OpenBSD__ )
|
||||
# ifndef OS_OPENBSD
|
||||
# define OS_OPENBSD 1
|
||||
# ifndef MD_OS_OPENBSD
|
||||
# define MD_OS_OPENBSD 1
|
||||
# endif
|
||||
# elif defined( __EMSCRIPTEN__ )
|
||||
# ifndef OS_EMSCRIPTEN
|
||||
# define OS_EMSCRIPTEN 1
|
||||
# ifndef MD_OS_EMSCRIPTEN
|
||||
# define MD_OS_EMSCRIPTEN 1
|
||||
# endif
|
||||
# elif defined( __CYGWIN__ )
|
||||
# ifndef OS_CYGWIN
|
||||
# define OS_CYGWIN 1
|
||||
# ifndef MD_OS_CYGWIN
|
||||
# define MD_OS_CYGWIN 1
|
||||
# endif
|
||||
# else
|
||||
# error This UNIX operating system is not supported
|
||||
@@ -272,55 +272,55 @@
|
||||
////////////////////////////////
|
||||
//~ rjf: Zero All Undefined Options
|
||||
|
||||
#if !defined(ARCH_32BIT)
|
||||
# define ARCH_32BIT 0
|
||||
#if !defined(MD_ARCH_32BIT)
|
||||
# define MD_ARCH_32BIT 0
|
||||
#endif
|
||||
#if !defined(ARCH_64BIT)
|
||||
# define ARCH_64BIT 0
|
||||
#if !defined(MD_ARCH_64BIT)
|
||||
# define MD_ARCH_64BIT 0
|
||||
#endif
|
||||
#if !defined(ARCH_X64)
|
||||
# define ARCH_X64 0
|
||||
#if !defined(MD_ARCH_X64)
|
||||
# define MD_ARCH_X64 0
|
||||
#endif
|
||||
#if !defined(ARCH_X86)
|
||||
# define ARCH_X86 0
|
||||
#if !defined(MD_ARCH_X86)
|
||||
# define MD_ARCH_X86 0
|
||||
#endif
|
||||
#if !defined(ARCH_ARM64)
|
||||
# define ARCH_ARM64 0
|
||||
#if !defined(MD_ARCH_ARM64)
|
||||
# define MD_ARCH_ARM64 0
|
||||
#endif
|
||||
#if !defined(ARCH_ARM32)
|
||||
# define ARCH_ARM32 0
|
||||
#if !defined(MD_ARCH_ARM32)
|
||||
# define MD_ARCH_ARM32 0
|
||||
#endif
|
||||
#if !defined(COMPILER_MSVC)
|
||||
# define COMPILER_MSVC 0
|
||||
#if !defined(MD_COMPILER_MSVC)
|
||||
# define MD_COMPILER_MSVC 0
|
||||
#endif
|
||||
#if !defined(COMPILER_GCC)
|
||||
# define COMPILER_GCC 0
|
||||
#if !defined(MD_COMPILER_GCC)
|
||||
# define MD_COMPILER_GCC 0
|
||||
#endif
|
||||
#if !defined(COMPILER_CLANG)
|
||||
# define COMPILER_CLANG 0
|
||||
#if !defined(MD_COMPILER_CLANG)
|
||||
# define MD_COMPILER_CLANG 0
|
||||
#endif
|
||||
#if !defined(OS_WINDOWS)
|
||||
# define OS_WINDOWS 0
|
||||
#if !defined(MD_OS_WINDOWS)
|
||||
# define MD_OS_WINDOWS 0
|
||||
#endif
|
||||
#if !defined(OS_LINUX)
|
||||
# define OS_LINUX 0
|
||||
#if !defined(MD_OS_LINUX)
|
||||
# define MD_OS_LINUX 0
|
||||
#endif
|
||||
#if !defined(OS_MAC)
|
||||
# define OS_MAC 0
|
||||
#if !defined(MD_OS_MAC)
|
||||
# define MD_OS_MAC 0
|
||||
#endif
|
||||
#if !defined(LANG_CPP)
|
||||
# define LANG_CPP 0
|
||||
#if !defined(MD_LANG_CPP)
|
||||
# define MD_LANG_CPP 0
|
||||
#endif
|
||||
#if !defined(LANG_C)
|
||||
# define LANG_C 0
|
||||
#if !defined(MD_LANG_C)
|
||||
# define MD_LANG_C 0
|
||||
#endif
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Unsupported Errors
|
||||
|
||||
#if ARCH_X86
|
||||
#if MD_ARCH_X86
|
||||
# error You tried to build in x86 (32 bit) mode, but currently, only building in x64 (64 bit) mode is supported.
|
||||
#endif
|
||||
#if ! ARCH_X64
|
||||
#if ! MD_ARCH_X64
|
||||
# error You tried to build with an unsupported architecture. Currently, only building in x64 mode is supported.
|
||||
#endif
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@
|
||||
#define md__printf_err( fmt, ... ) fprintf( stderr, fmt, __VA_ARGS__ )
|
||||
#define md__printf_err_va( fmt, va ) vfprintf( stderr, fmt, va )
|
||||
|
||||
void assert_handler( char const* condition, char const* file, char const* function, S32 line, char const* msg, ... )
|
||||
void md_assert_handler( char const* condition, char const* file, char const* function, MD_S32 line, char const* msg, ... )
|
||||
{
|
||||
md__printf_err( "%s - %s:(%d): Assert Failure: ", file, function, line );
|
||||
|
||||
|
||||
+24
-24
@@ -11,53 +11,53 @@
|
||||
////////////////////////////////
|
||||
//~ rjf: Asserts
|
||||
|
||||
#ifndef trap
|
||||
# if COMPILER_MSVC
|
||||
#ifndef md_trap
|
||||
# if MD_COMPILER_MSVC
|
||||
# if _MSC_VER < 1300
|
||||
# define trap() __asm int 3 /* Trap to debugger! */
|
||||
# define md_trap() __asm int 3 /* Trap to debugger! */
|
||||
# else
|
||||
# define trap() __debugbreak()
|
||||
# define md_trap() __debugbreak()
|
||||
# endif
|
||||
# elif COMPILER_CLANG || COMPILER_GCC
|
||||
# define trap() __builtin_trap()
|
||||
# elif MD_COMPILER_CLANG || MD_COMPILER_GCC
|
||||
# define md_trap() __builtin_trap()
|
||||
# else
|
||||
# error Unknown trap intrinsic for this compiler.
|
||||
# error Unknown md_trap intrinsic for this compiler.
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#define assert_msg( cond, msg, ... ) \
|
||||
#define md_assert_msg( cond, msg, ... ) \
|
||||
do \
|
||||
{ \
|
||||
if ( ! ( cond ) ) \
|
||||
{ \
|
||||
assert_handler( #cond, __FILE__, __func__, scast( S64, __LINE__ ), msg, ##__VA_ARGS__ ); \
|
||||
trap(); \
|
||||
md_assert_handler( #cond, __FILE__, __func__, md_scast( MD_S64, __LINE__ ), msg, ##__VA_ARGS__ ); \
|
||||
md_trap(); \
|
||||
} \
|
||||
} while ( 0 )
|
||||
|
||||
#ifndef assert_always
|
||||
#define assert_always(x) do { if ( !(x) ) { trap(); } } while(0)
|
||||
#ifndef md_assert_always
|
||||
#define md_assert_always(x) do { if ( !(x) ) { md_trap(); } } while(0)
|
||||
#endif
|
||||
|
||||
#ifndef assert
|
||||
# if BUILD_DEBUG
|
||||
# define assert(x) assert_always(x)
|
||||
#ifndef md_assert
|
||||
# if MD_BUILD_DEBUG
|
||||
# define md_assert(x) md_assert_always(x)
|
||||
# else
|
||||
# define assert(x) (void)(x)
|
||||
# define md_assert(x) (void)(x)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef invalid_path
|
||||
#define invalid_path assert( ! "Invalid Path!")
|
||||
#ifndef md_invalid_path
|
||||
#define md_invalid_path md_assert( ! "Invalid Path!")
|
||||
#endif
|
||||
#ifndef not_implemented
|
||||
#define not_implemented assert( ! "Not Implemented!")
|
||||
#ifndef md_not_implemented
|
||||
#define md_not_implemented md_assert( ! "Not Implemented!")
|
||||
#endif
|
||||
#ifndef no_op
|
||||
#define no_op ((void)0)
|
||||
#ifndef md_no_op
|
||||
#define md_no_op ((void)0)
|
||||
#endif
|
||||
#ifndef md_static_assert
|
||||
#define md_static_assert(C, ID) global U8 glue(ID, __LINE__)[ (C) ? 1 : -1 ]
|
||||
#define md_static_assert(C, ID) md_global MD_U8 md_glue(ID, __LINE__)[ (C) ? 1 : -1 ]
|
||||
#endif
|
||||
|
||||
MD_API void assert_handler( char const* condition, char const* file, char const* function, S32 line, char const* msg, ... );
|
||||
MD_API void md_assert_handler( char const* condition, char const* file, char const* function, MD_S32 line, char const* msg, ... );
|
||||
|
||||
+16
-16
@@ -9,39 +9,39 @@
|
||||
// Copyright (c) 2024 Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
void main_thread_base_entry_point(MainThread_EntryPointProc* entry_point, char** arguments, U64 arguments_count)
|
||||
void md_main_thread_base_entry_point(MD_MainThread_EntryPointProc* md_entry_point, char** arguments, MD_U64 arguments_count)
|
||||
{
|
||||
#if PROFILE_TELEMETRY
|
||||
local_persist U8 tm_data[MB(64)];
|
||||
#if MD_PROFILE_TELEMETRY
|
||||
md_local_persist MD_U8 tm_data[MD_MB(64)];
|
||||
tmLoadLibrary(TM_RELEASE);
|
||||
tmSetMaxThreadCount(256);
|
||||
tmInitialize(sizeof(tm_data), (char *)tm_data);
|
||||
#endif
|
||||
thread_namef("[main thread]");
|
||||
md_thread_namef("[main thread]");
|
||||
|
||||
TempArena scratch = scratch_begin(0, 0);
|
||||
MD_TempArena scratch = md_scratch_begin(0, 0);
|
||||
|
||||
String8List command_line_argument_strings = os_string_list_from_argcv(scratch.arena, (int)arguments_count, arguments);
|
||||
CmdLine cmdline = cmd_line_from_string_list(scratch.arena, command_line_argument_strings);
|
||||
B32 capture = cmd_line_has_flag(&cmdline, str8_lit("capture"));
|
||||
MD_String8List command_line_argument_strings = md_os_string_list_from_argcv(scratch.arena, (int)arguments_count, arguments);
|
||||
MD_CmdLine cmdline = md_cmd_line_from_string_list(scratch.arena, command_line_argument_strings);
|
||||
MD_B32 capture = md_cmd_line_has_flag(&cmdline, md_str8_lit("capture"));
|
||||
if (capture) {
|
||||
prof_begin_capture(arguments[0]);
|
||||
md_prof_begin_capture(arguments[0]);
|
||||
}
|
||||
|
||||
entry_point(&cmdline);
|
||||
md_entry_point(&cmdline);
|
||||
|
||||
if (capture) {
|
||||
prof_end_capture();
|
||||
md_prof_end_capture();
|
||||
}
|
||||
|
||||
scratch_end(scratch);
|
||||
}
|
||||
|
||||
void
|
||||
supplement_thread_base_entry_point(SupplementThread_EntryPointProc* entry_point, void* params)
|
||||
md_supplement_thread_base_entry_point(MD_SupplementThread_EntryPointProc* md_entry_point, void* params)
|
||||
{
|
||||
TCTX tctx;
|
||||
tctx_init_and_equip(&tctx);
|
||||
entry_point(params);
|
||||
tctx_release();
|
||||
MD_TCTX md_tctx;
|
||||
md_tctx_init_and_equip(&md_tctx);
|
||||
md_entry_point(params);
|
||||
md_tctx_release();
|
||||
}
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
// Copyright (c) 2024 Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
typedef void (MainThread_EntryPointProc) (CmdLine* cmd_line);
|
||||
typedef void (SupplementThread_EntryPointProc)(void* params);
|
||||
typedef void (MD_MainThread_EntryPointProc) (MD_CmdLine* cmd_line);
|
||||
typedef void (MD_SupplementThread_EntryPointProc)(void* params);
|
||||
|
||||
MD_API void main_thread_base_entry_point (MainThread_EntryPointProc* entry_point, char** arguments, U64 arguments_count);
|
||||
MD_API void supplement_thread_base_entry_point(SupplementThread_EntryPointProc* entry_point, void* params);
|
||||
MD_API void md_main_thread_base_entry_point (MD_MainThread_EntryPointProc* md_entry_point, char** arguments, MD_U64 arguments_count);
|
||||
MD_API void md_supplement_thread_base_entry_point(MD_SupplementThread_EntryPointProc* md_entry_point, void* params);
|
||||
|
||||
+8
-8
@@ -7,17 +7,17 @@
|
||||
////////////////////////////////
|
||||
//~ allen: Files
|
||||
|
||||
typedef U32 FilePropertyFlags;
|
||||
typedef MD_U32 MD_FilePropertyFlags;
|
||||
enum
|
||||
{
|
||||
FilePropertyFlag_IsFolder = (1 << 0),
|
||||
MD_FilePropertyFlag_IsFolder = (1 << 0),
|
||||
};
|
||||
|
||||
typedef struct FileProperties FileProperties;
|
||||
struct FileProperties
|
||||
typedef struct MD_FileProperties MD_FileProperties;
|
||||
struct MD_FileProperties
|
||||
{
|
||||
U64 size;
|
||||
DenseTime modified;
|
||||
DenseTime created;
|
||||
FilePropertyFlags flags;
|
||||
MD_U64 size;
|
||||
MD_DenseTime modified;
|
||||
MD_DenseTime created;
|
||||
MD_FilePropertyFlags flags;
|
||||
};
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
#ifdef INTELLISENSE_DIRECTIVES
|
||||
# pragma once
|
||||
// NOTE(Ed): For C++ generation, this file will not be injected, any macros that are used will either be injected as transparent defines
|
||||
// or have their usage removed during the library generation pass.
|
||||
#endif
|
||||
|
||||
// ____ _ ______ _ _ ____ _ __ _
|
||||
@@ -19,42 +17,42 @@
|
||||
// Additional info: https://www.chiark.greenend.org.uk/~sgtatham/quasiblog/c11-generic/
|
||||
// --------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
#ifndef COMMA_OPERATOR
|
||||
#define COMMA_OPERATOR , // The comma operator is used by preprocessor macros to delimit arguments, so we have to represent it via a macro to prevent parsing incorrectly.
|
||||
#ifndef MD_COMMA_OPERATOR
|
||||
#define MD_COMMA_OPERATOR , // The comma operator is used by preprocessor macros to delimit arguments, so we have to represent it via a macro to prevent parsing incorrectly.
|
||||
#endif
|
||||
|
||||
// Helper macros for argument selection
|
||||
#ifndef select_arg_1
|
||||
#define select_arg_1( _1, ... ) _1 // <-- Of all th args passed pick _1.
|
||||
#define select_arg_2( _1, _2, ... ) _2 // <-- Of all the args passed pick _2.
|
||||
#define select_arg_3( _1, _2, _3, ... ) _3 // etc..
|
||||
#ifndef md_select_arg_1
|
||||
#define md_select_arg_1( _1, ... ) _1 // <-- Of all th args passed pick _1.
|
||||
#define md_select_arg_2( _1, _2, ... ) _2 // <-- Of all the args passed pick _2.
|
||||
#define md_select_arg_3( _1, _2, _3, ... ) _3 // etc..
|
||||
|
||||
#define generic_sel_entry_type select_arg_1 // Use the arg expansion macro to select arg 1 which should have the type.
|
||||
#define generic_sel_entry_function select_arg_2 // Use the arg expansion macro to select arg 2 which should have the function.
|
||||
#define generic_sel_entry_comma_delimiter select_arg_3 // Use the arg expansion macro to select arg 3 which should have the comma delimiter ','.
|
||||
#define md_generic_sel_entry_type md_select_arg_1 // Use the arg expansion macro to select arg 1 which should have the type.
|
||||
#define md_generic_sel_entry_function md_select_arg_2 // Use the arg expansion macro to select arg 2 which should have the function.
|
||||
#define md_generic_sel_entry_comma_delimiter md_select_arg_3 // Use the arg expansion macro to select arg 3 which should have the comma delimiter ','.
|
||||
#endif
|
||||
|
||||
#ifndef generic_call
|
||||
#define generic_call // Just used to indicate where the call "occurs"
|
||||
#ifndef md_generic_call
|
||||
#define md_generic_call // Just used to indicate where the call "occurs"
|
||||
#endif
|
||||
|
||||
// ----------------------------------------------------------------------------------------------------------------------------------
|
||||
#ifndef if_generic_selector_defined_include_slot
|
||||
// if_generic_selector_defined_include_slot( macro ) includes a _Generic slot only if the specified macro is defined (as type, function_name).
|
||||
#ifndef md_if_generic_selector_defined_include_slot
|
||||
// md_if_generic_selector_defined_include_slot( macro ) includes a _Generic slot only if the specified macro is defined (as type, function_name).
|
||||
// It takes advantage of the fact that if the macro is defined, then the expanded text will contain a comma.
|
||||
// Expands to ',' if it can find (type): (function) <comma_operator: ',' >
|
||||
// Where generic_sel_entry_comma_delimiter is specifically looking for that <comma> ,
|
||||
#define if_generic_selector_defined_include_slot( slot_exp ) generic_sel_entry_comma_delimiter( slot_exp, generic_sel_entry_type( slot_exp, ): generic_sel_entry_function( slot_exp, ) COMMA_OPERATOR, , )
|
||||
// Where md_generic_sel_entry_comma_delimiter is specifically looking for that <comma> ,
|
||||
#define md_if_generic_selector_defined_include_slot( slot_exp ) md_generic_sel_entry_comma_delimiter( slot_exp, md_generic_sel_entry_type( slot_exp, ): md_generic_sel_entry_function( slot_exp, ) MD_COMMA_OPERATOR, , )
|
||||
// ^ Selects the comma ^ is the type ^ is the function ^ Insert a comma
|
||||
// The slot won't exist if that comma is not found.
|
||||
#endif
|
||||
|
||||
// For the occastion where an expression didn't resolve to a selection option the "default: <value>" will be set to:
|
||||
typedef struct UNRESOLVED_GENERIC_SELECTION UNRESOLVED_GENERIC_SELECTION;
|
||||
struct UNRESOLVED_GENERIC_SELECTION {
|
||||
typedef struct MD_UNRESOLVED_GENERIC_SELECTION MD_UNRESOLVED_GENERIC_SELECTION;
|
||||
struct MD_UNRESOLVED_GENERIC_SELECTION {
|
||||
void* _THE_VOID_SLOT_;
|
||||
};
|
||||
UNRESOLVED_GENERIC_SELECTION const assert_generic_sel_fail = {0};
|
||||
MD_UNRESOLVED_GENERIC_SELECTION const md_assert_generic_sel_fail = {0};
|
||||
// Which will provide the message: error: called object type 'struct NO_RESOLVED_GENERIC_SELECTION' is not a function or function pointer
|
||||
// ----------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -63,10 +61,10 @@ UNRESOLVED_GENERIC_SELECTION const assert_generic_sel_fail = {0};
|
||||
#define function_generic_example( selector_arg ) _Generic( \
|
||||
(selector_arg), /* Select Via Expression*/ \
|
||||
/* Extendibility slots: */ \
|
||||
if_generic_selector_defined_include_slot( GENERIC_SLOT_1__function_sig ) \
|
||||
if_generic_selector_defined_include_slot( GENERIC_SLOT_2__function_sig ) \
|
||||
default: assert_generic_sel_fail \
|
||||
) generic_call( selector_arg )
|
||||
md_if_generic_selector_defined_include_slot( MD_GENERIC_SLOT_1__function_sig ) \
|
||||
md_if_generic_selector_defined_include_slot( GENERIC_SLOT_2__function_sig ) \
|
||||
default: md_assert_generic_sel_fail \
|
||||
) md_generic_call( selector_arg )
|
||||
// ----------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
// Then each definiton of a function has an associated define:
|
||||
@@ -78,56 +76,56 @@ UNRESOLVED_GENERIC_SELECTION const assert_generic_sel_fail = {0};
|
||||
// Concrete example:
|
||||
|
||||
// To add support for long:
|
||||
#define GENERIC_SLOT_1__example_hash long, generic_example_hash__P_long
|
||||
size_t generic_example_hash__P_long( long val ) { return val * 2654435761ull; }
|
||||
#define MD_GENERIC_SLOT_1__example_hash long, md_generic_example_hash__P_long
|
||||
size_t md_generic_example_hash__P_long( long val ) { return val * 2654435761ull; }
|
||||
|
||||
// To add support for long long:
|
||||
#define GENERIC_SLOT_2__example_hash long long, generic_example_hash__P_long_long
|
||||
size_t generic_example_hash__P_long_long( long long val ) { return val * 2654435761ull; }
|
||||
#define GENERIC_SLOT_2__example_hash long long, md_generic_example_hash__P_long_long
|
||||
size_t md_generic_example_hash__P_long_long( long long val ) { return val * 2654435761ull; }
|
||||
|
||||
// If using an Editor with support for syntax hightlighting macros:
|
||||
// GENERIC_SLOT_1__example_hash and GENERIC_SLOT_2__example_hash should show color highlighting indicating the slot is enabled,
|
||||
// MD_GENERIC_SLOT_1__example_hash and GENERIC_SLOT_2__example_hash should show color highlighting indicating the slot is enabled,
|
||||
// or, "defined" for usage during the compilation pass that handles the _Generic instrinsic.
|
||||
#define generic_example_hash( function_arguments ) _Generic( \
|
||||
(function_arguments), /* Select Via Expression*/ \
|
||||
/* Extendibility slots: */ \
|
||||
if_generic_selector_defined_include_slot( GENERIC_SLOT_1__example_hash ) \
|
||||
if_generic_selector_defined_include_slot( GENERIC_SLOT_2__example_hash ) \
|
||||
if_generic_selector_defined_include_slot( GENERIC_SLOT_3__example_hash ) \
|
||||
if_generic_selector_defined_include_slot( GENERIC_SLOT_4__example_hash ) \
|
||||
if_generic_selector_defined_include_slot( GENERIC_SLOT_5__example_hash ) \
|
||||
if_generic_selector_defined_include_slot( GENERIC_SLOT_6__example_hash ) \
|
||||
if_generic_selector_defined_include_slot( GENERIC_SLOT_7__example_hash ) \
|
||||
if_generic_selector_defined_include_slot( GENERIC_SLOT_8__example_hash ) \
|
||||
default: assert_generic_sel_fail \
|
||||
) generic_call( function_arguments )
|
||||
md_if_generic_selector_defined_include_slot( MD_GENERIC_SLOT_1__example_hash ) \
|
||||
md_if_generic_selector_defined_include_slot( GENERIC_SLOT_2__example_hash ) \
|
||||
md_if_generic_selector_defined_include_slot( GENERIC_SLOT_3__example_hash ) \
|
||||
md_if_generic_selector_defined_include_slot( GENERIC_SLOT_4__example_hash ) \
|
||||
md_if_generic_selector_defined_include_slot( GENERIC_SLOT_5__example_hash ) \
|
||||
md_if_generic_selector_defined_include_slot( GENERIC_SLOT_6__example_hash ) \
|
||||
md_if_generic_selector_defined_include_slot( GENERIC_SLOT_7__example_hash ) \
|
||||
md_if_generic_selector_defined_include_slot( GENERIC_SLOT_8__example_hash ) \
|
||||
default: md_assert_generic_sel_fail \
|
||||
) md_generic_call( function_arguments )
|
||||
|
||||
// Additional Variations:
|
||||
|
||||
// If the function takes more than one argument the following is used:
|
||||
#define function_generic_example_varadic( selector_arg, ... ) _Generic( \
|
||||
#define md_function_generic_example_varadic( selector_arg, ... ) _Generic( \
|
||||
(selector_arg), \
|
||||
if_generic_selector_defined_include_slot( GENERIC_SLOT_1__function_sig ) \
|
||||
if_generic_selector_defined_include_slot( GENERIC_SLOT_2__function_sig ) \
|
||||
md_if_generic_selector_defined_include_slot( MD_GENERIC_SLOT_1__function_sig ) \
|
||||
md_if_generic_selector_defined_include_slot( GENERIC_SLOT_2__function_sig ) \
|
||||
/* ... */ \
|
||||
if_generic_selector_defined_include_slot(GENERIC_SLOT_N__function_sig ) \
|
||||
default: assert_generic_sel_fail \
|
||||
) generic_call( selector_arg, __VA_ARG__ )
|
||||
md_if_generic_selector_defined_include_slot(GENERIC_SLOT_N__function_sig ) \
|
||||
default: md_assert_generic_sel_fail \
|
||||
) md_generic_call( selector_arg, __VA_ARG__ )
|
||||
|
||||
// If the function does not take the arugment as a parameter:
|
||||
#define function_generic_example_direct_type( selector_arg ) _Generic( \
|
||||
( type_to_expression(selector_arg) ), \
|
||||
if_generic_selector_defined_include_slot( GENERIC_SLOT_1__function_sig ) \
|
||||
if_generic_selector_defined_include_slot( GENERIC_SLOT_2__function_sig ) \
|
||||
#define md_function_generic_example_direct_type( selector_arg ) _Generic( \
|
||||
( md_type_to_expression(selector_arg) ), \
|
||||
md_if_generic_selector_defined_include_slot( MD_GENERIC_SLOT_1__function_sig ) \
|
||||
md_if_generic_selector_defined_include_slot( GENERIC_SLOT_2__function_sig ) \
|
||||
/* ... */ \
|
||||
if_generic_selector_defined_include_slot(GENERIC_SLOT_N__function_sig ) \
|
||||
default: assert_generic_sel_fail \
|
||||
) generic_call(selector_arg)
|
||||
md_if_generic_selector_defined_include_slot(GENERIC_SLOT_N__function_sig ) \
|
||||
default: md_assert_generic_sel_fail \
|
||||
) md_generic_call(selector_arg)
|
||||
|
||||
|
||||
#ifndef type_to_expression
|
||||
#ifndef md_type_to_expression
|
||||
// Used to keep the _Generic keyword happy as bare types are not considered "expressions"
|
||||
#define type_to_expression(type) (* (type*)NULL)
|
||||
#define md_type_to_expression(type) (* (type*)NULL)
|
||||
// Instead of using this macro, it should be directly expanded by code generation.
|
||||
#endif
|
||||
|
||||
@@ -136,14 +134,14 @@ size_t generic_example_hash__P_long_long( long long val ) { return val * 2654435
|
||||
|
||||
#define example_with__l2(expr) _Generic( \
|
||||
(expr), \
|
||||
S64 : example_with_s64, \
|
||||
default: assert_generic_sel_fail \
|
||||
MD_S64 : example_with_s64, \
|
||||
default: md_assert_generic_sel_fail \
|
||||
)
|
||||
#define example_with(expr) \
|
||||
_Generic((expr), \
|
||||
SSIZE : example_with_SSIZEZ \
|
||||
MD_SSIZE : example_with_SSIZEZ \
|
||||
default : example_with_not_SSIZE(allocator, in) \
|
||||
) generic_call(allocator, in)
|
||||
) md_generic_call(allocator, in)
|
||||
|
||||
// This can be made more concise with he following "layer" indicating _Generic macros
|
||||
|
||||
@@ -152,21 +150,21 @@ _Generic((expr), \
|
||||
|
||||
#define example_with_generic_layers(expr) \
|
||||
_Generic( (expr), \
|
||||
S64 : example_with_s64, \
|
||||
MD_S64 : example_with_s64, \
|
||||
_Generic_L2((expr), \
|
||||
SSIZE: example_with_SSIZZE \
|
||||
default: assert_generic_sel_fail \
|
||||
MD_SSIZE: example_with_SSIZZE \
|
||||
default: md_assert_generic_sel_fail \
|
||||
), \
|
||||
) generic_call(expr)
|
||||
) md_generic_call(expr)
|
||||
|
||||
// Removing example definitions
|
||||
#undef example_with
|
||||
#undef example_with__l2
|
||||
#undef example_with_generic_layers
|
||||
#undef function_generic_example
|
||||
#undef GENERIC_SLOT_1__example_hash
|
||||
#undef MD_GENERIC_SLOT_1__example_hash
|
||||
#undef GENERIC_SLOT_2__example_hash
|
||||
#undef generic_example_hash
|
||||
#undef function_generic_example_varadic
|
||||
#undef function_generic_example_direct_type
|
||||
#undef md_function_generic_example_varadic
|
||||
#undef md_function_generic_example_direct_type
|
||||
#undef generic_example_do_something_with
|
||||
|
||||
+11
-11
@@ -4,9 +4,9 @@
|
||||
#endif
|
||||
|
||||
#ifndef MD_API
|
||||
#if COMPILER_MSVC
|
||||
# if BUILD_DYANMIC
|
||||
# if BUILD_API_EXPORT
|
||||
#if MD_COMPILER_MSVC
|
||||
# if MD_BUILD_DYANMIC
|
||||
# if MD_BUILD_API_EXPORT
|
||||
# define MD_API __declspec(dllexport)
|
||||
# else
|
||||
# define MD_API __declspec(dllimport)
|
||||
@@ -15,7 +15,7 @@
|
||||
# define MD_API // Empty for static builds
|
||||
# endif
|
||||
#else
|
||||
# ifdef BUILD_DYANMIC
|
||||
# ifdef MD_BUILD_DYANMIC
|
||||
# define MD_API __attribute__((visibility("default")))
|
||||
# else
|
||||
# define MD_API // Empty for static builds
|
||||
@@ -24,7 +24,7 @@
|
||||
#endif // GEN_API
|
||||
|
||||
#ifndef MD_API_C_BEGIN
|
||||
# if LANG_C
|
||||
# if MD_LANG_C
|
||||
# define MD_API_C_BEGIN
|
||||
# define MD_API_C_END
|
||||
# define MD_API_C
|
||||
@@ -35,15 +35,15 @@
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef global // Global variables
|
||||
# if BUILD_API_EXPORT || BUILD_STATIC
|
||||
# define global
|
||||
#ifndef md_global // Global variables
|
||||
# if MD_BUILD_API_EXPORT || MD_BUILD_STATIC
|
||||
# define md_global
|
||||
# else
|
||||
# define global static
|
||||
# define md_global static
|
||||
# endif
|
||||
#endif
|
||||
|
||||
// Internal Linkage
|
||||
#ifndef internal
|
||||
#define internal static
|
||||
#ifndef md_internal
|
||||
#define md_internal static
|
||||
#endif
|
||||
|
||||
+34
-34
@@ -9,40 +9,40 @@
|
||||
////////////////////////////////
|
||||
//~ rjf: Globals/Thread-Locals
|
||||
|
||||
MD_API_C thread_static Log* log_active;
|
||||
#if !BUILD_SUPPLEMENTARY_UNIT
|
||||
MD_API_C thread_static Log* log_active = 0;
|
||||
MD_API_C md_thread_static MD_Log* md_log_active;
|
||||
#if !MD_BUILD_SUPPLEMENTARY_UNIT
|
||||
MD_API_C md_thread_static MD_Log* md_log_active = 0;
|
||||
#endif
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Log Creation/Selection
|
||||
//~ rjf: MD_Log Creation/Selection
|
||||
|
||||
void
|
||||
log_select(Log* log) {
|
||||
log_active = log;
|
||||
md_log_select(MD_Log* log) {
|
||||
md_log_active = log;
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Log Building
|
||||
//~ rjf: MD_Log Building
|
||||
|
||||
void
|
||||
log_msg(LogMsgKind kind, String8 string) {
|
||||
if(log_active != 0 && log_active->top_scope != 0) {
|
||||
String8 string_copy = str8_copy(log_active->arena, string);
|
||||
str8_list_push(log_active->arena, &log_active->top_scope->strings[kind], string_copy);
|
||||
md_log_msg(MD_LogMsgKind kind, MD_String8 string) {
|
||||
if(md_log_active != 0 && md_log_active->top_scope != 0) {
|
||||
MD_String8 md_string_copy = md_str8_copy(md_log_active->arena, string);
|
||||
md_str8_list_push(md_log_active->arena, &md_log_active->top_scope->strings[kind], md_string_copy);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
log_msgf(LogMsgKind kind, char *fmt, ...) {
|
||||
if(log_active != 0)
|
||||
md_log_msgf(MD_LogMsgKind kind, char *fmt, ...) {
|
||||
if(md_log_active != 0)
|
||||
{
|
||||
TempArena scratch = scratch_begin(0, 0);
|
||||
MD_TempArena scratch = md_scratch_begin(0, 0);
|
||||
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
String8 string = str8fv(scratch.arena, fmt, args);
|
||||
log_msg(kind, string);
|
||||
MD_String8 string = md_str8fv(scratch.arena, fmt, args);
|
||||
md_log_msg(kind, string);
|
||||
va_end(args);
|
||||
|
||||
scratch_end(scratch);
|
||||
@@ -50,39 +50,39 @@ log_msgf(LogMsgKind kind, char *fmt, ...) {
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Log Scopes
|
||||
//~ rjf: MD_Log Scopes
|
||||
|
||||
void
|
||||
log_scope_begin(void) {
|
||||
if (log_active != 0) {
|
||||
U64 pos = arena_pos(log_active->arena);
|
||||
LogScope* scope = push_array(log_active->arena, LogScope, 1);
|
||||
md_log_scope_begin(void) {
|
||||
if (md_log_active != 0) {
|
||||
MD_U64 pos = md_arena_pos(md_log_active->arena);
|
||||
MD_LogScope* scope = md_push_array_(md_log_active->arena, MD_LogScope, 1);
|
||||
scope->pos = pos;
|
||||
sll_stack_push(log_active->top_scope, scope);
|
||||
md_sll_stack_push(md_log_active->top_scope, scope);
|
||||
}
|
||||
}
|
||||
|
||||
LogScopeResult
|
||||
log_scope_end(Arena *arena)
|
||||
MD_LogScopeResult
|
||||
md_log_scope_end(MD_Arena *arena)
|
||||
{
|
||||
LogScopeResult result = {0};
|
||||
if(log_active != 0)
|
||||
MD_LogScopeResult result = {0};
|
||||
if(md_log_active != 0)
|
||||
{
|
||||
LogScope* scope = log_active->top_scope;
|
||||
MD_LogScope* scope = md_log_active->top_scope;
|
||||
if(scope != 0)
|
||||
{
|
||||
sll_stack_pop(log_active->top_scope);
|
||||
md_sll_stack_pop(md_log_active->top_scope);
|
||||
if(arena != 0)
|
||||
{
|
||||
for (each_enum_val(LogMsgKind, kind)) {
|
||||
TempArena scratch = scratch_begin(&arena, 1);
|
||||
String8
|
||||
result_unindented = str8_list_join(scratch.arena, &scope->strings[kind], 0);
|
||||
result.strings[kind] = indented_from_string(arena, result_unindented);
|
||||
for (md_each_enum_val(MD_LogMsgKind, kind)) {
|
||||
MD_TempArena scratch = md_scratch_begin(&arena, 1);
|
||||
MD_String8
|
||||
result_unindented = md_str8_list_join(scratch.arena, &scope->strings[kind], 0);
|
||||
result.strings[kind] = md_indented_from_string(arena, result_unindented);
|
||||
scratch_end(scratch);
|
||||
}
|
||||
}
|
||||
arena_pop_to(log_active->arena, scope->pos);
|
||||
md_arena_pop_to(md_log_active->arena, scope->pos);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
||||
+43
-43
@@ -10,77 +10,77 @@
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Log Types
|
||||
//~ rjf: MD_Log Types
|
||||
|
||||
typedef enum LogMsgKind LogMsgKind;
|
||||
enum LogMsgKind
|
||||
typedef enum MD_LogMsgKind MD_LogMsgKind;
|
||||
enum MD_LogMsgKind
|
||||
{
|
||||
LogMsgKind_Info,
|
||||
LogMsgKind_UserError,
|
||||
LogMsgKind_COUNT
|
||||
MD_LogMsgKind_Info,
|
||||
MD_LogMsgKind_UserError,
|
||||
MD_LogMsgKind_COUNT
|
||||
};
|
||||
|
||||
typedef struct LogScope LogScope;
|
||||
struct LogScope
|
||||
typedef struct MD_LogScope MD_LogScope;
|
||||
struct MD_LogScope
|
||||
{
|
||||
LogScope* next;
|
||||
U64 pos;
|
||||
String8List strings[LogMsgKind_COUNT];
|
||||
MD_LogScope* next;
|
||||
MD_U64 pos;
|
||||
MD_String8List strings[MD_LogMsgKind_COUNT];
|
||||
};
|
||||
|
||||
typedef struct LogScopeResult LogScopeResult;
|
||||
struct LogScopeResult
|
||||
typedef struct MD_LogScopeResult MD_LogScopeResult;
|
||||
struct MD_LogScopeResult
|
||||
{
|
||||
String8 strings[LogMsgKind_COUNT];
|
||||
MD_String8 strings[MD_LogMsgKind_COUNT];
|
||||
};
|
||||
|
||||
typedef struct Log Log;
|
||||
struct Log
|
||||
typedef struct MD_Log MD_Log;
|
||||
struct MD_Log
|
||||
{
|
||||
Arena* arena;
|
||||
LogScope* top_scope;
|
||||
MD_Arena* arena;
|
||||
MD_LogScope* top_scope;
|
||||
};
|
||||
|
||||
#ifndef LOG_DEFAULT_ARENA_BLOCK_SIZE
|
||||
#define LOG_DEFAULT_ARENA_BLOCK_SIZE VARENA_DEFAULT_RESERVE
|
||||
#ifndef MD_LOG_DEFAULT_ARENA_BLOCK_SIZE
|
||||
#define MD_LOG_DEFAULT_ARENA_BLOCK_SIZE MD_VARENA_DEFAULT_RESERVE
|
||||
#endif
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Log Creation/Selection
|
||||
//~ rjf: MD_Log Creation/Selection
|
||||
|
||||
Log* log_alloc(AllocatorInfo ainfo, U64 arena_block_size);
|
||||
void log_release(Log* log);
|
||||
MD_API void log_select (Log* log);
|
||||
MD_Log* md_log_alloc(MD_AllocatorInfo ainfo, MD_U64 md_arena_block_size);
|
||||
void md_log_release(MD_Log* log);
|
||||
MD_API void md_log_select (MD_Log* log);
|
||||
|
||||
inline Log*
|
||||
log_alloc(AllocatorInfo ainfo, U64 arena_block_size) {
|
||||
if (arena_block_size == 0) {
|
||||
arena_block_size = LOG_DEFAULT_ARENA_BLOCK_SIZE;
|
||||
inline MD_Log*
|
||||
md_log_alloc(MD_AllocatorInfo ainfo, MD_U64 md_arena_block_size) {
|
||||
if (md_arena_block_size == 0) {
|
||||
md_arena_block_size = MD_LOG_DEFAULT_ARENA_BLOCK_SIZE;
|
||||
}
|
||||
Arena* arena = arena_alloc(.backing = ainfo, .block_size = arena_block_size);
|
||||
Log* log = push_array(arena, Log, 1);
|
||||
MD_Arena* arena = md_arena_alloc(.backing = ainfo, .block_size = md_arena_block_size);
|
||||
MD_Log* log = md_push_array_(arena, MD_Log, 1);
|
||||
log->arena = arena;
|
||||
return log;
|
||||
}
|
||||
|
||||
inline void log_release(Log* log) { arena_release(log->arena); }
|
||||
inline void md_log_release(MD_Log* log) { md_arena_release(log->arena); }
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Log Building
|
||||
//~ rjf: MD_Log Building
|
||||
|
||||
MD_API void log_msg (LogMsgKind kind, String8 string);
|
||||
MD_API void log_msgf(LogMsgKind kind, char* fmt, ...);
|
||||
MD_API void md_log_msg (MD_LogMsgKind kind, MD_String8 string);
|
||||
MD_API void md_log_msgf(MD_LogMsgKind kind, char* fmt, ...);
|
||||
|
||||
#define log_info(s) log_msg (LogMsgKind_Info, (s))
|
||||
#define log_infof(fmt, ...) log_msgf(LogMsgKind_Info, (fmt), __VA_ARGS__)
|
||||
#define log_user_error(s) log_msg (LogMsgKind_UserError, (s))
|
||||
#define log_user_errorf(fmt, ...) log_msgf(LogMsgKind_UserError, (fmt), __VA_ARGS__)
|
||||
#define md_log_info(s) md_log_msg (MD_LogMsgKind_Info, (s))
|
||||
#define md_log_infof(fmt, ...) md_log_msgf(MD_LogMsgKind_Info, (fmt), __VA_ARGS__)
|
||||
#define md_log_user_error(s) md_log_msg (MD_LogMsgKind_UserError, (s))
|
||||
#define md_log_user_errorf(fmt, ...) md_log_msgf(MD_LogMsgKind_UserError, (fmt), __VA_ARGS__)
|
||||
|
||||
#define log_info_named_block(s) defer_loop(log_infof("%S:\n{\n", (s)), log_infof("}\n"))
|
||||
#define log_info_named_blockf(fmt, ...) defer_loop((log_infof(fmt, __VA_ARGS__), log_infof(":\n{\n")), log_infof("}\n"))
|
||||
#define md_log_info_named_block(s) md_defer_loop(md_log_infof("%S:\n{\n", (s)), md_log_infof("}\n"))
|
||||
#define md_log_info_named_blockf(fmt, ...) md_defer_loop((md_log_infof(fmt, __VA_ARGS__), md_log_infof(":\n{\n")), md_log_infof("}\n"))
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Log Scopes
|
||||
//~ rjf: MD_Log Scopes
|
||||
|
||||
void log_scope_begin(void);
|
||||
MD_API LogScopeResult log_scope_end(Arena* arena);
|
||||
void md_log_scope_begin(void);
|
||||
MD_API MD_LogScopeResult md_log_scope_end(MD_Arena* arena);
|
||||
|
||||
+79
-79
@@ -7,71 +7,71 @@
|
||||
////////////////////////////////
|
||||
//~ rjf: Branch Predictor Hints
|
||||
|
||||
#if COMPILER_CLANG
|
||||
# define expect(expr, val) __builtin_expect((expr), (val))
|
||||
#if MD_COMPILER_CLANG
|
||||
# define md_expect(expr, val) __builtin_expect((expr), (val))
|
||||
#else
|
||||
# define expect(expr, val) (expr)
|
||||
# define md_expect(expr, val) (expr)
|
||||
#endif
|
||||
|
||||
#define likely(expr) expect(expr, 1)
|
||||
#define unlikely(expr) expect(expr, 0)
|
||||
#define md_likely(expr) md_expect(expr, 1)
|
||||
#define md_unlikely(expr) md_expect(expr, 0)
|
||||
|
||||
////////////////////////////////
|
||||
//~ erg: type casting
|
||||
|
||||
#if LANG_CPP
|
||||
# ifndef ccast
|
||||
# define ccast( type, value ) ( const_cast< type >( (value) ) )
|
||||
#if MD_LANG_CPP
|
||||
# ifndef md_ccast
|
||||
# define md_ccast( type, value ) ( const_cast< type >( (value) ) )
|
||||
# endif
|
||||
# ifndef pcast
|
||||
# define pcast( type, value ) ( * reinterpret_cast< type* >( & ( value ) ) )
|
||||
# ifndef md_pcast
|
||||
# define md_pcast( type, value ) ( * reinterpret_cast< type* >( & ( value ) ) )
|
||||
# endif
|
||||
# ifndef rcast
|
||||
# define rcast( type, value ) reinterpret_cast< type >( value )
|
||||
# ifndef md_rcast
|
||||
# define md_rcast( type, value ) reinterpret_cast< type >( value )
|
||||
# endif
|
||||
# ifndef scast
|
||||
# define scast( type, value ) static_cast< type >( value )
|
||||
# ifndef md_scast
|
||||
# define md_scast( type, value ) static_cast< type >( value )
|
||||
# endif
|
||||
#else
|
||||
# ifndef ccast
|
||||
# define ccast( type, value ) ( (type)(value) )
|
||||
# ifndef md_ccast
|
||||
# define md_ccast( type, value ) ( (type)(value) )
|
||||
# endif
|
||||
# ifndef pcast
|
||||
# define pcast( type, value ) ( * (type*)(& value) )
|
||||
# ifndef md_pcast
|
||||
# define md_pcast( type, value ) ( * (type*)(& value) )
|
||||
# endif
|
||||
# ifndef rcast
|
||||
# define rcast( type, value ) ( (type)(value) )
|
||||
# ifndef md_rcast
|
||||
# define md_rcast( type, value ) ( (type)(value) )
|
||||
# endif
|
||||
# ifndef scast
|
||||
# define scast( type, value ) ( (type)(value) )
|
||||
# ifndef md_scast
|
||||
# define md_scast( type, value ) ( (type)(value) )
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if ! defined(typeof) && ( ! LANG_C || __STDC_VERSION__ < 202311L)
|
||||
# if ! LANG_C
|
||||
#if ! defined(typeof) && ( ! MD_LANG_C || __STDC_VERSION__ < 202311L)
|
||||
# if ! MD_LANG_C
|
||||
# define typeof decltype
|
||||
# elif defined(_MSC_VER)
|
||||
# define typeof __typeof__
|
||||
# elif defined(__GNUC__) || defined(__clang__)
|
||||
# define typeof __typeof__
|
||||
# else
|
||||
# error "Compiler not supported"
|
||||
# error "MD_Compiler not supported"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if LANG_C
|
||||
#if MD_LANG_C
|
||||
# if __STDC_VERSION__ >= 202311L
|
||||
# define enum_underlying(type) : type
|
||||
# define md_enum_underlying(type) : type
|
||||
# else
|
||||
# define enum_underlying(type)
|
||||
# define md_enum_underlying(type)
|
||||
# endif
|
||||
#else
|
||||
# define enum_underlying(type) : type
|
||||
# define md_enum_underlying(type) : type
|
||||
#endif
|
||||
|
||||
#if LANG_C
|
||||
# ifndef nullptr
|
||||
# define nullptr NULL
|
||||
#if MD_LANG_C
|
||||
# ifndef md_nullptr
|
||||
# define md_nullptr NULL
|
||||
# endif
|
||||
|
||||
# ifndef MD_REMOVE_PTR
|
||||
@@ -79,13 +79,13 @@
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if ! defined(PARAM_DEFAULT) && LANG_CPP
|
||||
# define PARAM_DEFAULT = {}
|
||||
#if ! defined(MD_PARAM_DEFAULT) && MD_LANG_CPP
|
||||
# define MD_PARAM_DEFAULT = {}
|
||||
#else
|
||||
# define PARAM_DEFAULT
|
||||
# define MD_PARAM_DEFAULT
|
||||
#endif
|
||||
|
||||
#if LANG_C
|
||||
#if MD_LANG_C
|
||||
# ifndef static_assert
|
||||
# undef static_assert
|
||||
# if __STDC_VERSION__ >= 201112L
|
||||
@@ -96,86 +96,86 @@
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef force_inline
|
||||
# if COMPILER_MSVC
|
||||
# define force_inline __forceinline
|
||||
# elif COMPILER_GCC
|
||||
# define force_inline inline __attribute__((__always_inline__))
|
||||
# elif COMPILER_CLANG
|
||||
#ifndef md_force_inline
|
||||
# if MD_COMPILER_MSVC
|
||||
# define md_force_inline __forceinline
|
||||
# elif MD_COMPILER_GCC
|
||||
# define md_force_inline inline __attribute__((__always_inline__))
|
||||
# elif MD_COMPILER_CLANG
|
||||
# if __has_attribute(__always_inline__)
|
||||
# define force_inline inline __attribute__((__always_inline__))
|
||||
# define md_force_inline inline __attribute__((__always_inline__))
|
||||
# else
|
||||
# define force_inline
|
||||
# define md_force_inline
|
||||
# endif
|
||||
# else
|
||||
# define force_inline
|
||||
# define md_force_inline
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef never_inline
|
||||
# if COMPILER_MSVC
|
||||
# define never_inline __declspec( noinline )
|
||||
# elif COMPILER_GCC
|
||||
# define never_inline __attribute__( ( __noinline__ ) )
|
||||
# elif COMPILER_CLANG
|
||||
#ifndef md_never_inline
|
||||
# if MD_COMPILER_MSVC
|
||||
# define md_never_inline __declspec( noinline )
|
||||
# elif MD_COMPILER_GCC
|
||||
# define md_never_inline __attribute__( ( __noinline__ ) )
|
||||
# elif MD_COMPILER_CLANG
|
||||
# if __has_attribute(__always_inline__)
|
||||
# define never_inline __attribute__( ( __noinline__ ) )
|
||||
# define md_never_inline __attribute__( ( __noinline__ ) )
|
||||
# else
|
||||
# define never_inline
|
||||
# define md_never_inline
|
||||
# endif
|
||||
# else
|
||||
# define never_inline
|
||||
# define md_never_inline
|
||||
# endif
|
||||
#endif
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: For-Loop Construct Macros
|
||||
|
||||
#ifndef defer_loop
|
||||
#define defer_loop(begin, end) for (int _i_ = ((begin), 0); ! _i_; _i_ += 1, (end))
|
||||
#ifndef md_defer_loop
|
||||
#define md_defer_loop(begin, end) for (int _i_ = ((begin), 0); ! _i_; _i_ += 1, (end))
|
||||
#endif
|
||||
#ifndef defer_loop_checked
|
||||
#define defer_loop_checked(begin, end) for (int _i_ = 2 * ! (begin); (_i_ == 2 ? ((end), 0) : !_i_); _i_ += 1, (end))
|
||||
#ifndef md_defer_loop_checked
|
||||
#define md_defer_loop_checked(begin, end) for (int _i_ = 2 * ! (begin); (_i_ == 2 ? ((end), 0) : !_i_); _i_ += 1, (end))
|
||||
#endif
|
||||
|
||||
#ifndef each_enum_val
|
||||
#define each_enum_val(type, it) type it = (type) 0; it < type ## _COUNT; it = (type)( it + 1 )
|
||||
#ifndef md_each_enum_val
|
||||
#define md_each_enum_val(type, it) type it = (type) 0; it < type ## _COUNT; it = (type)( it + 1 )
|
||||
#endif
|
||||
#ifndef each_non_zero_enum_val
|
||||
#define each_non_zero_enum_val(type, it) type it = (type) 1; it < type ## _COUNT; it = (type)( it + 1 )
|
||||
#ifndef md_each_non_zero_enum_val
|
||||
#define md_each_non_zero_enum_val(type, it) type it = (type) 1; it < type ## _COUNT; it = (type)( it + 1 )
|
||||
#endif
|
||||
|
||||
#ifndef stringify
|
||||
#define stringify_(S) #S
|
||||
#define stringify(S) stringify_(S)
|
||||
#ifndef md_stringify
|
||||
#define md_stringify_(S) #S
|
||||
#define md_stringify(S) md_stringify_(S)
|
||||
#endif
|
||||
|
||||
#ifndef glue
|
||||
#define glue_(A, B) A ## B
|
||||
#define glue(A, B) glue_(A,B)
|
||||
#ifndef md_glue
|
||||
#define md_glue_(A, B) A ## B
|
||||
#define md_glue(A, B) md_glue_(A,B)
|
||||
#endif
|
||||
|
||||
#define src_line_str stringify(__LINE__)
|
||||
#define md_src_line_str md_stringify(__LINE__)
|
||||
|
||||
#ifndef do_once
|
||||
#define do_once() \
|
||||
local_persist int __do_once_counter_##src_line_str = 0; \
|
||||
for(; __do_once_counter_##src_line_str != 1; __do_once_counter_##src_line_str = 1 ) \
|
||||
#ifndef md_do_once
|
||||
#define md_do_once() \
|
||||
md_local_persist int __do_once_counter_##md_src_line_str = 0; \
|
||||
for(; __do_once_counter_##md_src_line_str != 1; __do_once_counter_##md_src_line_str = 1 ) \
|
||||
|
||||
#define do_once_defer( expression ) \
|
||||
local_persist int __do_once_counter_##src_line_str = 0; \
|
||||
for(;__do_once_counter_##src_line_str != 1; __do_once_counter_##src_line_str = 1, (expression)) \
|
||||
#define md_do_once_defer( expression ) \
|
||||
md_local_persist int __do_once_counter_##md_src_line_str = 0; \
|
||||
for(;__do_once_counter_##md_src_line_str != 1; __do_once_counter_##md_src_line_str = 1, (expression)) \
|
||||
|
||||
#define do_once_start \
|
||||
#define md_do_once_start \
|
||||
do \
|
||||
{ \
|
||||
local_persist \
|
||||
md_local_persist \
|
||||
bool done = false; \
|
||||
if ( done ) \
|
||||
break; \
|
||||
done = true;
|
||||
|
||||
#define do_once_end \
|
||||
#define md_do_once_end \
|
||||
} \
|
||||
while(0);
|
||||
#endif
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#endif
|
||||
|
||||
inline void
|
||||
set_thread_name(String8 string) {
|
||||
prof_thread_name("%.*s", str8_varg(string));
|
||||
os_set_thread_name(string);
|
||||
md_set_thread_name(MD_String8 string) {
|
||||
md_prof_thread_name("%.*s", md_str8_varg(string));
|
||||
md_os_set_thread_name(string);
|
||||
}
|
||||
|
||||
@@ -8,21 +8,21 @@
|
||||
// Copyright (c) 2024 Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
MD_API void set_thread_name(String8 string);
|
||||
MD_API void md_set_thread_name(MD_String8 string);
|
||||
|
||||
inline void
|
||||
set_thread_namef(char *fmt, ...)
|
||||
md_set_thread_namef(char *fmt, ...)
|
||||
{
|
||||
TempArena scratch = scratch_begin(0, 0);
|
||||
MD_TempArena scratch = md_scratch_begin(0, 0);
|
||||
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
String8 string = str8fv(scratch.arena, fmt, args);
|
||||
set_thread_name(string);
|
||||
MD_String8 string = md_str8fv(scratch.arena, fmt, args);
|
||||
md_set_thread_name(string);
|
||||
va_end(args);
|
||||
|
||||
scratch_end(scratch);
|
||||
}
|
||||
|
||||
#define thread_namef(...) (set_thread_namef(__VA_ARGS__))
|
||||
#define thread_name(str) (set_thread_name(str))
|
||||
#define md_thread_namef(...) (md_set_thread_namef(__VA_ARGS__))
|
||||
#define md_thread_name(str) (md_set_thread_name(str))
|
||||
|
||||
+574
-574
File diff suppressed because it is too large
Load Diff
+357
-357
File diff suppressed because it is too large
Load Diff
+163
-163
@@ -5,15 +5,15 @@
|
||||
#endif
|
||||
|
||||
void*
|
||||
default_resize_align( AllocatorInfo a, void* old_memory, SSIZE old_size, SSIZE new_size, SSIZE alignment )
|
||||
md_default_resize_align( MD_AllocatorInfo a, void* old_memory, MD_SSIZE old_size, MD_SSIZE new_size, MD_SSIZE alignment )
|
||||
{
|
||||
if ( ! old_memory )
|
||||
return alloc_align( a, new_size, alignment );
|
||||
return md_alloc_align( a, new_size, alignment );
|
||||
|
||||
if ( new_size == 0 )
|
||||
{
|
||||
alloc_free( a, old_memory );
|
||||
return nullptr;
|
||||
md_alloc_free( a, old_memory );
|
||||
return md_nullptr;
|
||||
}
|
||||
|
||||
if ( new_size < old_size )
|
||||
@@ -25,12 +25,12 @@ default_resize_align( AllocatorInfo a, void* old_memory, SSIZE old_size, SSIZE n
|
||||
}
|
||||
else
|
||||
{
|
||||
void* new_memory = alloc_align( a, new_size, alignment );
|
||||
void* new_memory = md_alloc_align( a, new_size, alignment );
|
||||
if ( ! new_memory )
|
||||
return nullptr;
|
||||
return md_nullptr;
|
||||
|
||||
mem_move( new_memory, old_memory, md_min( new_size, old_size ) );
|
||||
alloc_free( a, old_memory );
|
||||
md_mem_move( new_memory, old_memory, md_min( new_size, old_size ) );
|
||||
md_alloc_free( a, old_memory );
|
||||
return new_memory;
|
||||
}
|
||||
}
|
||||
@@ -41,73 +41,73 @@ default_resize_align( AllocatorInfo a, void* old_memory, SSIZE old_size, SSIZE n
|
||||
typedef struct _heap_stats _heap_stats;
|
||||
struct _heap_stats
|
||||
{
|
||||
U32 magic;
|
||||
SSIZE used_memory;
|
||||
SSIZE alloc_count;
|
||||
MD_U32 magic;
|
||||
MD_SSIZE used_memory;
|
||||
MD_SSIZE md_alloc_count;
|
||||
};
|
||||
|
||||
global _heap_stats _heap_stats_info;
|
||||
md_global _heap_stats _heap_stats_info;
|
||||
|
||||
void
|
||||
heap_stats_init( void )
|
||||
md_heap_stats_init( void )
|
||||
{
|
||||
memory_zero_struct( &_heap_stats_info );
|
||||
md_memory_zero_struct( &_heap_stats_info );
|
||||
_heap_stats_info.magic = GEN_HEAP_STATS_MAGIC;
|
||||
}
|
||||
|
||||
SSIZE
|
||||
MD_SSIZE
|
||||
heap_stats_used_memory( void )
|
||||
{
|
||||
assert_msg( _heap_stats_info.magic == GEN_HEAP_STATS_MAGIC, "heap_stats is not initialised yet, call heap_stats_init first!" );
|
||||
md_assert_msg( _heap_stats_info.magic == GEN_HEAP_STATS_MAGIC, "heap_stats is not initialised yet, call md_heap_stats_init first!" );
|
||||
return _heap_stats_info.used_memory;
|
||||
}
|
||||
|
||||
SSIZE
|
||||
heap_stats_alloc_count( void )
|
||||
MD_SSIZE
|
||||
md_heap_stats_alloc_count( void )
|
||||
{
|
||||
assert_msg( _heap_stats_info.magic == GEN_HEAP_STATS_MAGIC, "heap_stats is not initialised yet, call heap_stats_init first!" );
|
||||
return _heap_stats_info.alloc_count;
|
||||
md_assert_msg( _heap_stats_info.magic == GEN_HEAP_STATS_MAGIC, "heap_stats is not initialised yet, call md_heap_stats_init first!" );
|
||||
return _heap_stats_info.md_alloc_count;
|
||||
}
|
||||
|
||||
void
|
||||
heap_stats_check( void )
|
||||
md_heap_stats_check( void )
|
||||
{
|
||||
assert_msg( _heap_stats_info.magic == GEN_HEAP_STATS_MAGIC, "heap_stats is not initialised yet, call heap_stats_init first!" );
|
||||
assert( _heap_stats_info.used_memory == 0 );
|
||||
assert( _heap_stats_info.alloc_count == 0 );
|
||||
md_assert_msg( _heap_stats_info.magic == GEN_HEAP_STATS_MAGIC, "heap_stats is not initialised yet, call md_heap_stats_init first!" );
|
||||
md_assert( _heap_stats_info.used_memory == 0 );
|
||||
md_assert( _heap_stats_info.md_alloc_count == 0 );
|
||||
}
|
||||
|
||||
typedef struct _heap_alloc_info _heap_alloc_info;
|
||||
struct _heap_alloc_info
|
||||
{
|
||||
SSIZE size;
|
||||
MD_SSIZE size;
|
||||
void* physical_start;
|
||||
};
|
||||
#endif
|
||||
|
||||
void*
|
||||
heap_allocator_proc( void* allocator_data, AllocatorMode mode, SSIZE size, SSIZE alignment, void* old_memory, SSIZE old_size, U64 flags )
|
||||
md_heap_allocator_proc( void* allocator_data, MD_AllocatorMode mode, MD_SSIZE size, MD_SSIZE alignment, void* old_memory, MD_SSIZE old_size, MD_U64 flags )
|
||||
{
|
||||
void* ptr = nullptr;
|
||||
void* ptr = md_nullptr;
|
||||
// unused( allocator_data );
|
||||
// unused( old_size );
|
||||
if ( ! alignment )
|
||||
alignment = MD_DEFAULT_MEMORY_ALIGNMENT;
|
||||
|
||||
#ifdef MD_HEAP_ANALYSIS
|
||||
ssize alloc_info_size = size_of( _heap_alloc_info );
|
||||
ssize alloc_info_remainder = ( alloc_info_size % alignment );
|
||||
ssize track_size = max( alloc_info_size, alignment ) + alloc_info_remainder;
|
||||
ssize md_alloc_info_size = size_of( _heap_alloc_info );
|
||||
ssize md_alloc_info_remainder = ( md_alloc_info_size % alignment );
|
||||
ssize track_size = md_max( md_alloc_info_size, alignment ) + md_alloc_info_remainder;
|
||||
switch ( type )
|
||||
{
|
||||
case EAllocatorMode_FREE :
|
||||
{
|
||||
if ( ! old_memory )
|
||||
break;
|
||||
_heap_alloc_info* alloc_info = rcast( _heap_alloc_info*, old_memory) - 1;
|
||||
_heap_stats_info.used_memory -= alloc_info->size;
|
||||
_heap_stats_info.alloc_count--;
|
||||
old_memory = alloc_info->physical_start;
|
||||
_heap_alloc_info* md_alloc_info = md_rcast( _heap_alloc_info*, old_memory) - 1;
|
||||
_heap_stats_info.used_memory -= md_alloc_info->size;
|
||||
_heap_stats_info.md_alloc_count--;
|
||||
old_memory = md_alloc_info->physical_start;
|
||||
}
|
||||
break;
|
||||
case EAllocatorMode_ALLOC :
|
||||
@@ -122,27 +122,27 @@ heap_allocator_proc( void* allocator_data, AllocatorMode mode, SSIZE size, SSIZE
|
||||
|
||||
switch ( mode )
|
||||
{
|
||||
#if defined( COMPILER_MSVC ) || ( defined( COMPILER_GCC ) && defined( OS_WINDOWS ) ) || ( defined( COMPILER_TINYC ) && defined( OS_WINDOWS ) )
|
||||
case AllocatorMode_Alloc:
|
||||
#if defined( MD_COMPILER_MSVC ) || ( defined( MD_COMPILER_GCC ) && defined( MD_OS_WINDOWS ) ) || ( defined( MD_COMPILER_TINYC ) && defined( MD_OS_WINDOWS ) )
|
||||
case MD_AllocatorMode_Alloc:
|
||||
{
|
||||
ptr = _aligned_malloc( size, alignment );
|
||||
if ( flags & ALLOCATOR_FLAG_CLEAR_TO_ZERO )
|
||||
memory_zero( ptr, size );
|
||||
if ( flags & MD_ALLOCATOR_FLAG_CLEAR_TO_ZERO )
|
||||
md_memory_zero( ptr, size );
|
||||
}
|
||||
break;
|
||||
|
||||
case AllocatorMode_Free:
|
||||
case MD_AllocatorMode_Free:
|
||||
_aligned_free( old_memory );
|
||||
break;
|
||||
|
||||
case AllocatorMode_Resize:
|
||||
case MD_AllocatorMode_Resize:
|
||||
{
|
||||
AllocatorInfo a = heap();
|
||||
ptr = default_resize_align( a, old_memory, old_size, size, alignment );
|
||||
MD_AllocatorInfo a = md_heap();
|
||||
ptr = md_default_resize_align( a, old_memory, old_size, size, alignment );
|
||||
}
|
||||
break;
|
||||
|
||||
#elif defined( OS_LINUX ) && ! defined( CPU_ARM ) && ! defined( COMPILER_TINYC )
|
||||
#elif defined( MD_OS_LINUX ) && ! defined( CPU_ARM ) && ! defined( MD_COMPILER_TINYC )
|
||||
case EAllocation_ALLOC :
|
||||
{
|
||||
ptr = aligned_alloc( alignment, ( size + alignment - 1 ) & ~( alignment - 1 ) );
|
||||
@@ -162,8 +162,8 @@ heap_allocator_proc( void* allocator_data, AllocatorMode mode, SSIZE size, SSIZE
|
||||
|
||||
case EAllocation_RESIZE :
|
||||
{
|
||||
AllocatorInfo a = heap();
|
||||
ptr = default_resize_align( a, old_memory, old_size, size, alignment );
|
||||
MD_AllocatorInfo a = md_heap();
|
||||
ptr = md_default_resize_align( a, old_memory, old_size, size, alignment );
|
||||
}
|
||||
break;
|
||||
#else
|
||||
@@ -171,7 +171,7 @@ heap_allocator_proc( void* allocator_data, AllocatorMode mode, SSIZE size, SSIZE
|
||||
{
|
||||
posix_memalign( &ptr, alignment, size );
|
||||
|
||||
if ( flags & ALLOCATOR_FLAG_CLEAR_TO_ZERO )
|
||||
if ( flags & MD_ALLOCATOR_FLAG_CLEAR_TO_ZERO )
|
||||
{
|
||||
zero_size( ptr, size );
|
||||
}
|
||||
@@ -186,89 +186,89 @@ heap_allocator_proc( void* allocator_data, AllocatorMode mode, SSIZE size, SSIZE
|
||||
|
||||
case EAllocType_RESIZE :
|
||||
{
|
||||
AllocatorInfo a = heap();
|
||||
ptr = default_resize_align( a, old_memory, old_size, size, alignment );
|
||||
MD_AllocatorInfo a = md_heap();
|
||||
ptr = md_default_resize_align( a, old_memory, old_size, size, alignment );
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
case AllocatorMode_FreeAll:
|
||||
case MD_AllocatorMode_FreeAll:
|
||||
break;
|
||||
|
||||
case AllocatorMode_QueryType:
|
||||
return (void*) AllocatorType_Heap;
|
||||
case MD_AllocatorMode_QueryType:
|
||||
return (void*) MD_AllocatorType_Heap;
|
||||
|
||||
case AllocatorMode_QuerySupport:
|
||||
case MD_AllocatorMode_QuerySupport:
|
||||
return (void*) (
|
||||
AllocatorQuery_Alloc | AllocatorQuery_Free | AllocatorQuery_Resize | AllocatorQuery_ResizeGrow | AllocatorQuery_ResizeShrink
|
||||
MD_AllocatorQuery_Alloc | MD_AllocatorQuery_Free | MD_AllocatorQuery_Resize | MD_AllocatorQuery_ResizeGrow | MD_AllocatorQuery_ResizeShrink
|
||||
);
|
||||
}
|
||||
|
||||
#ifdef GEN_HEAP_ANALYSIS
|
||||
if ( type == AllocatorMode_Alloc )
|
||||
if ( type == MD_AllocatorMode_Alloc )
|
||||
{
|
||||
_heap_alloc_info* alloc_info = rcast( _heap_alloc_info*, rcast( char*, ptr) + alloc_info_remainder );
|
||||
zero_item( alloc_info );
|
||||
alloc_info->size = size - track_size;
|
||||
alloc_info->physical_start = ptr;
|
||||
ptr = rcast( void*, alloc_info + 1 );
|
||||
_heap_stats_info.used_memory += alloc_info->size;
|
||||
_heap_stats_info.alloc_count++;
|
||||
_heap_alloc_info* md_alloc_info = md_rcast( _heap_alloc_info*, md_rcast( char*, ptr) + md_alloc_info_remainder );
|
||||
zero_item( md_alloc_info );
|
||||
md_alloc_info->size = size - track_size;
|
||||
md_alloc_info->physical_start = ptr;
|
||||
ptr = md_rcast( void*, md_alloc_info + 1 );
|
||||
_heap_stats_info.used_memory += md_alloc_info->size;
|
||||
_heap_stats_info.md_alloc_count++;
|
||||
}
|
||||
#endif
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
VArena*
|
||||
varena__alloc(VArenaParams params)
|
||||
MD_VArena*
|
||||
md_varena__alloc(MD_VArenaParams params)
|
||||
{
|
||||
if (params.reserve_size == 0) {
|
||||
params.reserve_size = VARENA_DEFAULT_RESERVE;
|
||||
params.reserve_size = MD_VARENA_DEFAULT_RESERVE;
|
||||
}
|
||||
if (params.commit_size == 0) {
|
||||
params.commit_size = VARENA_DEFAULT_COMMIT;
|
||||
params.commit_size = MD_VARENA_DEFAULT_COMMIT;
|
||||
}
|
||||
|
||||
// rjf: round up reserve/commit sizes
|
||||
U64 reserve_size = params.reserve_size;
|
||||
U64 commit_size = params.commit_size;
|
||||
MD_U64 reserve_size = params.reserve_size;
|
||||
MD_U64 commit_size = params.commit_size;
|
||||
|
||||
void* base = nullptr;
|
||||
if (params.flags & VArenaFlag_LargePages)
|
||||
void* base = md_nullptr;
|
||||
if (params.flags & MD_VArenaFlag_LargePages)
|
||||
{
|
||||
reserve_size = align_pow2(reserve_size, os_get_system_info()->large_page_size);
|
||||
commit_size = align_pow2(commit_size, os_get_system_info()->large_page_size);
|
||||
reserve_size = md_align_pow2(reserve_size, md_os_get_system_info()->large_page_size);
|
||||
commit_size = md_align_pow2(commit_size, md_os_get_system_info()->large_page_size);
|
||||
|
||||
base = os_reserve_large(reserve_size);
|
||||
os_commit_large(base, commit_size);
|
||||
asan_poison_memory_region(base, params.commit_size);
|
||||
base = md_os_reserve_large(reserve_size);
|
||||
md_os_commit_large(base, commit_size);
|
||||
md_asan_poison_memory_region(base, params.commit_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
reserve_size = align_pow2(reserve_size, os_get_system_info()->page_size);
|
||||
commit_size = align_pow2(commit_size, os_get_system_info()->page_size);
|
||||
reserve_size = md_align_pow2(reserve_size, md_os_get_system_info()->page_size);
|
||||
commit_size = md_align_pow2(commit_size, md_os_get_system_info()->page_size);
|
||||
|
||||
base = os_reserve(reserve_size);
|
||||
B32 commit_result = os_commit(base, commit_size);
|
||||
assert(commit_result == 1);
|
||||
asan_poison_memory_region(base, params.commit_size);
|
||||
base = md_os_reserve(reserve_size);
|
||||
MD_B32 commit_result = md_os_commit(base, commit_size);
|
||||
md_assert(commit_result == 1);
|
||||
md_asan_poison_memory_region(base, params.commit_size);
|
||||
}
|
||||
|
||||
// NOTE(Ed): Panic on varena creation failure
|
||||
#if OS_FEATURE_GRAPHICAL
|
||||
if(unlikely(base == 0))
|
||||
#if MD_OS_FEATURE_GRAPHICAL
|
||||
if(md_unlikely(base == 0))
|
||||
{
|
||||
os_graphical_message(1, str8_lit("Fatal Allocation Failure"), str8_lit("Unexpected memory allocation failure."));
|
||||
os_abort(1);
|
||||
md_os_graphical_message(1, md_str8_lit("Fatal Allocation Failure"), md_str8_lit("Unexpected memory allocation failure."));
|
||||
md_os_abort(1);
|
||||
}
|
||||
#endif
|
||||
|
||||
SPTR header_size = align_pow2(size_of(VArena), MD_DEFAULT_MEMORY_ALIGNMENT);
|
||||
asan_unpoison_memory_region(base, header_size);
|
||||
MD_SPTR header_size = md_align_pow2(size_of(MD_VArena), MD_DEFAULT_MEMORY_ALIGNMENT);
|
||||
md_asan_unpoison_memory_region(base, header_size);
|
||||
|
||||
VArena* vm = rcast(VArena*, base);
|
||||
vm->reserve_start = rcast(SPTR, base) + header_size;
|
||||
MD_VArena* vm = md_rcast(MD_VArena*, base);
|
||||
vm->reserve_start = md_rcast(MD_SPTR, base) + header_size;
|
||||
vm->reserve = reserve_size;
|
||||
vm->commit_size = params.commit_size;
|
||||
vm->committed = commit_size;
|
||||
@@ -278,50 +278,50 @@ varena__alloc(VArenaParams params)
|
||||
}
|
||||
|
||||
void
|
||||
varena_release(VArena* arena)
|
||||
md_varena_release(MD_VArena* arena)
|
||||
{
|
||||
os_release(arena, arena->reserve);
|
||||
arena = nullptr;
|
||||
md_os_release(arena, arena->reserve);
|
||||
arena = md_nullptr;
|
||||
}
|
||||
|
||||
void*
|
||||
varena_allocator_proc(void* allocator_data, AllocatorMode mode, SSIZE requested_size, SSIZE alignment, void* old_memory, SSIZE old_size, U64 flags)
|
||||
md_varena_allocator_proc(void* allocator_data, MD_AllocatorMode mode, MD_SSIZE requested_size, MD_SSIZE alignment, void* old_memory, MD_SSIZE old_size, MD_U64 flags)
|
||||
{
|
||||
OS_SystemInfo const* info = os_get_system_info();
|
||||
MD_OS_SystemInfo const* info = md_os_get_system_info();
|
||||
|
||||
VArena* vm = rcast(VArena*, allocator_data);
|
||||
MD_VArena* vm = md_rcast(MD_VArena*, allocator_data);
|
||||
|
||||
void* allocated_mem = nullptr;
|
||||
void* allocated_mem = md_nullptr;
|
||||
switch (mode)
|
||||
{
|
||||
case AllocatorMode_Alloc:
|
||||
case MD_AllocatorMode_Alloc:
|
||||
{
|
||||
assert_msg(requested_size != 0, "requested_size is 0");
|
||||
md_assert_msg(requested_size != 0, "requested_size is 0");
|
||||
|
||||
requested_size = align_pow2(requested_size, alignment);
|
||||
requested_size = md_align_pow2(requested_size, alignment);
|
||||
|
||||
UPTR current_offset = vm->reserve_start + vm->commit_used;
|
||||
UPTR size_to_allocate = requested_size;
|
||||
UPTR to_be_used = vm->commit_used + size_to_allocate;
|
||||
SPTR reserve_left = vm->reserve - vm->committed;
|
||||
assert(to_be_used < reserve_left);
|
||||
MD_UPTR current_offset = vm->reserve_start + vm->commit_used;
|
||||
MD_UPTR size_to_allocate = requested_size;
|
||||
MD_UPTR to_be_used = vm->commit_used + size_to_allocate;
|
||||
MD_SPTR reserve_left = vm->reserve - vm->committed;
|
||||
md_assert(to_be_used < reserve_left);
|
||||
|
||||
UPTR header_offset = vm->reserve_start - scast(UPTR, vm);
|
||||
MD_UPTR header_offset = vm->reserve_start - md_scast(MD_UPTR, vm);
|
||||
|
||||
UPTR commit_left = vm->committed - vm->commit_used - header_offset;
|
||||
B32 needs_more_commited = commit_left < size_to_allocate;
|
||||
MD_UPTR commit_left = vm->committed - vm->commit_used - header_offset;
|
||||
MD_B32 needs_more_commited = commit_left < size_to_allocate;
|
||||
if (needs_more_commited)
|
||||
{
|
||||
UPTR next_commit_size;
|
||||
if (vm->flags & VArenaFlag_LargePages) {
|
||||
next_commit_size = reserve_left > 0 ? md_max(vm->commit_size, size_to_allocate) : scast(UPTR, align_pow2( abs(reserve_left), os_get_system_info()->large_page_size));
|
||||
MD_UPTR next_commit_size;
|
||||
if (vm->flags & MD_VArenaFlag_LargePages) {
|
||||
next_commit_size = reserve_left > 0 ? md_max(vm->commit_size, size_to_allocate) : md_scast(MD_UPTR, md_align_pow2( abs(reserve_left), md_os_get_system_info()->large_page_size));
|
||||
}
|
||||
else {
|
||||
next_commit_size = reserve_left > 0 ? md_max(vm->commit_size, size_to_allocate) : scast(UPTR, align_pow2(abs(reserve_left), os_get_system_info()->page_size));
|
||||
next_commit_size = reserve_left > 0 ? md_max(vm->commit_size, size_to_allocate) : md_scast(MD_UPTR, md_align_pow2(abs(reserve_left), md_os_get_system_info()->page_size));
|
||||
}
|
||||
if (next_commit_size) {
|
||||
void* next_commit_start = rcast(void*, rcast(UPTR, vm) + vm->committed);
|
||||
B32 commit_result = os_commit(next_commit_start, next_commit_size);
|
||||
void* next_commit_start = md_rcast(void*, md_rcast(MD_UPTR, vm) + vm->committed);
|
||||
MD_B32 commit_result = md_os_commit(next_commit_start, next_commit_size);
|
||||
if (commit_result == false) {
|
||||
break;
|
||||
}
|
||||
@@ -329,60 +329,60 @@ varena_allocator_proc(void* allocator_data, AllocatorMode mode, SSIZE requested_
|
||||
}
|
||||
}
|
||||
|
||||
allocated_mem = rcast(void*, current_offset);
|
||||
allocated_mem = md_rcast(void*, current_offset);
|
||||
vm->commit_used += size_to_allocate;
|
||||
}
|
||||
break;
|
||||
|
||||
case AllocatorMode_Free:
|
||||
case MD_AllocatorMode_Free:
|
||||
{
|
||||
}
|
||||
break;
|
||||
|
||||
case AllocatorMode_FreeAll:
|
||||
case MD_AllocatorMode_FreeAll:
|
||||
{
|
||||
vm->commit_used = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case AllocatorMode_Resize:
|
||||
case MD_AllocatorMode_Resize:
|
||||
{
|
||||
assert(old_memory != nullptr);
|
||||
assert(old_size > 0);
|
||||
assert_msg(old_size == requested_size, "Requested resize when none needed");
|
||||
md_assert(old_memory != md_nullptr);
|
||||
md_assert(old_size > 0);
|
||||
md_assert_msg(old_size == requested_size, "Requested md_resize when none needed");
|
||||
|
||||
requested_size = align_pow2(requested_size, alignment);
|
||||
old_size = align_pow2(old_size, alignment);
|
||||
requested_size = md_align_pow2(requested_size, alignment);
|
||||
old_size = md_align_pow2(old_size, alignment);
|
||||
|
||||
UPTR old_memory_offset = scast(UPTR, old_memory) + scast(UPTR, old_size);
|
||||
UPTR current_offset = scast(UPTR, vm->reserve_start) + scast(UPTR, vm->commit_used);
|
||||
MD_UPTR old_memory_offset = md_scast(MD_UPTR, old_memory) + md_scast(MD_UPTR, old_size);
|
||||
MD_UPTR current_offset = md_scast(MD_UPTR, vm->reserve_start) + md_scast(MD_UPTR, vm->commit_used);
|
||||
|
||||
assert_msg(old_memory_offset == current_offset, "Cannot resize existing allocation in VArena unless it was the last allocated");
|
||||
md_assert_msg(old_memory_offset == current_offset, "Cannot md_resize existing allocation in MD_VArena unless it was the last allocated");
|
||||
|
||||
B32 requested_shrink = requested_size >= old_size;
|
||||
MD_B32 requested_shrink = requested_size >= old_size;
|
||||
if (requested_shrink) {
|
||||
vm->commit_used -= rcast(UPTR, align_pow2(requested_size, alignment));
|
||||
vm->commit_used -= md_rcast(MD_UPTR, md_align_pow2(requested_size, alignment));
|
||||
allocated_mem = old_memory;
|
||||
break;
|
||||
}
|
||||
|
||||
UPTR size_to_allocate = requested_size - old_size, alignment;
|
||||
MD_UPTR size_to_allocate = requested_size - old_size, alignment;
|
||||
|
||||
UPTR header_offset = vm->reserve_start - scast(UPTR, vm);
|
||||
UPTR commit_left = vm->committed - vm->commit_used - header_offset;
|
||||
B32 needs_more_commited = commit_left < size_to_allocate;
|
||||
MD_UPTR header_offset = vm->reserve_start - md_scast(MD_UPTR, vm);
|
||||
MD_UPTR commit_left = vm->committed - vm->commit_used - header_offset;
|
||||
MD_B32 needs_more_commited = commit_left < size_to_allocate;
|
||||
if (needs_more_commited)
|
||||
{
|
||||
SPTR reserve_left = vm->reserve - vm->committed;
|
||||
UPTR next_commit_size;
|
||||
if (vm->flags & VArenaFlag_LargePages) {
|
||||
next_commit_size = reserve_left > 0 ? vm->commit_size : scast(UPTR, align_pow2( -reserve_left, os_get_system_info()->large_page_size));
|
||||
MD_SPTR reserve_left = vm->reserve - vm->committed;
|
||||
MD_UPTR next_commit_size;
|
||||
if (vm->flags & MD_VArenaFlag_LargePages) {
|
||||
next_commit_size = reserve_left > 0 ? vm->commit_size : md_scast(MD_UPTR, md_align_pow2( -reserve_left, md_os_get_system_info()->large_page_size));
|
||||
}
|
||||
else {
|
||||
next_commit_size = reserve_left > 0 ? vm->commit_size : scast(UPTR, align_pow2(abs(reserve_left), os_get_system_info()->page_size));
|
||||
next_commit_size = reserve_left > 0 ? vm->commit_size : md_scast(MD_UPTR, md_align_pow2(abs(reserve_left), md_os_get_system_info()->page_size));
|
||||
}
|
||||
if (next_commit_size) {
|
||||
B32 commit_result = os_commit(vm, next_commit_size);
|
||||
MD_B32 commit_result = md_os_commit(vm, next_commit_size);
|
||||
if (commit_result == false) {
|
||||
break;
|
||||
}
|
||||
@@ -394,16 +394,16 @@ varena_allocator_proc(void* allocator_data, AllocatorMode mode, SSIZE requested_
|
||||
}
|
||||
break;
|
||||
|
||||
case AllocatorMode_QueryType:
|
||||
case MD_AllocatorMode_QueryType:
|
||||
{
|
||||
return (void*) AllocatorType_VArena;
|
||||
return (void*) MD_AllocatorType_VArena;
|
||||
}
|
||||
break;
|
||||
|
||||
case AllocatorMode_QuerySupport:
|
||||
case MD_AllocatorMode_QuerySupport:
|
||||
{
|
||||
return (void*) (
|
||||
AllocatorQuery_Alloc | AllocatorQuery_FreeAll | AllocatorQuery_Resize | AllocatorQuery_ResizeGrow | AllocatorQuery_ResizeShrink
|
||||
MD_AllocatorQuery_Alloc | MD_AllocatorQuery_FreeAll | MD_AllocatorQuery_Resize | MD_AllocatorQuery_ResizeGrow | MD_AllocatorQuery_ResizeShrink
|
||||
);
|
||||
}
|
||||
break;
|
||||
@@ -412,54 +412,54 @@ varena_allocator_proc(void* allocator_data, AllocatorMode mode, SSIZE requested_
|
||||
}
|
||||
|
||||
void*
|
||||
farena_allocator_proc(void* allocator_data, AllocatorMode mode, SSIZE size, SSIZE alignment, void* old_memory, SSIZE old_size, U64 flags)
|
||||
farena_allocator_proc(void* allocator_data, MD_AllocatorMode mode, MD_SSIZE size, MD_SSIZE alignment, void* old_memory, MD_SSIZE old_size, MD_U64 flags)
|
||||
{
|
||||
FArena* arena = rcast(FArena*, allocator_data);
|
||||
MD_FArena* arena = md_rcast(MD_FArena*, allocator_data);
|
||||
|
||||
void* allocated_mem = nullptr;
|
||||
void* allocated_mem = md_nullptr;
|
||||
switch (mode)
|
||||
{
|
||||
case AllocatorMode_Alloc:
|
||||
case MD_AllocatorMode_Alloc:
|
||||
{
|
||||
SPTR end = scast(SPTR, arena->slice.data) + arena->used;
|
||||
SSIZE total_size = align_pow2(size, alignment);
|
||||
MD_SPTR end = md_scast(MD_SPTR, arena->slice.data) + arena->used;
|
||||
MD_SSIZE total_size = md_align_pow2(size, alignment);
|
||||
|
||||
if (arena->used + total_size > arena->slice.len ) {
|
||||
// Out of memory
|
||||
return allocated_mem;
|
||||
}
|
||||
|
||||
allocated_mem = scast(void*, end);
|
||||
allocated_mem = md_scast(void*, end);
|
||||
arena->used += total_size;
|
||||
}
|
||||
break;
|
||||
|
||||
case AllocatorMode_Free:
|
||||
case MD_AllocatorMode_Free:
|
||||
{
|
||||
}
|
||||
break;
|
||||
|
||||
case AllocatorMode_FreeAll:
|
||||
case MD_AllocatorMode_FreeAll:
|
||||
{
|
||||
arena->used = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case AllocatorMode_Resize:
|
||||
case MD_AllocatorMode_Resize:
|
||||
{
|
||||
assert(old_memory != nullptr);
|
||||
assert(old_size > 0);
|
||||
assert_msg(old_size == size, "Requested resize when none needed");
|
||||
md_assert(old_memory != md_nullptr);
|
||||
md_assert(old_size > 0);
|
||||
md_assert_msg(old_size == size, "Requested md_resize when none needed");
|
||||
|
||||
size = align_pow2(size, alignment);
|
||||
old_size = align_pow2(size, alignment);
|
||||
size = md_align_pow2(size, alignment);
|
||||
old_size = md_align_pow2(size, alignment);
|
||||
|
||||
SPTR old_memory_offset = scast(SPTR, old_memory) + old_size;
|
||||
SPTR current_offset = scast(SPTR, arena->slice.data) + arena->used;
|
||||
MD_SPTR old_memory_offset = md_scast(MD_SPTR, old_memory) + old_size;
|
||||
MD_SPTR current_offset = md_scast(MD_SPTR, arena->slice.data) + arena->used;
|
||||
|
||||
assert_msg(old_memory_offset == current_offset, "Cannot resize existing allocation in VArena unless it was the last allocated");
|
||||
md_assert_msg(old_memory_offset == current_offset, "Cannot md_resize existing allocation in MD_VArena unless it was the last allocated");
|
||||
|
||||
B32 requested_shrink = size >= old_size;
|
||||
MD_B32 requested_shrink = size >= old_size;
|
||||
if (requested_shrink) {
|
||||
|
||||
arena->used -= size;
|
||||
@@ -472,13 +472,13 @@ farena_allocator_proc(void* allocator_data, AllocatorMode mode, SSIZE size, SSIZ
|
||||
}
|
||||
break;
|
||||
|
||||
case AllocatorMode_QueryType:
|
||||
return (void*) AllocatorType_FArena;
|
||||
case MD_AllocatorMode_QueryType:
|
||||
return (void*) MD_AllocatorType_FArena;
|
||||
break;
|
||||
|
||||
case AllocatorMode_QuerySupport:
|
||||
case MD_AllocatorMode_QuerySupport:
|
||||
return (void*) (
|
||||
AllocatorQuery_Alloc | AllocatorQuery_FreeAll | AllocatorQuery_Resize | AllocatorQuery_ResizeGrow | AllocatorQuery_ResizeShrink
|
||||
MD_AllocatorQuery_Alloc | MD_AllocatorQuery_FreeAll | MD_AllocatorQuery_Resize | MD_AllocatorQuery_ResizeGrow | MD_AllocatorQuery_ResizeShrink
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
+136
-136
@@ -14,57 +14,57 @@
|
||||
// Users can override the underlying memory allocator used, even for the HMH arena memory strategy.
|
||||
|
||||
#ifndef MD__ONES
|
||||
#define MD__ONES ( scast( GEN_NS usize, - 1) / MD_U8_MAX )
|
||||
#define MD__ONES ( md_scast( GEN_NS usize, - 1) / MD_U8_MAX )
|
||||
#define MD__HIGHS ( MD__ONES * ( MD_U8_MAX / 2 + 1 ) )
|
||||
#define MD__HAS_ZERO( x ) ( ( ( x ) - MD__ONES ) & ~( x ) & MD__HIGHS )
|
||||
#endif
|
||||
|
||||
// Return value of allocator_type
|
||||
typedef U64 AllocatorType;
|
||||
// Return value of md_allocator_type
|
||||
typedef MD_U64 MD_AllocatorType;
|
||||
enum
|
||||
{
|
||||
AllocatorType_Heap = 0, // Genreal heap allocator
|
||||
AllocatorType_VArena = 1, // Arena allocator backed by virtual address space
|
||||
AllocatorType_FArena = 2, // Fixed arena backed back by a fixed size block of memory (usually a byte slice)
|
||||
AllocatorType_Arena = 3, // Composite arena used originally by RAD Debugger & Metadesk
|
||||
MD_AllocatorType_Heap = 0, // Genreal md_heap allocator
|
||||
MD_AllocatorType_VArena = 1, // MD_Arena allocator backed by virtual address space
|
||||
MD_AllocatorType_FArena = 2, // Fixed arena backed back by a fixed size block of memory (usually a byte slice)
|
||||
MD_AllocatorType_Arena = 3, // Composite arena used originally by RAD Debugger & Metadesk
|
||||
};
|
||||
|
||||
typedef U32 AllocatorMode;
|
||||
enum AllocatorMode
|
||||
typedef MD_U32 MD_AllocatorMode;
|
||||
enum MD_AllocatorMode
|
||||
{
|
||||
AllocatorMode_Alloc,
|
||||
AllocatorMode_Free,
|
||||
AllocatorMode_FreeAll,
|
||||
AllocatorMode_Resize,
|
||||
AllocatorMode_QueryType,
|
||||
AllocatorMode_QuerySupport,
|
||||
MD_AllocatorMode_Alloc,
|
||||
MD_AllocatorMode_Free,
|
||||
MD_AllocatorMode_FreeAll,
|
||||
MD_AllocatorMode_Resize,
|
||||
MD_AllocatorMode_QueryType,
|
||||
MD_AllocatorMode_QuerySupport,
|
||||
};
|
||||
typedef U64 AllocatorQueryFlags;
|
||||
typedef MD_U64 MD_AllocatorQueryFlags;
|
||||
enum
|
||||
{
|
||||
AllocatorQuery_Alloc = (1 << 0),
|
||||
AllocatorQuery_Free = (1 << 1),
|
||||
AllocatorQuery_FreeAll = (1 << 2),
|
||||
AllocatorQuery_Resize = (1 << 3), // Supports both grow and shrink
|
||||
AllocatorQuery_ResizeShrink = (1 << 4),
|
||||
AllocatorQuery_ResizeGrow = (1 << 5),
|
||||
MD_AllocatorQuery_Alloc = (1 << 0),
|
||||
MD_AllocatorQuery_Free = (1 << 1),
|
||||
MD_AllocatorQuery_FreeAll = (1 << 2),
|
||||
MD_AllocatorQuery_Resize = (1 << 3), // Supports both grow and shrink
|
||||
MD_AllocatorQuery_ResizeShrink = (1 << 4),
|
||||
MD_AllocatorQuery_ResizeGrow = (1 << 5),
|
||||
};
|
||||
|
||||
typedef void*(AllocatorProc)( void* allocator_data, AllocatorMode type, SSIZE size, SSIZE alignment, void* old_memory, SSIZE old_size, U64 flags );
|
||||
typedef void*(MD_AllocatorProc)( void* allocator_data, MD_AllocatorMode type, MD_SSIZE size, MD_SSIZE alignment, void* old_memory, MD_SSIZE old_size, MD_U64 flags );
|
||||
|
||||
typedef struct AllocatorInfo AllocatorInfo;
|
||||
struct AllocatorInfo
|
||||
typedef struct MD_AllocatorInfo MD_AllocatorInfo;
|
||||
struct MD_AllocatorInfo
|
||||
{
|
||||
AllocatorProc* proc;
|
||||
MD_AllocatorProc* proc;
|
||||
void* data;
|
||||
};
|
||||
|
||||
// Overridable by the user by defining MD_OVERRIDE_DEFAULT_ALLOCATOR
|
||||
AllocatorInfo default_allocator();
|
||||
MD_AllocatorInfo md_default_allocator();
|
||||
|
||||
enum AllocFlag
|
||||
{
|
||||
ALLOCATOR_FLAG_CLEAR_TO_ZERO = (1 << 0),
|
||||
MD_ALLOCATOR_FLAG_CLEAR_TO_ZERO = (1 << 0),
|
||||
};
|
||||
|
||||
#ifndef MD_DEFAULT_MEMORY_ALIGNMENT
|
||||
@@ -72,222 +72,222 @@ enum AllocFlag
|
||||
#endif
|
||||
|
||||
#ifndef MD_DEFAULT_ALLOCATOR_FLAGS
|
||||
# define MD_DEFAULT_ALLOCATOR_FLAGS ( ALLOCATOR_FLAG_CLEAR_TO_ZERO )
|
||||
# define MD_DEFAULT_ALLOCATOR_FLAGS ( MD_ALLOCATOR_FLAG_CLEAR_TO_ZERO )
|
||||
#endif
|
||||
|
||||
// Retrieve which type of allocator
|
||||
AllocatorType allocator_type(AllocatorInfo a);
|
||||
MD_AllocatorType md_allocator_type(MD_AllocatorInfo a);
|
||||
// Retreive which modes the allocator supports
|
||||
AllocatorQueryFlags allocator_query_support(AllocatorInfo a);
|
||||
MD_AllocatorQueryFlags md_allocator_query_support(MD_AllocatorInfo a);
|
||||
|
||||
// Allocate memory with default alignment.
|
||||
void* alloc( AllocatorInfo a, SSIZE size );
|
||||
void* md_alloc( MD_AllocatorInfo a, MD_SSIZE size );
|
||||
|
||||
// Allocate memory with specified alignment.
|
||||
void* alloc_align( AllocatorInfo a, SSIZE size, SSIZE alignment );
|
||||
void* md_alloc_align( MD_AllocatorInfo a, MD_SSIZE size, MD_SSIZE alignment );
|
||||
|
||||
// Free allocated memory.
|
||||
void alloc_free( AllocatorInfo a, void* ptr );
|
||||
void md_alloc_free( MD_AllocatorInfo a, void* ptr );
|
||||
|
||||
// Free all memory allocated by an allocator.
|
||||
void free_all( AllocatorInfo a );
|
||||
void md_free_all( MD_AllocatorInfo a );
|
||||
|
||||
// Resize an allocated memory.
|
||||
void* resize( AllocatorInfo a, void* ptr, SSIZE old_size, SSIZE new_size );
|
||||
void* md_resize( MD_AllocatorInfo a, void* ptr, MD_SSIZE old_size, MD_SSIZE new_size );
|
||||
|
||||
// Resize an allocated memory with specified alignment.
|
||||
void* resize_align( AllocatorInfo a, void* ptr, SSIZE old_size, SSIZE new_size, SSIZE alignment );
|
||||
void* md_resize_align( MD_AllocatorInfo a, void* ptr, MD_SSIZE old_size, MD_SSIZE new_size, MD_SSIZE alignment );
|
||||
|
||||
#ifndef alloc_item
|
||||
#ifndef md_alloc_item
|
||||
// Allocate memory for an item.
|
||||
#define alloc_item(allocator, Type) (Type*)memory_zero(alloc(allocator, size_of(Type)), size_of(Type))
|
||||
#define md_alloc_item(allocator, Type) (Type*)md_memory_zero(md_alloc(allocator, size_of(Type)), size_of(Type))
|
||||
// Allocate memory for an item.
|
||||
#define alloc_item_no_zero( allocator, Type ) (Type*) alloc(allocator, size_of(Type))
|
||||
#define md_alloc_item_no_zero( allocator, Type ) (Type*) md_alloc(allocator, size_of(Type))
|
||||
#endif
|
||||
|
||||
#ifndef alloc_array
|
||||
#ifndef md_alloc_array
|
||||
// Allocate memory for an array of items.
|
||||
#define alloc_array( allocator_, Type, count ) (Type*)memory_zero(alloc( allocator_, size_of(Type) * (count) ), size_of(Type) * (count))
|
||||
#define md_alloc_array( allocator_, Type, count ) (Type*)md_memory_zero(md_alloc( allocator_, size_of(Type) * (count) ), size_of(Type) * (count))
|
||||
// Allocate memory for an array of items. (Don't zero initialize)
|
||||
#define alloc_array_no_zero( allocator_, Type, count ) (Type*) alloc( allocator_, size_of(Type) * (count) )
|
||||
#define md_alloc_array_no_zero( allocator_, Type, count ) (Type*) md_alloc( allocator_, size_of(Type) * (count) )
|
||||
#endif
|
||||
|
||||
// Allocate/Resize memory using default options.
|
||||
|
||||
// Use this if you don't need a "fancy" resize allocation
|
||||
void* default_resize_align( AllocatorInfo a, void* ptr, SSIZE old_size, SSIZE new_size, SSIZE alignment );
|
||||
// Use this if you don't need a "fancy" md_resize allocation
|
||||
void* md_default_resize_align( MD_AllocatorInfo a, void* ptr, MD_SSIZE old_size, MD_SSIZE new_size, MD_SSIZE alignment );
|
||||
|
||||
#ifdef MD_HEAP_ANALYSIS
|
||||
/* heap memory analysis tools */
|
||||
/* md_heap memory analysis tools */
|
||||
/* define GEN_HEAP_ANALYSIS to enable this feature */
|
||||
/* call zpl_heap_stats_init at the beginning of the entry point */
|
||||
/* you can call zpl_heap_stats_check near the end of the execution to validate any possible leaks */
|
||||
MD_API void heap_stats_init( void );
|
||||
MD_API SSIZE heap_stats_used_memory( void );
|
||||
MD_API SSIZE heap_stats_alloc_count( void );
|
||||
MD_API void heap_stats_check( void );
|
||||
MD_API void md_heap_stats_init( void );
|
||||
MD_API MD_SSIZE heap_stats_used_memory( void );
|
||||
MD_API MD_SSIZE md_heap_stats_alloc_count( void );
|
||||
MD_API void md_heap_stats_check( void );
|
||||
#endif
|
||||
|
||||
MD_API void* heap_allocator_proc( void* allocator_data, AllocatorMode mode, SSIZE size, SSIZE alignment, void* old_memory, SSIZE old_size, U64 flags );
|
||||
MD_API void* md_heap_allocator_proc( void* allocator_data, MD_AllocatorMode mode, MD_SSIZE size, MD_SSIZE alignment, void* old_memory, MD_SSIZE old_size, MD_U64 flags );
|
||||
|
||||
#ifndef heap
|
||||
// The heap allocator backed by the platform vendor's malloc & free.
|
||||
#define heap() (AllocatorInfo){ heap_allocator_proc, nullptr }
|
||||
#ifndef md_heap
|
||||
// The md_heap allocator backed by the platform vendor's md_malloc & free.
|
||||
#define md_heap() (MD_AllocatorInfo){ md_heap_allocator_proc, md_nullptr }
|
||||
#endif
|
||||
|
||||
#ifndef md_malloc
|
||||
// Helper to allocate memory using heap allocator.
|
||||
#define md_malloc( sz ) alloc( heap(), sz )
|
||||
// Helper to allocate memory using md_heap allocator.
|
||||
#define md_malloc( sz ) md_alloc( md_heap(), sz )
|
||||
#endif
|
||||
|
||||
#ifndef md_free
|
||||
// Helper to free memory allocated by heap allocator.
|
||||
#define md_free( ptr ) alloc_free( heap(), ptr )
|
||||
// Helper to free memory allocated by md_heap allocator.
|
||||
#define md_free( ptr ) md_alloc_free( md_heap(), ptr )
|
||||
#endif
|
||||
|
||||
/* Virtual Memory Arena
|
||||
/* Virtual Memory MD_Arena
|
||||
This is separate from the composite arena used by HMH/Casey Muratori/RJF
|
||||
This arena stricly manages one reservation of the process's virtual address space.
|
||||
|
||||
Segregating this from composite Arena style causes more moremoy to be used for "allocator headers", however it allows
|
||||
Segregating this from composite MD_Arena style causes more moremoy to be used for "allocator headers", however it allows
|
||||
users of a library to have greater control over the allocation strategy used from their side instead of the library itself.
|
||||
|
||||
Like with the composite Arena, the VArena has its struct as the header of the reserve of memory.
|
||||
Like with the composite MD_Arena, the MD_VArena has its struct as the header of the reserve of memory.
|
||||
*/
|
||||
|
||||
#ifndef VARENA_DEFUALT_RESERVE
|
||||
#define VARENA_DEFAULT_RESERVE MB(64)
|
||||
#ifndef MD_VARENA_DEFUALT_RESERVE
|
||||
#define MD_VARENA_DEFAULT_RESERVE MD_MB(64)
|
||||
#endif
|
||||
#ifndef VARENA_DEFUALT_COMMIT
|
||||
#define VARENA_DEFAULT_COMMIT KB(64)
|
||||
#ifndef MD_VARENA_DEFUALT_COMMIT
|
||||
#define MD_VARENA_DEFAULT_COMMIT MD_KB(64)
|
||||
#endif
|
||||
|
||||
typedef U32 VArenaFlags;
|
||||
typedef MD_U32 MD_VArenaFlags;
|
||||
enum
|
||||
{
|
||||
VArenaFlag_LargePages = (1 << 0),
|
||||
MD_VArenaFlag_LargePages = (1 << 0),
|
||||
};
|
||||
|
||||
typedef struct VArenaParams VArenaParams;
|
||||
struct VArenaParams
|
||||
typedef struct MD_VArenaParams MD_VArenaParams;
|
||||
struct MD_VArenaParams
|
||||
{
|
||||
U64 base_addr;
|
||||
VArenaFlags flags;
|
||||
U64 reserve_size;
|
||||
U64 commit_size;
|
||||
MD_U64 base_addr;
|
||||
MD_VArenaFlags flags;
|
||||
MD_U64 reserve_size;
|
||||
MD_U64 commit_size;
|
||||
};
|
||||
|
||||
typedef struct VArena VArena;
|
||||
struct VArena
|
||||
typedef struct MD_VArena MD_VArena;
|
||||
struct MD_VArena
|
||||
{
|
||||
SSIZE reserve_start;
|
||||
SSIZE reserve;
|
||||
SSIZE commit_size;
|
||||
SSIZE committed;
|
||||
SSIZE commit_used;
|
||||
VArenaFlags flags;
|
||||
MD_SSIZE reserve_start;
|
||||
MD_SSIZE reserve;
|
||||
MD_SSIZE commit_size;
|
||||
MD_SSIZE committed;
|
||||
MD_SSIZE commit_used;
|
||||
MD_VArenaFlags flags;
|
||||
};
|
||||
|
||||
MD_API VArena* varena__alloc(VArenaParams params PARAM_DEFAULT);
|
||||
#define varena_alloc(...) varena__alloc( (VArenaParams){__VA_ARGS__} )
|
||||
MD_API MD_VArena* md_varena__alloc(MD_VArenaParams params MD_PARAM_DEFAULT);
|
||||
#define md_varena_alloc(...) md_varena__alloc( (MD_VArenaParams){__VA_ARGS__} )
|
||||
|
||||
MD_API void varena_commit (VArena* vm, SSIZE commit_size);
|
||||
MD_API void varena_release(VArena* vm);
|
||||
MD_API void md_varena_commit (MD_VArena* vm, MD_SSIZE commit_size);
|
||||
MD_API void md_varena_release(MD_VArena* vm);
|
||||
|
||||
force_inline void varena_rewind(VArena* vm, SSIZE pos) { vm->commit_used = pos; }
|
||||
md_force_inline void varena_rewind(MD_VArena* vm, MD_SSIZE pos) { vm->commit_used = pos; }
|
||||
|
||||
MD_API void* varena_allocator_proc(void* allocator_data, AllocatorMode mode, SSIZE size, SSIZE alignment, void* old_memory, SSIZE old_size, U64 flags);
|
||||
MD_API void* md_varena_allocator_proc(void* allocator_data, MD_AllocatorMode mode, MD_SSIZE size, MD_SSIZE alignment, void* old_memory, MD_SSIZE old_size, MD_U64 flags);
|
||||
|
||||
#define varena_allocator(vm) (AllocatorInfo) { varena_allocator_proc, vm }
|
||||
#define md_varena_allocator(vm) (MD_AllocatorInfo) { md_varena_allocator_proc, vm }
|
||||
|
||||
typedef struct ByteSlice ByteSlice;
|
||||
struct ByteSlice
|
||||
typedef struct MD_ByteSlice MD_ByteSlice;
|
||||
struct MD_ByteSlice
|
||||
{
|
||||
U8* data;
|
||||
SSIZE len;
|
||||
MD_U8* data;
|
||||
MD_SSIZE len;
|
||||
};
|
||||
|
||||
#define mem_to_byteslice(data, len) (ByteSlice){ (U8*)(data), (SSIZE)(len) }
|
||||
#define md_mem_to_byteslice(data, len) (MD_ByteSlice){ (MD_U8*)(data), (MD_SSIZE)(len) }
|
||||
|
||||
// Fixed size arena
|
||||
typedef struct FArena FArena;
|
||||
struct FArena
|
||||
typedef struct MD_FArena MD_FArena;
|
||||
struct MD_FArena
|
||||
{
|
||||
ByteSlice slice;
|
||||
SSIZE used;
|
||||
MD_ByteSlice slice;
|
||||
MD_SSIZE used;
|
||||
};
|
||||
|
||||
#define farena_from_byteslice(slice) (FArena) { slice, 0 }
|
||||
#define farena_from_memory(data, len) (FArena) { mem_to_byteslice(data, len), 0 }
|
||||
#define md_farena_from_byteslice(slice) (MD_FArena) { slice, 0 }
|
||||
#define md_farena_from_memory(data, len) (MD_FArena) { md_mem_to_byteslice(data, len), 0 }
|
||||
|
||||
MD_API void* farena_allocator_proc(void* allocator_data, AllocatorMode mode, SSIZE size, SSIZE alignment, void* old_memory, SSIZE old_size, U64 flags);
|
||||
MD_API void* farena_allocator_proc(void* allocator_data, MD_AllocatorMode mode, MD_SSIZE size, MD_SSIZE alignment, void* old_memory, MD_SSIZE old_size, MD_U64 flags);
|
||||
|
||||
#define farena_allocator(arena) (AllocatorInfo){ farena_allocator_proc, & arena }
|
||||
#define farena_allocator(arena) (MD_AllocatorInfo){ farena_allocator_proc, & arena }
|
||||
|
||||
// Inlines
|
||||
|
||||
inline AllocatorType
|
||||
allocator_type(AllocatorInfo a) {
|
||||
if (a.proc == nullptr) {
|
||||
a = default_allocator();
|
||||
inline MD_AllocatorType
|
||||
md_allocator_type(MD_AllocatorInfo a) {
|
||||
if (a.proc == md_nullptr) {
|
||||
a = md_default_allocator();
|
||||
}
|
||||
return (AllocatorType) a.proc(a.data, AllocatorMode_QueryType, 0, 0, nullptr, 0, MD_DEFAULT_ALLOCATOR_FLAGS);
|
||||
return (MD_AllocatorType) a.proc(a.data, MD_AllocatorMode_QueryType, 0, 0, md_nullptr, 0, MD_DEFAULT_ALLOCATOR_FLAGS);
|
||||
}
|
||||
|
||||
inline AllocatorQueryFlags
|
||||
allocator_query_support(AllocatorInfo a) {
|
||||
if (a.proc == nullptr) {
|
||||
a = default_allocator();
|
||||
inline MD_AllocatorQueryFlags
|
||||
md_allocator_query_support(MD_AllocatorInfo a) {
|
||||
if (a.proc == md_nullptr) {
|
||||
a = md_default_allocator();
|
||||
}
|
||||
return (AllocatorType) a.proc(a.data, AllocatorMode_QuerySupport, 0, 0, nullptr, 0, MD_DEFAULT_ALLOCATOR_FLAGS);
|
||||
return (MD_AllocatorType) a.proc(a.data, MD_AllocatorMode_QuerySupport, 0, 0, md_nullptr, 0, MD_DEFAULT_ALLOCATOR_FLAGS);
|
||||
}
|
||||
|
||||
inline void*
|
||||
alloc_align( AllocatorInfo a, SSIZE size, SSIZE alignment ) {
|
||||
if (a.proc == nullptr) {
|
||||
a = default_allocator();
|
||||
md_alloc_align( MD_AllocatorInfo a, MD_SSIZE size, MD_SSIZE alignment ) {
|
||||
if (a.proc == md_nullptr) {
|
||||
a = md_default_allocator();
|
||||
}
|
||||
return a.proc( a.data, AllocatorMode_Alloc, size, alignment, nullptr, 0, MD_DEFAULT_ALLOCATOR_FLAGS );
|
||||
return a.proc( a.data, MD_AllocatorMode_Alloc, size, alignment, md_nullptr, 0, MD_DEFAULT_ALLOCATOR_FLAGS );
|
||||
}
|
||||
|
||||
inline void*
|
||||
alloc( AllocatorInfo a, SSIZE size ) {
|
||||
if (a.proc == nullptr) {
|
||||
a = default_allocator();
|
||||
md_alloc( MD_AllocatorInfo a, MD_SSIZE size ) {
|
||||
if (a.proc == md_nullptr) {
|
||||
a = md_default_allocator();
|
||||
}
|
||||
return alloc_align( a, size, MD_DEFAULT_MEMORY_ALIGNMENT );
|
||||
return md_alloc_align( a, size, MD_DEFAULT_MEMORY_ALIGNMENT );
|
||||
}
|
||||
|
||||
inline void
|
||||
alloc_free( AllocatorInfo a, void* ptr ) {
|
||||
if (a.proc == nullptr) {
|
||||
a = default_allocator();
|
||||
md_alloc_free( MD_AllocatorInfo a, void* ptr ) {
|
||||
if (a.proc == md_nullptr) {
|
||||
a = md_default_allocator();
|
||||
}
|
||||
if ( ptr != nullptr ) {
|
||||
a.proc( a.data, AllocatorMode_Free, 0, 0, ptr, 0, MD_DEFAULT_ALLOCATOR_FLAGS );
|
||||
if ( ptr != md_nullptr ) {
|
||||
a.proc( a.data, MD_AllocatorMode_Free, 0, 0, ptr, 0, MD_DEFAULT_ALLOCATOR_FLAGS );
|
||||
}
|
||||
}
|
||||
|
||||
inline void
|
||||
free_all( AllocatorInfo a ) {
|
||||
if (a.proc == nullptr) {
|
||||
a = default_allocator();
|
||||
md_free_all( MD_AllocatorInfo a ) {
|
||||
if (a.proc == md_nullptr) {
|
||||
a = md_default_allocator();
|
||||
}
|
||||
a.proc( a.data, AllocatorMode_FreeAll, 0, 0, nullptr, 0, MD_DEFAULT_ALLOCATOR_FLAGS );
|
||||
a.proc( a.data, MD_AllocatorMode_FreeAll, 0, 0, md_nullptr, 0, MD_DEFAULT_ALLOCATOR_FLAGS );
|
||||
}
|
||||
|
||||
inline void*
|
||||
resize( AllocatorInfo a, void* ptr, SSIZE old_size, SSIZE new_size ) {
|
||||
if (a.proc == nullptr) {
|
||||
a = default_allocator();
|
||||
md_resize( MD_AllocatorInfo a, void* ptr, MD_SSIZE old_size, MD_SSIZE new_size ) {
|
||||
if (a.proc == md_nullptr) {
|
||||
a = md_default_allocator();
|
||||
}
|
||||
return resize_align( a, ptr, old_size, new_size, MD_DEFAULT_ALLOCATOR_FLAGS );
|
||||
return md_resize_align( a, ptr, old_size, new_size, MD_DEFAULT_ALLOCATOR_FLAGS );
|
||||
}
|
||||
|
||||
inline void*
|
||||
resize_align( AllocatorInfo a, void* ptr, SSIZE old_size, SSIZE new_size, SSIZE alignment ) {
|
||||
if (a.proc == nullptr) {
|
||||
a = default_allocator();
|
||||
md_resize_align( MD_AllocatorInfo a, void* ptr, MD_SSIZE old_size, MD_SSIZE new_size, MD_SSIZE alignment ) {
|
||||
if (a.proc == md_nullptr) {
|
||||
a = md_default_allocator();
|
||||
}
|
||||
return a.proc( a.data, AllocatorMode_Resize, new_size, alignment, ptr, old_size, MD_DEFAULT_ALLOCATOR_FLAGS );
|
||||
return a.proc( a.data, MD_AllocatorMode_Resize, new_size, alignment, ptr, old_size, MD_DEFAULT_ALLOCATOR_FLAGS );
|
||||
}
|
||||
|
||||
@@ -6,13 +6,13 @@
|
||||
#include <stdarg.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#if defined( OS_WINDOWS )
|
||||
#if defined( MD_OS_WINDOWS )
|
||||
# include <intrin.h>
|
||||
# include <tmmintrin.h>
|
||||
# include <wmmintrin.h>
|
||||
#endif
|
||||
|
||||
#if LANG_C
|
||||
#if MD_LANG_C
|
||||
# include <assert.h>
|
||||
# include <stdbool.h>
|
||||
#endif
|
||||
|
||||
+38
-38
@@ -9,20 +9,20 @@
|
||||
////////////////////////////////
|
||||
//~ rjf: Zero Settings
|
||||
|
||||
#if !defined(PROFILE_TELEMETRY)
|
||||
# define PROFILE_TELEMETRY 0
|
||||
#if !defined(MD_PROFILE_TELEMETRY)
|
||||
# define MD_PROFILE_TELEMETRY 0
|
||||
#endif
|
||||
|
||||
#if !defined(MARKUP_LAYER_COLOR)
|
||||
# define MARKUP_LAYER_COLOR 1.00f, 0.00f, 1.00f
|
||||
#if !defined(MD_MARKUP_LAYER_COLOR)
|
||||
# define MD_MARKUP_LAYER_COLOR 1.00f, 0.00f, 1.00f
|
||||
#endif
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Third Party Includes
|
||||
|
||||
#if PROFILE_TELEMETRY
|
||||
#if MD_PROFILE_TELEMETRY
|
||||
# include "rad_tm.h"
|
||||
# if OS_WINDOWS
|
||||
# if MD_OS_WINDOWS
|
||||
# pragma comment(lib, "rad_tm_win64.lib")
|
||||
# endif
|
||||
#endif
|
||||
@@ -30,21 +30,21 @@
|
||||
////////////////////////////////
|
||||
//~ rjf: Telemetry Profile Defines
|
||||
|
||||
#if PROFILE_TELEMETRY
|
||||
# define prof_begin(...) tmEnter(0, 0, __VA_ARGS__)
|
||||
# define prof_begin_dynamic(...) (TM_API_PTR ? TM_API_PTR->_tmEnterZoneV_Core(0, 0, __FILE__, &g_telemetry_filename_id, __LINE__, __VA_ARGS__) : (void)0)
|
||||
# define prof_end(...) (TM_API_PTR ? TM_API_PTR->_tmLeaveZone(0) : (void)0)
|
||||
# define prof_tick(...) tmTick(0)
|
||||
# define prof_is_capturing(...) tmRunning()
|
||||
# define prof_begin_capture(...) tmOpen(0, __VA_ARGS__, __DATE__, "localhost", TMCT_TCP, TELEMETRY_DEFAULT_PORT, TMOF_INIT_NETWORKING|TMOF_CAPTURE_CONTEXT_SWITCHES, 100)
|
||||
# define prof_end_capture(...) tmClose(0)
|
||||
# define prof_thread_name(...) (TM_API_PTR ? TM_API_PTR->_tmThreadName(0, 0, __VA_ARGS__) : (void)0)
|
||||
# define prof_msg(...) (TM_API_PTR ? TM_API_PTR->_tmMessageV_Core(0, TMMF_ICON_NOTE, __FILE__, &g_telemetry_filename_id, __LINE__, __VA_ARGS__) : (void)0)
|
||||
# define prof_begin_lock_wait(...) tmStartWaitForLock(0, 0, __VA_ARGS__)
|
||||
# define prof_end_lock_wait(...) tmEndWaitForLock(0)
|
||||
# define prof_lock_take(...) tmAcquiredLock(0, 0, __VA_ARGS__)
|
||||
# define prof_lock_drop(...) tmReleasedLock(0, __VA_ARGS__)
|
||||
# define prof_color(color) tmZoneColorSticky(color)
|
||||
#if MD_PROFILE_TELEMETRY
|
||||
# define md_prof_begin(...) tmEnter(0, 0, __VA_ARGS__)
|
||||
# define md_prof_begin_dynamic(...) (TM_API_PTR ? TM_API_PTR->_tmEnterZoneV_Core(0, 0, __FILE__, &g_telemetry_filename_id, __LINE__, __VA_ARGS__) : (void)0)
|
||||
# define md_prof_end(...) (TM_API_PTR ? TM_API_PTR->_tmLeaveZone(0) : (void)0)
|
||||
# define md_prof_tick(...) tmTick(0)
|
||||
# define md_prof_is_capturing(...) tmRunning()
|
||||
# define md_prof_begin_capture(...) tmOpen(0, __VA_ARGS__, __DATE__, "localhost", TMCT_TCP, TELEMETRY_DEFAULT_PORT, TMOF_INIT_NETWORKING|TMOF_CAPTURE_CONTEXT_SWITCHES, 100)
|
||||
# define md_prof_end_capture(...) tmClose(0)
|
||||
# define md_prof_thread_name(...) (TM_API_PTR ? TM_API_PTR->_tmThreadName(0, 0, __VA_ARGS__) : (void)0)
|
||||
# define md_prof_msg(...) (TM_API_PTR ? TM_API_PTR->_tmMessageV_Core(0, TMMF_ICON_NOTE, __FILE__, &g_telemetry_filename_id, __LINE__, __VA_ARGS__) : (void)0)
|
||||
# define md_prof_begin_lock_wait(...) tmStartWaitForLock(0, 0, __VA_ARGS__)
|
||||
# define md_prof_end_lock_wait(...) tmEndWaitForLock(0)
|
||||
# define md_prof_lock_take(...) tmAcquiredLock(0, 0, __VA_ARGS__)
|
||||
# define md_prof_lock_drop(...) tmReleasedLock(0, __VA_ARGS__)
|
||||
# define md_prof_color(color) tmZoneColorSticky(color)
|
||||
#endif
|
||||
|
||||
// TODO(Ed): Support spall?
|
||||
@@ -53,25 +53,25 @@
|
||||
////////////////////////////////
|
||||
//~ rjf: Zeroify Undefined Defines
|
||||
|
||||
#if !defined(prof_begin)
|
||||
# define prof_begin(...) (0)
|
||||
# define prof_begin_dynamic(...) (0)
|
||||
# define prof_end(...) (0)
|
||||
# define prof_tick(...) (0)
|
||||
# define prof_is_capturing(...) (0)
|
||||
# define prof_begin_capture(...) (0)
|
||||
# define prof_end_capture(...) (0)
|
||||
# define prof_thread_name(...) (0)
|
||||
# define prof_msg(...) (0)
|
||||
# define prof_end_lock_wait(...) (0)
|
||||
# define prof_end_lock_wait(...) (0)
|
||||
# define prof_lock_take(...) (0)
|
||||
# define prof_lock_drop(...) (0)
|
||||
# define prof_color(...) (0)
|
||||
#if !defined(md_prof_begin)
|
||||
# define md_prof_begin(...) (0)
|
||||
# define md_prof_begin_dynamic(...) (0)
|
||||
# define md_prof_end(...) (0)
|
||||
# define md_prof_tick(...) (0)
|
||||
# define md_prof_is_capturing(...) (0)
|
||||
# define md_prof_begin_capture(...) (0)
|
||||
# define md_prof_end_capture(...) (0)
|
||||
# define md_prof_thread_name(...) (0)
|
||||
# define md_prof_msg(...) (0)
|
||||
# define md_prof_end_lock_wait(...) (0)
|
||||
# define md_prof_end_lock_wait(...) (0)
|
||||
# define md_prof_lock_take(...) (0)
|
||||
# define md_prof_lock_drop(...) (0)
|
||||
# define md_prof_color(...) (0)
|
||||
#endif
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Helper Wrappers
|
||||
|
||||
#define prof_begin_function(...) prof_begin(this_function_name)
|
||||
#define prof_scope(...) defer_loop(prof_begin_dynamic(__VA_ARGS__), ProfEnd())
|
||||
#define md_prof_begin_function(...) md_prof_begin(md_this_function_name)
|
||||
#define md_prof_scope(...) md_defer_loop(md_prof_begin_dynamic(__VA_ARGS__), ProfEnd())
|
||||
|
||||
+23
-23
@@ -6,41 +6,41 @@
|
||||
////////////////////////////////
|
||||
//~ rjf: Non-Fancy Ring Buffer Reads/Writes
|
||||
|
||||
U64 ring_write(U8* ring_base, U64 ring_size, U64 ring_pos, void* src_data, U64 src_data_size);
|
||||
U64 ring_read (U8* ring_base, U64 ring_size, U64 ring_pos, void* dst_data, U64 read_size);
|
||||
MD_U64 md_ring_write(MD_U8* md_ring_base, MD_U64 md_ring_size, MD_U64 md_ring_pos, void* src_data, MD_U64 src_data_size);
|
||||
MD_U64 md_ring_read (MD_U8* md_ring_base, MD_U64 md_ring_size, MD_U64 md_ring_pos, void* dst_data, MD_U64 read_size);
|
||||
|
||||
#define ring_write_struct(ring_base, ring_size, ring_pos, ptr) ring_write((ring_base), (ring_size), (ring_pos), (ptr), sizeof(*(ptr)))
|
||||
#define ring_read_struct(ring_base, ring_size, ring_pos, ptr) ring_read ((ring_base), (ring_size), (ring_pos), (ptr), sizeof(*(ptr)))
|
||||
#define md_ring_write_struct(md_ring_base, md_ring_size, md_ring_pos, ptr) md_ring_write((md_ring_base), (md_ring_size), (md_ring_pos), (ptr), sizeof(*(ptr)))
|
||||
#define md_ring_read_struct(md_ring_base, md_ring_size, md_ring_pos, ptr) md_ring_read ((md_ring_base), (md_ring_size), (md_ring_pos), (ptr), sizeof(*(ptr)))
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Non-Fancy Ring Buffer Reads/Writes
|
||||
|
||||
inline U64
|
||||
ring_write(U8* ring_base, U64 ring_size, U64 ring_pos, void* src_data, U64 src_data_size) {
|
||||
assert(src_data_size <= ring_size);
|
||||
inline MD_U64
|
||||
md_ring_write(MD_U8* md_ring_base, MD_U64 md_ring_size, MD_U64 md_ring_pos, void* src_data, MD_U64 src_data_size) {
|
||||
md_assert(src_data_size <= md_ring_size);
|
||||
{
|
||||
U64 ring_off = ring_pos % ring_size;
|
||||
U64 bytes_before_split = ring_size - ring_off;
|
||||
U64 pre_split_bytes = min(bytes_before_split, src_data_size);
|
||||
U64 pst_split_bytes = src_data_size - pre_split_bytes;
|
||||
MD_U64 md_ring_off = md_ring_pos % md_ring_size;
|
||||
MD_U64 bytes_before_split = md_ring_size - md_ring_off;
|
||||
MD_U64 pre_split_bytes = md_min(bytes_before_split, src_data_size);
|
||||
MD_U64 pst_split_bytes = src_data_size - pre_split_bytes;
|
||||
void* pre_split_data = src_data;
|
||||
void* pst_split_data = ((U8*)src_data + pre_split_bytes);
|
||||
memory_copy(ring_base + ring_off, pre_split_data, pre_split_bytes);
|
||||
memory_copy(ring_base + 0, pst_split_data, pst_split_bytes);
|
||||
void* pst_split_data = ((MD_U8*)src_data + pre_split_bytes);
|
||||
md_memory_copy(md_ring_base + md_ring_off, pre_split_data, pre_split_bytes);
|
||||
md_memory_copy(md_ring_base + 0, pst_split_data, pst_split_bytes);
|
||||
}
|
||||
return src_data_size;
|
||||
}
|
||||
|
||||
inline U64
|
||||
ring_read(U8* ring_base, U64 ring_size, U64 ring_pos, void* dst_data, U64 read_size) {
|
||||
assert(read_size <= ring_size);
|
||||
inline MD_U64
|
||||
md_ring_read(MD_U8* md_ring_base, MD_U64 md_ring_size, MD_U64 md_ring_pos, void* dst_data, MD_U64 read_size) {
|
||||
md_assert(read_size <= md_ring_size);
|
||||
{
|
||||
U64 ring_off = ring_pos % ring_size;
|
||||
U64 bytes_before_split = ring_size-ring_off;
|
||||
U64 pre_split_bytes = min(bytes_before_split, read_size);
|
||||
U64 pst_split_bytes = read_size - pre_split_bytes;
|
||||
memory_copy(dst_data, ring_base+ring_off, pre_split_bytes);
|
||||
memory_copy((U8*)dst_data + pre_split_bytes, ring_base + 0, pst_split_bytes);
|
||||
MD_U64 md_ring_off = md_ring_pos % md_ring_size;
|
||||
MD_U64 bytes_before_split = md_ring_size-md_ring_off;
|
||||
MD_U64 pre_split_bytes = md_min(bytes_before_split, read_size);
|
||||
MD_U64 pst_split_bytes = read_size - pre_split_bytes;
|
||||
md_memory_copy(dst_data, md_ring_base+md_ring_off, pre_split_bytes);
|
||||
md_memory_copy((MD_U8*)dst_data + pre_split_bytes, md_ring_base + 0, pst_split_bytes);
|
||||
}
|
||||
return read_size;
|
||||
}
|
||||
|
||||
+2
-2
@@ -5,6 +5,6 @@
|
||||
////////////////////////////////
|
||||
//~ rjf: Sorts
|
||||
|
||||
#ifndef quick_sort
|
||||
#define quick_sort(ptr, count, element_size, cmp_function) qsort((ptr), (count), (element_size), (int (*)(const void *, const void *))(cmp_function))
|
||||
#ifndef md_quick_sort
|
||||
#define md_quick_sort(ptr, count, element_size, cmp_function) qsort((ptr), (count), (element_size), (int (*)(const void *, const void *))(cmp_function))
|
||||
#endif
|
||||
|
||||
+40
-40
@@ -6,62 +6,62 @@
|
||||
////////////////////////////////
|
||||
//~ rjf: Basic Types & Spaces
|
||||
|
||||
typedef enum Dimension Dimension;
|
||||
enum Dimension
|
||||
typedef enum MD_Dimension MD_Dimension;
|
||||
enum MD_Dimension
|
||||
{
|
||||
Dimension_X,
|
||||
Dimension_Y,
|
||||
Dimension_Z,
|
||||
Dimension_W,
|
||||
MD_Dimension_X,
|
||||
MD_Dimension_Y,
|
||||
MD_Dimension_Z,
|
||||
MD_Dimension_W,
|
||||
};
|
||||
|
||||
typedef enum Side Side;
|
||||
enum Side
|
||||
typedef enum MD_Side MD_Side;
|
||||
enum MD_Side
|
||||
{
|
||||
Side_Invalid = -1,
|
||||
Side_Min,
|
||||
Side_Max,
|
||||
Side_COUNT,
|
||||
MD_Side_Invalid = -1,
|
||||
MD_Side_Min,
|
||||
MD_Side_Max,
|
||||
MD_Side_COUNT,
|
||||
};
|
||||
#define side_flip(s) ((Side)(!(s)))
|
||||
#define side_flip(s) ((MD_Side)(!(s)))
|
||||
|
||||
typedef enum Axis2 Axis2;
|
||||
enum Axis2
|
||||
typedef enum MD_Axis2 MD_Axis2;
|
||||
enum MD_Axis2
|
||||
{
|
||||
Axis2_Invalid = -1,
|
||||
Axis2_X,
|
||||
Axis2_Y,
|
||||
Axis2_COUNT,
|
||||
MD_Axis2_Invalid = -1,
|
||||
MD_Axis2_X,
|
||||
MD_Axis2_Y,
|
||||
MD_Axis2_COUNT,
|
||||
};
|
||||
#define axis2_flip(a) ((Axis2)(!(a)))
|
||||
#define axis2_flip(a) ((MD_Axis2)(!(a)))
|
||||
|
||||
typedef enum Corner Corner;
|
||||
enum Corner
|
||||
typedef enum MD_corner MD_corner;
|
||||
enum MD_corner
|
||||
{
|
||||
Corner_Invalid = -1,
|
||||
Corner_00,
|
||||
Corner_01,
|
||||
Corner_10,
|
||||
Corner_11,
|
||||
Corner_COUNT
|
||||
MD_Corner_Invalid = -1,
|
||||
MD_Corner_00,
|
||||
MD_Corner_01,
|
||||
MD_Corner_10,
|
||||
MD_Corner_11,
|
||||
MD_Corner_COUNT
|
||||
};
|
||||
|
||||
typedef enum Dir2 Dir2;
|
||||
enum Dir2
|
||||
typedef enum MD_Dir2 MD_Dir2;
|
||||
enum MD_Dir2
|
||||
{
|
||||
Dir2_Invalid = -1,
|
||||
Dir2_Left,
|
||||
Dir2_Up,
|
||||
Dir2_Right,
|
||||
Dir2_Down,
|
||||
Dir2_COUNT
|
||||
MD_Dir2_Invalid = -1,
|
||||
MD_Dir2_Left,
|
||||
MD_Dir2_Up,
|
||||
MD_Dir2_Right,
|
||||
MD_Dir2_Down,
|
||||
MD_Dir2_COUNT
|
||||
};
|
||||
|
||||
#define axis2_from_dir2(d) (((d) & 1) ? Axis2_Y : Axis2_X)
|
||||
#define side_from_dir2(d) (((d) < Dir2_Right) ? Side_Min : Side_Max)
|
||||
#define md_axis2_from_dir2(d) (((d) & 1) ? MD_Axis2_Y : MD_Axis2_X)
|
||||
#define md_side_from_dir2(d) (((d) < MD_Dir2_Right) ? MD_Side_Min : MD_Side_Max)
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Enum -> Sign
|
||||
|
||||
inline S32 sign_from_side_S32(Side side) { return((side == Side_Min) ? -1 : 1 ); }
|
||||
inline F32 sign_from_side_F32(Side side) { return((side == Side_Min) ? -1.f : 1.f); }
|
||||
inline MD_S32 md_sign_from_side_S32(MD_Side side) { return((side == MD_Side_Min) ? -1 : 1 ); }
|
||||
inline MD_F32 md_sign_from_side_F32(MD_Side side) { return((side == MD_Side_Min) ? -1.f : 1.f); }
|
||||
|
||||
+629
-629
File diff suppressed because it is too large
Load Diff
+687
-687
File diff suppressed because it is too large
Load Diff
+19
-19
@@ -5,23 +5,23 @@
|
||||
////////////////////////////////
|
||||
//~ rjf: Text Path Helpers
|
||||
|
||||
String8TxtPtPair
|
||||
str8_txt_pt_pair_from_string(String8 string)
|
||||
MD_String8TxtPtPair
|
||||
md_str8_txt_pt_pair_from_string(MD_String8 string)
|
||||
{
|
||||
String8TxtPtPair pair = {0};
|
||||
MD_String8TxtPtPair pair = {0};
|
||||
{
|
||||
String8 file_part = {0};
|
||||
String8 line_part = {0};
|
||||
String8 col_part = {0};
|
||||
MD_String8 file_part = {0};
|
||||
MD_String8 line_part = {0};
|
||||
MD_String8 col_part = {0};
|
||||
|
||||
// rjf: grab file part
|
||||
for(U64 idx = 0; idx <= string.size; idx += 1)
|
||||
for(MD_U64 idx = 0; idx <= string.size; idx += 1)
|
||||
{
|
||||
U8 byte = (idx < string.size) ? (string.str[idx ]) : 0;
|
||||
U8 next_byte = ((idx + 1 < string.size) ? (string.str[idx + 1]) : 0);
|
||||
MD_U8 byte = (idx < string.size) ? (string.str[idx ]) : 0;
|
||||
MD_U8 next_byte = ((idx + 1 < string.size) ? (string.str[idx + 1]) : 0);
|
||||
if(byte == ':' && next_byte != '/' && next_byte != '\\') {
|
||||
file_part = str8_prefix(string, idx);
|
||||
line_part = str8_skip(string, idx+1);
|
||||
file_part = md_str8_prefix(string, idx);
|
||||
line_part = md_str8_skip(string, idx+1);
|
||||
break;
|
||||
}
|
||||
else if(byte == 0) {
|
||||
@@ -31,22 +31,22 @@ str8_txt_pt_pair_from_string(String8 string)
|
||||
}
|
||||
// rjf: grab line/column
|
||||
{
|
||||
U64 colon_pos = str8_find_needle(line_part, 0, str8_lit(":"), 0);
|
||||
MD_U64 colon_pos = md_str8_find_needle(line_part, 0, md_str8_lit(":"), 0);
|
||||
if(colon_pos < line_part.size) {
|
||||
col_part = str8_skip (line_part, colon_pos + 1);
|
||||
line_part = str8_prefix(line_part, colon_pos);
|
||||
col_part = md_str8_skip (line_part, colon_pos + 1);
|
||||
line_part = md_str8_prefix(line_part, colon_pos);
|
||||
}
|
||||
}
|
||||
|
||||
// rjf: convert line/column strings to numerics
|
||||
U64 line = 0;
|
||||
U64 column = 0;
|
||||
try_u64_from_str8_c_rules(line_part, &line);
|
||||
try_u64_from_str8_c_rules(col_part, &column);
|
||||
MD_U64 line = 0;
|
||||
MD_U64 column = 0;
|
||||
md_try_u64_from_str8_c_rules(line_part, &line);
|
||||
md_try_u64_from_str8_c_rules(col_part, &column);
|
||||
|
||||
// rjf: fill
|
||||
pair.string = file_part;
|
||||
pair.pt = txt_pt((S64)line, (S64)column);
|
||||
pair.pt = md_txt_pt((MD_S64)line, (MD_S64)column);
|
||||
if(pair.pt.line == 0) { pair.pt.line = 1; }
|
||||
if(pair.pt.column == 0) { pair.pt.column = 1; }
|
||||
}
|
||||
|
||||
+47
-47
@@ -6,54 +6,54 @@
|
||||
////////////////////////////////
|
||||
//~ rjf: Text 2D Coordinates & Ranges
|
||||
|
||||
typedef struct TxtPt TxtPt;
|
||||
struct TxtPt
|
||||
typedef struct MD_TxtPt MD_TxtPt;
|
||||
struct MD_TxtPt
|
||||
{
|
||||
S64 line;
|
||||
S64 column;
|
||||
MD_S64 line;
|
||||
MD_S64 column;
|
||||
};
|
||||
|
||||
typedef struct TxtRng TxtRng;
|
||||
struct TxtRng
|
||||
typedef struct MD_TxtRng MD_TxtRng;
|
||||
struct MD_TxtRng
|
||||
{
|
||||
TxtPt min;
|
||||
TxtPt max;
|
||||
MD_TxtPt md_min;
|
||||
MD_TxtPt md_max;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: String Pair Types
|
||||
|
||||
typedef struct String8TxtPtPair String8TxtPtPair;
|
||||
struct String8TxtPtPair
|
||||
typedef struct MD_String8TxtPtPair MD_String8TxtPtPair;
|
||||
struct MD_String8TxtPtPair
|
||||
{
|
||||
String8 string;
|
||||
TxtPt pt;
|
||||
MD_String8 string;
|
||||
MD_TxtPt pt;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Text Path Helpers
|
||||
|
||||
MD_API String8TxtPtPair str8_txt_pt_pair_from_string(String8 string);
|
||||
MD_API MD_String8TxtPtPair md_str8_txt_pt_pair_from_string(MD_String8 string);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Text 2D Coordinate/Range Functions
|
||||
|
||||
inline TxtPt txt_pt(S64 line, S64 column) { TxtPt p = { line, column }; return p; }
|
||||
inline MD_TxtPt md_txt_pt(MD_S64 line, MD_S64 column) { MD_TxtPt p = { line, column }; return p; }
|
||||
|
||||
inline B32 txt_pt_match(TxtPt a, TxtPt b) { return a.line == b.line && a.column == b.column; }
|
||||
inline TxtPt txt_pt_min (TxtPt a, TxtPt b) { TxtPt result = b; if (txt_pt_less_than(a, b)) { result = a; } return result; }
|
||||
inline TxtPt txt_pt_max (TxtPt a, TxtPt b) { TxtPt result = a; if (txt_pt_less_than(a, b)) { result = b; } return result; }
|
||||
inline MD_B32 md_txt_pt_match(MD_TxtPt a, MD_TxtPt b) { return a.line == b.line && a.column == b.column; }
|
||||
inline MD_TxtPt md_txt_pt_min (MD_TxtPt a, MD_TxtPt b) { MD_TxtPt result = b; if (md_txt_pt_less_than(a, b)) { result = a; } return result; }
|
||||
inline MD_TxtPt md_txt_pt_max (MD_TxtPt a, MD_TxtPt b) { MD_TxtPt result = a; if (md_txt_pt_less_than(a, b)) { result = b; } return result; }
|
||||
|
||||
B32 txt_pt_less_than (TxtPt a, TxtPt b);
|
||||
TxtRng txt_rng (TxtPt min, TxtPt max);
|
||||
TxtRng txt_rng_intersect(TxtRng a, TxtRng b);
|
||||
TxtRng txt_rng_union (TxtRng a, TxtRng b);
|
||||
B32 txt_rng_contains (TxtRng r, TxtPt pt);
|
||||
MD_B32 md_txt_pt_less_than (MD_TxtPt a, MD_TxtPt b);
|
||||
MD_TxtRng md_txt_rng (MD_TxtPt md_min, MD_TxtPt md_max);
|
||||
MD_TxtRng md_txt_rng_intersect(MD_TxtRng a, MD_TxtRng b);
|
||||
MD_TxtRng md_txt_rng_union (MD_TxtRng a, MD_TxtRng b);
|
||||
MD_B32 md_txt_rng_contains (MD_TxtRng r, MD_TxtPt pt);
|
||||
|
||||
inline B32
|
||||
txt_pt_less_than(TxtPt a, TxtPt b)
|
||||
inline MD_B32
|
||||
md_txt_pt_less_than(MD_TxtPt a, MD_TxtPt b)
|
||||
{
|
||||
B32 result = 0;
|
||||
MD_B32 result = 0;
|
||||
if (a.line < b.line) {
|
||||
result = 1;
|
||||
}
|
||||
@@ -63,44 +63,44 @@ txt_pt_less_than(TxtPt a, TxtPt b)
|
||||
return result;
|
||||
}
|
||||
|
||||
inline TxtRng
|
||||
txt_rng(TxtPt min, TxtPt max)
|
||||
inline MD_TxtRng
|
||||
md_txt_rng(MD_TxtPt md_min, MD_TxtPt md_max)
|
||||
{
|
||||
TxtRng range = {0};
|
||||
if(txt_pt_less_than(min, max)) {
|
||||
range.min = min;
|
||||
range.max = max;
|
||||
MD_TxtRng range = {0};
|
||||
if(md_txt_pt_less_than(md_min, md_max)) {
|
||||
range.md_min = md_min;
|
||||
range.md_max = md_max;
|
||||
}
|
||||
else {
|
||||
range.min = max;
|
||||
range.max = min;
|
||||
range.md_min = md_max;
|
||||
range.md_max = md_min;
|
||||
}
|
||||
return range;
|
||||
}
|
||||
|
||||
inline TxtRng
|
||||
txt_rng_intersect(TxtRng a, TxtRng b)
|
||||
inline MD_TxtRng
|
||||
md_txt_rng_intersect(MD_TxtRng a, MD_TxtRng b)
|
||||
{
|
||||
TxtRng result = {0};
|
||||
result.min = txt_pt_max(a.min, b.min);
|
||||
result.max = txt_pt_min(a.max, b.max);
|
||||
if (txt_pt_less_than(result.max, result.min)) {
|
||||
MD_TxtRng result = {0};
|
||||
result.md_min = md_txt_pt_max(a.md_min, b.md_min);
|
||||
result.md_max = md_txt_pt_min(a.md_max, b.md_max);
|
||||
if (md_txt_pt_less_than(result.md_max, result.md_min)) {
|
||||
MemoryZeroStruct(&result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
inline TxtRng
|
||||
txt_rng_union(TxtRng a, TxtRng b)
|
||||
inline MD_TxtRng
|
||||
md_txt_rng_union(MD_TxtRng a, MD_TxtRng b)
|
||||
{
|
||||
TxtRng result = {0};
|
||||
result.min = txt_pt_min(a.min, b.min);
|
||||
result.max = txt_pt_max(a.max, b.max);
|
||||
MD_TxtRng result = {0};
|
||||
result.md_min = md_txt_pt_min(a.md_min, b.md_min);
|
||||
result.md_max = md_txt_pt_max(a.md_max, b.md_max);
|
||||
return result;
|
||||
}
|
||||
|
||||
inline B32
|
||||
txt_rng_contains(TxtRng r, TxtPt pt) {
|
||||
B32 result = ((txt_pt_less_than(r.min, pt) || txt_pt_match(r.min, pt)) && txt_pt_less_than(pt, r.max));
|
||||
inline MD_B32
|
||||
md_txt_rng_contains(MD_TxtRng r, MD_TxtPt pt) {
|
||||
MD_B32 result = ((md_txt_pt_less_than(r.md_min, pt) || md_txt_pt_match(r.md_min, pt)) && md_txt_pt_less_than(pt, r.md_max));
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -7,79 +7,79 @@
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
////////////////////////////////
|
||||
// NOTE(allen): Thread Context Functions
|
||||
// NOTE(allen): Thread MD_Context Functions
|
||||
|
||||
MD_API_C thread_static TCTX* tctx_thread_local;
|
||||
MD_API_C md_thread_static MD_TCTX* md_tctx_thread_local;
|
||||
|
||||
#if ! MD_BUILD_SUPPLEMENTARY_UNIT
|
||||
MD_API_C thread_static TCTX* tctx_thread_local = 0;
|
||||
MD_API_C md_thread_static MD_TCTX* md_tctx_thread_local = 0;
|
||||
#endif
|
||||
|
||||
void
|
||||
tctx_init_and_equip(TCTX* tctx)
|
||||
md_tctx_init_and_equip(MD_TCTX* md_tctx)
|
||||
{
|
||||
// memory_zero_struct(tctx);
|
||||
// md_memory_zero_struct(md_tctx);
|
||||
|
||||
Arena** arena_ptr = tctx->arenas;
|
||||
for (U64 i = 0; i < array_count(tctx->arenas); i += 1, arena_ptr += 1)
|
||||
MD_Arena** md_arena_ptr = md_tctx->arenas;
|
||||
for (MD_U64 i = 0; i < md_array_count(md_tctx->arenas); i += 1, md_arena_ptr += 1)
|
||||
{
|
||||
if (*arena_ptr == nullptr)
|
||||
if (*md_arena_ptr == md_nullptr)
|
||||
{
|
||||
VArena* vm = varena_alloc(.reserve_size = VARENA_DEFAULT_RESERVE, .commit_size = VARENA_DEFAULT_COMMIT);
|
||||
*arena_ptr = arena_alloc(.backing = varena_allocator(vm));
|
||||
MD_VArena* vm = md_varena_alloc(.reserve_size = MD_VARENA_DEFAULT_RESERVE, .commit_size = MD_VARENA_DEFAULT_COMMIT);
|
||||
*md_arena_ptr = md_arena_alloc(.backing = md_varena_allocator(vm));
|
||||
}
|
||||
}
|
||||
tctx_thread_local = tctx;
|
||||
md_tctx_thread_local = md_tctx;
|
||||
}
|
||||
|
||||
void
|
||||
tctx_init_and_equip_alloc(TCTX* tctx, AllocatorInfo ainfo)
|
||||
md_tctx_init_and_equip_alloc(MD_TCTX* md_tctx, MD_AllocatorInfo ainfo)
|
||||
{
|
||||
memory_zero_struct(tctx);
|
||||
md_memory_zero_struct(md_tctx);
|
||||
|
||||
Arena** arena_ptr = tctx->arenas;
|
||||
for (U64 i = 0; i < array_count(tctx->arenas); i += 1, arena_ptr += 1)
|
||||
MD_Arena** md_arena_ptr = md_tctx->arenas;
|
||||
for (MD_U64 i = 0; i < md_array_count(md_tctx->arenas); i += 1, md_arena_ptr += 1)
|
||||
{
|
||||
if (*arena_ptr == nullptr)
|
||||
if (*md_arena_ptr == md_nullptr)
|
||||
{
|
||||
*arena_ptr = arena_alloc(.backing = ainfo);
|
||||
*md_arena_ptr = md_arena_alloc(.backing = ainfo);
|
||||
}
|
||||
}
|
||||
tctx_thread_local = tctx;
|
||||
md_tctx_thread_local = md_tctx;
|
||||
}
|
||||
|
||||
void
|
||||
tctx_release(void) {
|
||||
for (U64 i = 0; i < array_count(tctx_thread_local->arenas); i += 1) {
|
||||
arena_release(tctx_thread_local->arenas[i]);
|
||||
md_tctx_release(void) {
|
||||
for (MD_U64 i = 0; i < md_array_count(md_tctx_thread_local->arenas); i += 1) {
|
||||
md_arena_release(md_tctx_thread_local->arenas[i]);
|
||||
}
|
||||
}
|
||||
|
||||
TCTX*
|
||||
tctx_get_equipped(void){
|
||||
return(tctx_thread_local);
|
||||
MD_TCTX*
|
||||
md_tctx_get_equipped(void){
|
||||
return(md_tctx_thread_local);
|
||||
}
|
||||
|
||||
Arena*
|
||||
tctx_get_scratch(Arena** conflicts, U64 count)
|
||||
MD_Arena*
|
||||
md_tctx_get_scratch(MD_Arena** conflicts, MD_U64 count)
|
||||
{
|
||||
TCTX* tctx = tctx_get_equipped();
|
||||
MD_TCTX* md_tctx = md_tctx_get_equipped();
|
||||
|
||||
Arena* result = 0;
|
||||
Arena** arena_ptr = tctx->arenas;
|
||||
for (U64 i = 0; i < array_count(tctx->arenas); i += 1, arena_ptr += 1)
|
||||
MD_Arena* result = 0;
|
||||
MD_Arena** md_arena_ptr = md_tctx->arenas;
|
||||
for (MD_U64 i = 0; i < md_array_count(md_tctx->arenas); i += 1, md_arena_ptr += 1)
|
||||
{
|
||||
Arena** conflict_ptr = conflicts;
|
||||
B32 has_conflict = 0;
|
||||
for (U64 j = 0; j < count; j += 1, conflict_ptr += 1)
|
||||
MD_Arena** conflict_ptr = conflicts;
|
||||
MD_B32 has_conflict = 0;
|
||||
for (MD_U64 j = 0; j < count; j += 1, conflict_ptr += 1)
|
||||
{
|
||||
if (*arena_ptr == *conflict_ptr) {
|
||||
if (*md_arena_ptr == *conflict_ptr) {
|
||||
has_conflict = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( ! has_conflict){
|
||||
result = *arena_ptr;
|
||||
result = *md_arena_ptr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,83 +8,83 @@
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
////////////////////////////////
|
||||
// NOTE(allen): Thread Context
|
||||
// NOTE(allen): Thread MD_Context
|
||||
|
||||
typedef struct TCTX TCTX;
|
||||
struct TCTX
|
||||
typedef struct MD_TCTX MD_TCTX;
|
||||
struct MD_TCTX
|
||||
{
|
||||
Arena* arenas[2];
|
||||
MD_Arena* arenas[2];
|
||||
|
||||
U8 thread_name[32];
|
||||
U64 thread_name_size;
|
||||
MD_U8 md_thread_name[32];
|
||||
MD_U64 thread_name_size;
|
||||
|
||||
char* file_name;
|
||||
U64 line_number;
|
||||
MD_U64 line_number;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
// NOTE(allen): Thread Context Functions
|
||||
// NOTE(allen): Thread MD_Context Functions
|
||||
|
||||
MD_API void tctx_init_and_equip (TCTX* tctx);
|
||||
MD_API void tctx_init_and_equip_alloc(TCTX* tctx, AllocatorInfo ainfo);
|
||||
MD_API void tctx_release (void);
|
||||
MD_API TCTX* tctx_get_equipped (void);
|
||||
MD_API void md_tctx_init_and_equip (MD_TCTX* md_tctx);
|
||||
MD_API void md_tctx_init_and_equip_alloc(MD_TCTX* md_tctx, MD_AllocatorInfo ainfo);
|
||||
MD_API void md_tctx_release (void);
|
||||
MD_API MD_TCTX* md_tctx_get_equipped (void);
|
||||
|
||||
MD_API Arena* tctx_get_scratch(Arena** conflicts, U64 count);
|
||||
MD_API MD_Arena* md_tctx_get_scratch(MD_Arena** conflicts, MD_U64 count);
|
||||
|
||||
void tctx_set_thread_name(String8 name);
|
||||
String8 tctx_get_thread_name(void);
|
||||
void md_tctx_set_thread_name(MD_String8 name);
|
||||
MD_String8 md_tctx_get_thread_name(void);
|
||||
|
||||
void tctx_write_srcloc(char* file_name, U64 line_number);
|
||||
void tctx_read_srcloc (char** file_name, U64* line_number);
|
||||
#define tctx_write_this_srcloc() tctx_write_srcloc(__FILE__, __LINE__)
|
||||
void md_tctx_write_srcloc(char* file_name, MD_U64 line_number);
|
||||
void md_tctx_read_srcloc (char** file_name, MD_U64* line_number);
|
||||
#define md_tctx_write_this_srcloc() md_tctx_write_srcloc(__FILE__, __LINE__)
|
||||
|
||||
typedef struct { U64 count; } Opt_ScratchBegin;
|
||||
typedef struct { MD_U64 count; } Opt_ScratchBegin;
|
||||
|
||||
inline TempArena
|
||||
scratch_begin__ainfo(AllocatorInfo ainfo, Opt_ScratchBegin opt) {
|
||||
Arena* arena = extract_arena(ainfo);
|
||||
TempArena scratch = temp_begin(tctx_get_scratch(&arena, arena != nullptr));
|
||||
inline MD_TempArena
|
||||
md_scratch_begin__ainfo(MD_AllocatorInfo ainfo, Opt_ScratchBegin opt) {
|
||||
MD_Arena* arena = md_extract_arena(ainfo);
|
||||
MD_TempArena scratch = md_temp_begin(md_tctx_get_scratch(&arena, arena != md_nullptr));
|
||||
return scratch;
|
||||
}
|
||||
|
||||
force_inline TempArena scratch_begin__arena(Arena** arena, Opt_ScratchBegin opt) { TempArena scratch = temp_begin(tctx_get_scratch(arena, opt.count)); return scratch; }
|
||||
md_force_inline MD_TempArena md_scratch_begin__arena(MD_Arena** arena, Opt_ScratchBegin opt) { MD_TempArena scratch = md_temp_begin(md_tctx_get_scratch(arena, opt.count)); return scratch; }
|
||||
|
||||
#define scratch_begin(conflicts, ...) \
|
||||
#define md_scratch_begin(conflicts, ...) \
|
||||
_Generic(conflicts, \
|
||||
int : scratch_begin__arena, \
|
||||
Arena** : scratch_begin__arena, \
|
||||
AllocatorInfo: scratch_begin__ainfo, \
|
||||
default : assert_generic_sel_fail \
|
||||
) generic_call(conflicts, (Opt_ScratchBegin){__VA_ARGS__})
|
||||
int : md_scratch_begin__arena, \
|
||||
MD_Arena** : md_scratch_begin__arena, \
|
||||
MD_AllocatorInfo: md_scratch_begin__ainfo, \
|
||||
default : md_assert_generic_sel_fail \
|
||||
) md_generic_call(conflicts, (Opt_ScratchBegin){__VA_ARGS__})
|
||||
|
||||
#define scratch_end(scratch) temp_end(scratch)
|
||||
#define scratch_end(scratch) md_temp_end(scratch)
|
||||
|
||||
inline void
|
||||
tctx_set_thread_name(String8 string){
|
||||
TCTX* tctx = tctx_get_equipped();
|
||||
U64 size = clamp_top(string.size, sizeof(tctx->thread_name));
|
||||
memory_copy(tctx->thread_name, string.str, size);
|
||||
tctx->thread_name_size = size;
|
||||
md_tctx_set_thread_name(MD_String8 string){
|
||||
MD_TCTX* md_tctx = md_tctx_get_equipped();
|
||||
MD_U64 size = md_clamp_top(string.size, sizeof(md_tctx->md_thread_name));
|
||||
md_memory_copy(md_tctx->md_thread_name, string.str, size);
|
||||
md_tctx->thread_name_size = size;
|
||||
}
|
||||
|
||||
inline String8
|
||||
tctx_get_thread_name(void) {
|
||||
TCTX* tctx = tctx_get_equipped();
|
||||
String8 result = str8(tctx->thread_name, tctx->thread_name_size);
|
||||
inline MD_String8
|
||||
md_tctx_get_thread_name(void) {
|
||||
MD_TCTX* md_tctx = md_tctx_get_equipped();
|
||||
MD_String8 result = md_str8(md_tctx->md_thread_name, md_tctx->thread_name_size);
|
||||
return(result);
|
||||
}
|
||||
|
||||
inline void
|
||||
tctx_write_srcloc(char* file_name, U64 line_number){
|
||||
TCTX *tctx = tctx_get_equipped();
|
||||
tctx->file_name = file_name;
|
||||
tctx->line_number = line_number;
|
||||
md_tctx_write_srcloc(char* file_name, MD_U64 line_number){
|
||||
MD_TCTX *md_tctx = md_tctx_get_equipped();
|
||||
md_tctx->file_name = file_name;
|
||||
md_tctx->line_number = line_number;
|
||||
}
|
||||
|
||||
inline void
|
||||
tctx_read_srcloc(char** file_name, U64* line_number){
|
||||
TCTX* tctx = tctx_get_equipped();
|
||||
*file_name = tctx->file_name;
|
||||
*line_number = tctx->line_number;
|
||||
md_tctx_read_srcloc(char** file_name, MD_U64* line_number){
|
||||
MD_TCTX* md_tctx = md_tctx_get_equipped();
|
||||
*file_name = md_tctx->file_name;
|
||||
*line_number = md_tctx->line_number;
|
||||
}
|
||||
|
||||
+20
-20
@@ -3,25 +3,25 @@
|
||||
# include "time.h"
|
||||
#endif
|
||||
|
||||
DateTime
|
||||
date_time_from_unix_time(U64 unix_time)
|
||||
MD_DateTime
|
||||
md_date_time_from_unix_time(MD_U64 unix_time)
|
||||
{
|
||||
DateTime date = {0};
|
||||
MD_DateTime date = {0};
|
||||
date.year = 1970;
|
||||
date.day = 1 + (unix_time / 86400);
|
||||
date.sec = (U32) unix_time % 60;
|
||||
date.min = (U32)(unix_time / 60) % 60;
|
||||
date.hour = (U32)(unix_time / 3600) % 24;
|
||||
date.sec = (MD_U32) unix_time % 60;
|
||||
date.md_min = (MD_U32)(unix_time / 60) % 60;
|
||||
date.hour = (MD_U32)(unix_time / 3600) % 24;
|
||||
|
||||
for(;;)
|
||||
{
|
||||
for(date.month = 0; date.month < 12; ++date.month)
|
||||
{
|
||||
U64 c = 0;
|
||||
MD_U64 c = 0;
|
||||
switch(date.month)
|
||||
{
|
||||
case Month_Jan: c = 31; break;
|
||||
case Month_Feb:
|
||||
case MD_Month_Jan: c = 31; break;
|
||||
case MD_Month_Feb:
|
||||
{
|
||||
if((date.year % 4 == 0) && ((date.year % 100) != 0 || (date.year % 400) == 0))
|
||||
{
|
||||
@@ -32,17 +32,17 @@ date_time_from_unix_time(U64 unix_time)
|
||||
c = 28;
|
||||
}
|
||||
} break;
|
||||
case Month_Mar: c = 31; break;
|
||||
case Month_Apr: c = 30; break;
|
||||
case Month_May: c = 31; break;
|
||||
case Month_Jun: c = 30; break;
|
||||
case Month_Jul: c = 31; break;
|
||||
case Month_Aug: c = 31; break;
|
||||
case Month_Sep: c = 30; break;
|
||||
case Month_Oct: c = 31; break;
|
||||
case Month_Nov: c = 30; break;
|
||||
case Month_Dec: c = 31; break;
|
||||
default: invalid_path;
|
||||
case MD_Month_Mar: c = 31; break;
|
||||
case MD_Month_Apr: c = 30; break;
|
||||
case MD_Month_May: c = 31; break;
|
||||
case MD_Month_Jun: c = 30; break;
|
||||
case MD_Month_Jul: c = 31; break;
|
||||
case MD_Month_Aug: c = 31; break;
|
||||
case MD_Month_Sep: c = 30; break;
|
||||
case MD_Month_Oct: c = 31; break;
|
||||
case MD_Month_Nov: c = 30; break;
|
||||
case MD_Month_Dec: c = 31; break;
|
||||
default: md_invalid_path;
|
||||
}
|
||||
if(date.day <= c)
|
||||
{
|
||||
|
||||
+59
-59
@@ -6,110 +6,110 @@
|
||||
////////////////////////////////
|
||||
//~ allen: Time
|
||||
|
||||
typedef enum WeekDay WeekDay;
|
||||
enum WeekDay
|
||||
typedef enum MD_WeekDay MD_WeekDay;
|
||||
enum MD_WeekDay
|
||||
{
|
||||
WeekDay_Sun,
|
||||
WeekDay_Mon,
|
||||
WeekDay_Tue,
|
||||
WeekDay_Wed,
|
||||
WeekDay_Thu,
|
||||
WeekDay_Fri,
|
||||
WeekDay_Sat,
|
||||
WeekDay_COUNT,
|
||||
MD_WeekDay_Sun,
|
||||
MD_WeekDay_Mon,
|
||||
MD_WeekDay_Tue,
|
||||
MD_WeekDay_Wed,
|
||||
MD_WeekDay_Thu,
|
||||
MD_WeekDay_Fri,
|
||||
MD_WeekDay_Sat,
|
||||
MD_WeekDay_COUNT,
|
||||
};
|
||||
|
||||
typedef enum Month Month;
|
||||
enum Month
|
||||
typedef enum MD_Month MD_Month;
|
||||
enum MD_Month
|
||||
{
|
||||
Month_Jan,
|
||||
Month_Feb,
|
||||
Month_Mar,
|
||||
Month_Apr,
|
||||
Month_May,
|
||||
Month_Jun,
|
||||
Month_Jul,
|
||||
Month_Aug,
|
||||
Month_Sep,
|
||||
Month_Oct,
|
||||
Month_Nov,
|
||||
Month_Dec,
|
||||
Month_COUNT,
|
||||
MD_Month_Jan,
|
||||
MD_Month_Feb,
|
||||
MD_Month_Mar,
|
||||
MD_Month_Apr,
|
||||
MD_Month_May,
|
||||
MD_Month_Jun,
|
||||
MD_Month_Jul,
|
||||
MD_Month_Aug,
|
||||
MD_Month_Sep,
|
||||
MD_Month_Oct,
|
||||
MD_Month_Nov,
|
||||
MD_Month_Dec,
|
||||
MD_Month_COUNT,
|
||||
};
|
||||
|
||||
typedef struct DateTime DateTime;
|
||||
struct DateTime
|
||||
typedef struct MD_DateTime MD_DateTime;
|
||||
struct MD_DateTime
|
||||
{
|
||||
U16 micro_sec; // [0,999]
|
||||
U16 msec; // [0,999]
|
||||
U16 sec; // [0,60]
|
||||
U16 min; // [0,59]
|
||||
U16 hour; // [0,24]
|
||||
U16 day; // [0,30]
|
||||
MD_U16 micro_sec; // [0,999]
|
||||
MD_U16 msec; // [0,999]
|
||||
MD_U16 sec; // [0,60]
|
||||
MD_U16 md_min; // [0,59]
|
||||
MD_U16 hour; // [0,24]
|
||||
MD_U16 day; // [0,30]
|
||||
union
|
||||
{
|
||||
WeekDay week_day;
|
||||
U32 wday;
|
||||
MD_WeekDay week_day;
|
||||
MD_U32 wday;
|
||||
};
|
||||
union
|
||||
{
|
||||
Month month;
|
||||
U32 mon;
|
||||
MD_Month month;
|
||||
MD_U32 mon;
|
||||
};
|
||||
U32 year; // 1 = 1 CE, 0 = 1 BC
|
||||
MD_U32 year; // 1 = 1 CE, 0 = 1 BC
|
||||
};
|
||||
|
||||
typedef U64 DenseTime;
|
||||
typedef MD_U64 MD_DenseTime;
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Time Functions
|
||||
|
||||
DenseTime dense_time_from_date_time (DateTime date_time);
|
||||
DateTime date_time_from_dense_time (DenseTime time);
|
||||
DateTime date_time_from_micro_seconds(U64 time);
|
||||
DateTime date_time_from_unix_time (U64 unix_time);
|
||||
MD_DenseTime md_dense_time_from_date_time (MD_DateTime date_time);
|
||||
MD_DateTime md_date_time_from_dense_time (MD_DenseTime time);
|
||||
MD_DateTime md_date_time_from_micro_seconds(MD_U64 time);
|
||||
MD_DateTime md_date_time_from_unix_time (MD_U64 unix_time);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Time Functions
|
||||
|
||||
inline DenseTime
|
||||
dense_time_from_date_time(DateTime date_time) {
|
||||
DenseTime result = 0;
|
||||
inline MD_DenseTime
|
||||
md_dense_time_from_date_time(MD_DateTime date_time) {
|
||||
MD_DenseTime result = 0;
|
||||
result += date_time.year; result *= 12;
|
||||
result += date_time.mon; result *= 31;
|
||||
result += date_time.day; result *= 24;
|
||||
result += date_time.hour; result *= 60;
|
||||
result += date_time.min; result *= 61;
|
||||
result += date_time.md_min; result *= 61;
|
||||
result += date_time.sec; result *= 1000;
|
||||
result += date_time.msec;
|
||||
return(result);
|
||||
}
|
||||
|
||||
inline DateTime
|
||||
date_time_from_dense_time(DenseTime time) {
|
||||
DateTime result = {0};
|
||||
inline MD_DateTime
|
||||
md_date_time_from_dense_time(MD_DenseTime time) {
|
||||
MD_DateTime result = {0};
|
||||
result.msec = time % 1000; time /= 1000;
|
||||
result.sec = time % 61; time /= 61;
|
||||
result.min = time % 60; time /= 60;
|
||||
result.md_min = time % 60; time /= 60;
|
||||
result.hour = time % 24; time /= 24;
|
||||
result.day = time % 31; time /= 31;
|
||||
result.mon = time % 12; time /= 12;
|
||||
assert(time <= MAX_U32);
|
||||
result.year = (U32)time;
|
||||
md_assert(time <= MD_MAX_U32);
|
||||
result.year = (MD_U32)time;
|
||||
return(result);
|
||||
}
|
||||
|
||||
inline DateTime
|
||||
date_time_from_micro_seconds(U64 time){
|
||||
DateTime result = {0};
|
||||
inline MD_DateTime
|
||||
md_date_time_from_micro_seconds(MD_U64 time){
|
||||
MD_DateTime result = {0};
|
||||
result.micro_sec = time % 1000; time /= 1000;
|
||||
result.msec = time % 1000; time /= 1000;
|
||||
result.sec = time % 60; time /= 60;
|
||||
result.min = time % 60; time /= 60;
|
||||
result.md_min = time % 60; time /= 60;
|
||||
result.hour = time % 24; time /= 24;
|
||||
result.day = time % 31; time /= 31;
|
||||
result.mon = time % 12; time /= 12;
|
||||
assert(time <= MAX_U32);
|
||||
result.year = (U32)time;
|
||||
md_assert(time <= MD_MAX_U32);
|
||||
result.year = (MD_U32)time;
|
||||
return(result);
|
||||
}
|
||||
|
||||
+67
-67
@@ -6,110 +6,110 @@
|
||||
////////////////////////////////
|
||||
//~ rjf: Toolchain/Environment Enums
|
||||
|
||||
typedef enum OperatingSystem OperatingSystem;
|
||||
enum OperatingSystem
|
||||
typedef enum MD_OperatingSystem MD_OperatingSystem;
|
||||
enum MD_OperatingSystem
|
||||
{
|
||||
OperatingSystem_Null,
|
||||
OperatingSystem_Windows,
|
||||
OperatingSystem_Linux,
|
||||
OperatingSystem_Mac,
|
||||
OperatingSystem_COUNT,
|
||||
MD_OperatingSystem_Null,
|
||||
MD_OperatingSystem_Windows,
|
||||
MD_OperatingSystem_Linux,
|
||||
MD_OperatingSystem_Mac,
|
||||
MD_OperatingSystem_COUNT,
|
||||
};
|
||||
|
||||
typedef enum ImageType ImageType;
|
||||
enum ImageType
|
||||
typedef enum MD_ImageType MD_ImageType;
|
||||
enum MD_ImageType
|
||||
{
|
||||
Image_Null,
|
||||
Image_CoffPe,
|
||||
Image_Elf32,
|
||||
Image_Elf64,
|
||||
Image_Macho
|
||||
MD_Image_Null,
|
||||
MD_Image_CoffPe,
|
||||
MD_Image_Elf32,
|
||||
MD_Image_Elf64,
|
||||
MD_Image_Macho
|
||||
};
|
||||
|
||||
typedef enum Arch Arch;
|
||||
enum Arch
|
||||
typedef enum MD_Arch MD_Arch;
|
||||
enum MD_Arch
|
||||
{
|
||||
Arch_Null,
|
||||
Arch_x64,
|
||||
Arch_x86,
|
||||
Arch_arm64,
|
||||
Arch_arm32,
|
||||
Arch_COUNT,
|
||||
MD_Arch_Null,
|
||||
MD_Arch_x64,
|
||||
MD_Arch_x86,
|
||||
MD_Arch_arm64,
|
||||
MD_Arch_arm32,
|
||||
MD_Arch_COUNT,
|
||||
};
|
||||
|
||||
typedef enum Compiler Compiler;
|
||||
enum Compiler
|
||||
typedef enum MD_Compiler MD_Compiler;
|
||||
enum MD_Compiler
|
||||
{
|
||||
Compiler_Null,
|
||||
Compiler_msvc,
|
||||
Compiler_gcc,
|
||||
Compiler_clang,
|
||||
Compiler_COUNT,
|
||||
MD_Compiler_Null,
|
||||
MD_Compiler_msvc,
|
||||
MD_Compiler_gcc,
|
||||
MD_Compiler_clang,
|
||||
MD_Compiler_COUNT,
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Toolchain/Environment Enum Functions
|
||||
|
||||
inline U64
|
||||
bit_size_from_arch(Arch arch)
|
||||
inline MD_U64
|
||||
md_bit_size_from_arch(MD_Arch arch)
|
||||
{
|
||||
// TODO(rjf): metacode
|
||||
U64 arch_bitsize = 0;
|
||||
MD_U64 arch_bitsize = 0;
|
||||
switch(arch)
|
||||
{
|
||||
case Arch_x64: arch_bitsize = 64; break;
|
||||
case Arch_x86: arch_bitsize = 32; break;
|
||||
case Arch_arm64: arch_bitsize = 64; break;
|
||||
case Arch_arm32: arch_bitsize = 32; break;
|
||||
case MD_Arch_x64: arch_bitsize = 64; break;
|
||||
case MD_Arch_x86: arch_bitsize = 32; break;
|
||||
case MD_Arch_arm64: arch_bitsize = 64; break;
|
||||
case MD_Arch_arm32: arch_bitsize = 32; break;
|
||||
default: break;
|
||||
}
|
||||
return arch_bitsize;
|
||||
}
|
||||
|
||||
inline U64
|
||||
max_instruction_size_from_arch(Arch arch)
|
||||
inline MD_U64
|
||||
md_max_instruction_size_from_arch(MD_Arch arch)
|
||||
{
|
||||
// TODO(rjf): make this real
|
||||
return 64;
|
||||
}
|
||||
|
||||
inline OperatingSystem
|
||||
operating_system_from_context(void) {
|
||||
OperatingSystem os = OperatingSystem_Null;
|
||||
#if OS_WINDOWS
|
||||
os = OperatingSystem_Windows;
|
||||
#elif OS_LINUX
|
||||
os = OperatingSystem_Linux;
|
||||
#elif OS_MAC
|
||||
os = OperatingSystem_Mac;
|
||||
inline MD_OperatingSystem
|
||||
md_operating_system_from_context(void) {
|
||||
MD_OperatingSystem os = MD_OperatingSystem_Null;
|
||||
#if MD_OS_WINDOWS
|
||||
os = MD_OperatingSystem_Windows;
|
||||
#elif MD_OS_LINUX
|
||||
os = MD_OperatingSystem_Linux;
|
||||
#elif MD_OS_MAC
|
||||
os = MD_OperatingSystem_Mac;
|
||||
#endif
|
||||
return os;
|
||||
}
|
||||
|
||||
inline Arch
|
||||
arch_from_context(void) {
|
||||
Arch arch = Arch_Null;
|
||||
#if ARCH_X64
|
||||
arch = Arch_x64;
|
||||
#elif ARCH_X86
|
||||
arch = Arch_x86;
|
||||
#elif ARCH_ARM64
|
||||
arch = Arch_arm64;
|
||||
#elif ARCH_ARM32
|
||||
arch = Arch_arm32;
|
||||
inline MD_Arch
|
||||
md_arch_from_contexto(void) {
|
||||
MD_Arch arch = MD_Arch_Null;
|
||||
#if MD_ARCH_X64
|
||||
arch = MD_Arch_x64;
|
||||
#elif MD_ARCH_X86
|
||||
arch = MD_Arch_x86;
|
||||
#elif MD_ARCH_ARM64
|
||||
arch = MD_Arch_arm64;
|
||||
#elif MD_ARCH_ARM32
|
||||
arch = MD_Arch_arm32;
|
||||
#endif
|
||||
return arch;
|
||||
}
|
||||
|
||||
inline Compiler
|
||||
compiler_from_context(void) {
|
||||
Compiler compiler = Compiler_Null;
|
||||
#if COMPILER_MSVC
|
||||
compiler = Compiler_msvc;
|
||||
#elif COMPILER_GCC
|
||||
compiler = Compiler_gcc;
|
||||
#elif COMPILER_CLANG
|
||||
compiler = Compiler_clang;
|
||||
inline MD_Compiler
|
||||
md_compiler_from_context(void) {
|
||||
MD_Compiler compiler = MD_Compiler_Null;
|
||||
#if MD_COMPILER_MSVC
|
||||
compiler = MD_Compiler_msvc;
|
||||
#elif MD_COMPILER_GCC
|
||||
compiler = MD_Compiler_gcc;
|
||||
#elif MD_COMPILER_CLANG
|
||||
compiler = MD_Compiler_clang;
|
||||
#endif
|
||||
return compiler;
|
||||
}
|
||||
|
||||
+316
-316
File diff suppressed because it is too large
Load Diff
+308
-308
@@ -9,249 +9,249 @@
|
||||
////////////////////////////////
|
||||
//~ rjf: Messages
|
||||
|
||||
typedef enum MsgKind
|
||||
typedef enum MD_MsgKind
|
||||
{
|
||||
MsgKind_Null,
|
||||
MsgKind_Note,
|
||||
MsgKind_Warning,
|
||||
MsgKind_Error,
|
||||
MsgKind_FatalError,
|
||||
MD_MsgKind_Null,
|
||||
MD_MsgKind_Note,
|
||||
MD_MsgKind_Warning,
|
||||
MD_MsgKind_Error,
|
||||
MD_MsgKind_FatalError,
|
||||
}
|
||||
MsgKind;
|
||||
MD_MsgKind;
|
||||
|
||||
typedef struct Node Node;
|
||||
typedef struct Msg Msg;
|
||||
struct Msg
|
||||
typedef struct MD_Node MD_Node;
|
||||
typedef struct MD_Msg MD_Msg;
|
||||
struct MD_Msg
|
||||
{
|
||||
Msg* next;
|
||||
Node* node;
|
||||
MsgKind kind;
|
||||
String8 string;
|
||||
MD_Msg* next;
|
||||
MD_Node* node;
|
||||
MD_MsgKind kind;
|
||||
MD_String8 string;
|
||||
};
|
||||
|
||||
typedef struct MsgList MsgList;
|
||||
struct MsgList
|
||||
typedef struct MD_MsgList MD_MsgList;
|
||||
struct MD_MsgList
|
||||
{
|
||||
Msg* first;
|
||||
Msg* last;
|
||||
U64 count;
|
||||
MsgKind worst_message_kind;
|
||||
MD_Msg* first;
|
||||
MD_Msg* last;
|
||||
MD_U64 count;
|
||||
MD_MsgKind worst_message_kind;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Token Types
|
||||
//~ rjf: MD_Token Types
|
||||
|
||||
typedef U32 TokenFlags;
|
||||
typedef MD_U32 MD_TokenFlags;
|
||||
enum
|
||||
{
|
||||
// TODO(Ed): Track type of comment, and opening/closing main delimiter.
|
||||
// (The parser needs that info later and just forces str_matches that werent necessary)
|
||||
// (The parser needs that info later and just forces md_str_matches that werent necessary)
|
||||
|
||||
// rjf: base kind info
|
||||
TokenFlag_Identifier = (1 << 0),
|
||||
TokenFlag_Numeric = (1 << 1),
|
||||
TokenFlag_StringLiteral = (1 << 2),
|
||||
TokenFlag_Symbol = (1 << 3),
|
||||
TokenFlag_Reserved = (1 << 4),
|
||||
TokenFlag_Comment = (1 << 5),
|
||||
TokenFlag_Whitespace = (1 << 6),
|
||||
TokenFlag_Newline = (1 << 7),
|
||||
MD_TokenFlag_Identifier = (1 << 0),
|
||||
MD_TokenFlag_Numeric = (1 << 1),
|
||||
MD_TokenFlag_StringLiteral = (1 << 2),
|
||||
MD_TokenFlag_Symbol = (1 << 3),
|
||||
MD_TokenFlag_Reserved = (1 << 4),
|
||||
MD_TokenFlag_Comment = (1 << 5),
|
||||
MD_TokenFlag_Whitespace = (1 << 6),
|
||||
MD_TokenFlag_Newline = (1 << 7),
|
||||
|
||||
// rjf: decoration info
|
||||
TokenFlag_StringSingleQuote = (1 << 8),
|
||||
TokenFlag_StringDoubleQuote = (1 << 9),
|
||||
TokenFlag_StringTick = (1 << 10),
|
||||
TokenFlag_StringTriplet = (1 << 11),
|
||||
MD_TokenFlag_StringSingleQuote = (1 << 8),
|
||||
MD_TokenFlag_StringDoubleQuote = (1 << 9),
|
||||
MD_TokenFlag_StringTick = (1 << 10),
|
||||
MD_TokenFlag_StringTriplet = (1 << 11),
|
||||
|
||||
// rjf: error info
|
||||
TokenFlag_BrokenComment = (1 << 12),
|
||||
TokenFlag_BrokenStringLiteral = (1 << 13),
|
||||
TokenFlag_BadCharacter = (1 << 14),
|
||||
MD_TokenFlag_BrokenComment = (1 << 12),
|
||||
MD_TokenFlag_BrokenStringLiteral = (1 << 13),
|
||||
MD_TokenFlag_BadCharacter = (1 << 14),
|
||||
};
|
||||
|
||||
typedef U32 TokenFlagGroups;
|
||||
typedef MD_U32 MD_TokenFlagGroups;
|
||||
enum
|
||||
{
|
||||
TokenFlagGroup_Comment = TokenFlag_Comment,
|
||||
TokenFlagGroup_Whitespace = (TokenFlag_Whitespace| TokenFlag_Newline),
|
||||
TokenFlagGroup_Irregular = (TokenFlagGroup_Comment | TokenFlagGroup_Whitespace),
|
||||
TokenFlagGroup_Regular = ~TokenFlagGroup_Irregular,
|
||||
TokenFlagGroup_Label = (TokenFlag_Identifier | TokenFlag_Numeric | TokenFlag_StringLiteral | TokenFlag_Symbol),
|
||||
TokenFlagGroup_Error = (TokenFlag_BrokenComment | TokenFlag_BrokenStringLiteral | TokenFlag_BadCharacter),
|
||||
MD_TokenFlagGroup_Comment = MD_TokenFlag_Comment,
|
||||
MD_TokenFlagGroup_Whitespace = (MD_TokenFlag_Whitespace| MD_TokenFlag_Newline),
|
||||
MD_TokenFlagGroup_Irregular = (MD_TokenFlagGroup_Comment | MD_TokenFlagGroup_Whitespace),
|
||||
MD_TokenFlagGroup_Regular = ~MD_TokenFlagGroup_Irregular,
|
||||
MD_TokenFlagGroup_Label = (MD_TokenFlag_Identifier | MD_TokenFlag_Numeric | MD_TokenFlag_StringLiteral | MD_TokenFlag_Symbol),
|
||||
MD_TokenFlagGroup_Error = (MD_TokenFlag_BrokenComment | MD_TokenFlag_BrokenStringLiteral | MD_TokenFlag_BadCharacter),
|
||||
};
|
||||
|
||||
typedef struct Token Token;
|
||||
struct Token
|
||||
typedef struct MD_Token MD_Token;
|
||||
struct MD_Token
|
||||
{
|
||||
Rng1U64 range;
|
||||
TokenFlags flags;
|
||||
MD_Rng1U64 range;
|
||||
MD_TokenFlags flags;
|
||||
};
|
||||
|
||||
typedef struct TokenChunkNode TokenChunkNode;
|
||||
struct TokenChunkNode
|
||||
typedef struct MD_TokenChunkNode MD_TokenChunkNode;
|
||||
struct MD_TokenChunkNode
|
||||
{
|
||||
TokenChunkNode* next;
|
||||
Token* v;
|
||||
U64 count;
|
||||
U64 cap;
|
||||
MD_TokenChunkNode* next;
|
||||
MD_Token* v;
|
||||
MD_U64 count;
|
||||
MD_U64 cap;
|
||||
};
|
||||
|
||||
typedef struct TokenChunkList TokenChunkList;
|
||||
struct TokenChunkList
|
||||
typedef struct MD_TokenChunkList MD_TokenChunkList;
|
||||
struct MD_TokenChunkList
|
||||
{
|
||||
TokenChunkNode* first;
|
||||
TokenChunkNode* last;
|
||||
U64 chunk_count;
|
||||
U64 total_token_count;
|
||||
MD_TokenChunkNode* first;
|
||||
MD_TokenChunkNode* last;
|
||||
MD_U64 chunk_count;
|
||||
MD_U64 total_token_count;
|
||||
};
|
||||
|
||||
typedef struct TokenArray TokenArray;
|
||||
struct TokenArray
|
||||
typedef struct MD_TokenArray MD_TokenArray;
|
||||
struct MD_TokenArray
|
||||
{
|
||||
Token* v;
|
||||
U64 count;
|
||||
MD_Token* v;
|
||||
MD_U64 count;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Node Types
|
||||
//~ rjf: MD_Node Types
|
||||
|
||||
typedef enum NodeKind NodeKind;
|
||||
enum NodeKind
|
||||
typedef enum MD_NodeKind MD_NodeKind;
|
||||
enum MD_NodeKind
|
||||
{
|
||||
NodeKind_Nil,
|
||||
NodeKind_File,
|
||||
NodeKind_ErrorMarker,
|
||||
NodeKind_Main,
|
||||
NodeKind_Tag,
|
||||
NodeKind_List,
|
||||
NodeKind_Reference,
|
||||
NodeKind_COUNT
|
||||
MD_NodeKind_Nil,
|
||||
MD_NodeKind_File,
|
||||
MD_NodeKind_ErrorMarker,
|
||||
MD_NodeKind_Main,
|
||||
MD_NodeKind_Tag,
|
||||
MD_NodeKind_List,
|
||||
MD_NodeKind_Reference,
|
||||
MD_NodeKind_COUNT
|
||||
};
|
||||
|
||||
typedef U32 NodeFlags;
|
||||
typedef MD_U32 NodeFlags;
|
||||
enum
|
||||
{
|
||||
NodeFlag_MaskSetDelimiters = (0x3F << 0),
|
||||
NodeFlag_HasParenLeft = (1 << 0),
|
||||
NodeFlag_HasParenRight = (1 << 1),
|
||||
NodeFlag_HasBracketLeft = (1 << 2),
|
||||
NodeFlag_HasBracketRight = (1 << 3),
|
||||
NodeFlag_HasBraceLeft = (1 << 4),
|
||||
NodeFlag_HasBraceRight = (1 << 5),
|
||||
MD_NodeFlag_MaskSetDelimiters = (0x3F << 0),
|
||||
MD_NodeFlag_HasParenLeft = (1 << 0),
|
||||
MD_NodeFlag_HasParenRight = (1 << 1),
|
||||
MD_NodeFlag_HasBracketLeft = (1 << 2),
|
||||
MD_NodeFlag_HasBracketRight = (1 << 3),
|
||||
MD_NodeFlag_HasBraceLeft = (1 << 4),
|
||||
MD_NodeFlag_HasBraceRight = (1 << 5),
|
||||
|
||||
NodeFlag_MaskSeparators = (0xF << 6),
|
||||
NodeFlag_IsBeforeSemicolon = (1 << 6),
|
||||
NodeFlag_IsAfterSemicolon = (1 << 7),
|
||||
NodeFlag_IsBeforeComma = (1 << 8),
|
||||
NodeFlag_IsAfterComma = (1 << 9),
|
||||
MD_NodeFlag_MaskSeparators = (0xF << 6),
|
||||
MD_NodeFlag_IsBeforeSemicolon = (1 << 6),
|
||||
MD_NodeFlag_IsAfterSemicolon = (1 << 7),
|
||||
MD_NodeFlag_IsBeforeComma = (1 << 8),
|
||||
MD_NodeFlag_IsAfterComma = (1 << 9),
|
||||
|
||||
NodeFlag_MaskStringDelimiters = (0xF << 10),
|
||||
NodeFlag_StringSingleQuote = (1 << 10),
|
||||
NodeFlag_StringDoubleQuote = (1 << 11),
|
||||
NodeFlag_StringTick = (1 << 12),
|
||||
NodeFlag_StringTriplet = (1 << 13),
|
||||
MD_NodeFlag_MaskStringDelimiters = (0xF << 10),
|
||||
MD_NodeFlag_StringSingleQuote = (1 << 10),
|
||||
MD_NodeFlag_StringDoubleQuote = (1 << 11),
|
||||
MD_NodeFlag_StringTick = (1 << 12),
|
||||
MD_NodeFlag_StringTriplet = (1 << 13),
|
||||
|
||||
NodeFlag_MaskLabelKind = (0xF << 14),
|
||||
NodeFlag_Numeric = (1 << 14),
|
||||
NodeFlag_Identifier = (1 << 15),
|
||||
NodeFlag_StringLiteral = (1 << 16),
|
||||
NodeFlag_Symbol = (1 << 17),
|
||||
MD_NodeFlag_MaskLabelKind = (0xF << 14),
|
||||
MD_NodeFlag_Numeric = (1 << 14),
|
||||
MD_NodeFlag_Identifier = (1 << 15),
|
||||
MD_NodeFlag_StringLiteral = (1 << 16),
|
||||
MD_NodeFlag_Symbol = (1 << 17),
|
||||
};
|
||||
#define NodeFlag_AfterFromBefore(f) ((f) << 1)
|
||||
#define MD_NodeFlag_AfterFromBefore(f) ((f) << 1)
|
||||
|
||||
typedef struct Node Node;
|
||||
struct Node
|
||||
typedef struct MD_Node MD_Node;
|
||||
struct MD_Node
|
||||
{
|
||||
// rjf: tree links
|
||||
Node* next;
|
||||
Node* prev;
|
||||
Node* parent;
|
||||
Node* first;
|
||||
Node* last;
|
||||
MD_Node* next;
|
||||
MD_Node* prev;
|
||||
MD_Node* parent;
|
||||
MD_Node* first;
|
||||
MD_Node* last;
|
||||
|
||||
// rjf: tag links
|
||||
Node* first_tag;
|
||||
Node* last_tag;
|
||||
MD_Node* first_tag;
|
||||
MD_Node* last_tag;
|
||||
|
||||
// rjf: node info
|
||||
NodeKind kind;
|
||||
MD_NodeKind kind;
|
||||
NodeFlags flags;
|
||||
String8 string;
|
||||
String8 raw_string;
|
||||
MD_String8 string;
|
||||
MD_String8 raw_string;
|
||||
|
||||
// rjf: source code info
|
||||
U64 src_offset;
|
||||
MD_U64 src_offset;
|
||||
|
||||
// rjf: user-controlled generation number
|
||||
//
|
||||
// (unused by mdesk layer, but can be used by usage code to use Node trees
|
||||
// (unused by mdesk layer, but can be used by usage code to use MD_Node trees
|
||||
// in a "retained mode" way, where stable generational handles can be formed
|
||||
// to nodes)
|
||||
U64 user_gen;
|
||||
MD_U64 user_gen;
|
||||
|
||||
// rjf: extra padding to 128 bytes
|
||||
U64 _unused_[2];
|
||||
MD_U64 _unused_[2];
|
||||
};
|
||||
|
||||
typedef struct NodeRec NodeRec;
|
||||
struct NodeRec
|
||||
typedef struct MD_NodeRec MD_NodeRec;
|
||||
struct MD_NodeRec
|
||||
{
|
||||
Node* next;
|
||||
S32 push_count;
|
||||
S32 pop_count;
|
||||
MD_Node* next;
|
||||
MD_S32 md_push_count;
|
||||
MD_S32 pop_count;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Text -> Tokens Types
|
||||
|
||||
typedef struct TokenizeResult TokenizeResult;
|
||||
struct TokenizeResult
|
||||
typedef struct MD_TokenizeResult MD_TokenizeResult;
|
||||
struct MD_TokenizeResult
|
||||
{
|
||||
TokenArray tokens;
|
||||
MsgList msgs;
|
||||
MD_TokenArray tokens;
|
||||
MD_MsgList msgs;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Tokens -> Tree Types
|
||||
|
||||
typedef struct ParseResult ParseResult;
|
||||
struct ParseResult
|
||||
typedef struct MD_ParseResult MD_ParseResult;
|
||||
struct MD_ParseResult
|
||||
{
|
||||
Node* root;
|
||||
MsgList msgs;
|
||||
MD_Node* root;
|
||||
MD_MsgList msgs;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
// Context
|
||||
// MD_Context
|
||||
|
||||
typedef struct Context Context;
|
||||
struct Context
|
||||
typedef struct MD_Context MD_Context;
|
||||
struct MD_Context
|
||||
{
|
||||
// Currently, this is only relevant if the user is utilizing this library via bindings
|
||||
// or they are not utilizing metadesk's hosted `entry_point` runtime
|
||||
// or they are not utilizing metadesk's hosted `md_entry_point` runtime
|
||||
|
||||
// Its recommended that the user hooks up
|
||||
// their own arena allocators to the thread context
|
||||
// which will be utilized for thread local scratch arena
|
||||
TCTX thread_ctx;
|
||||
MD_TCTX thread_ctx;
|
||||
|
||||
// Just as with TCTX its recommended the user setup the arena allocators
|
||||
// Just as with MD_TCTX its recommended the user setup the arena allocators
|
||||
// for te os context
|
||||
OS_Context os_ctx;
|
||||
MD_OS_Context os_ctx;
|
||||
|
||||
// This skips the os_init process but that means the user is expected to setup
|
||||
// This skips the md_os_init process but that means the user is expected to setup
|
||||
// the thread context's arenas for the process
|
||||
B32 dont_init_os;
|
||||
MD_B32 dont_init_os;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Globals
|
||||
|
||||
inline Node*
|
||||
nil_node()
|
||||
inline MD_Node*
|
||||
md_nil_node()
|
||||
{
|
||||
read_only local_persist
|
||||
Node nil =
|
||||
md_read_only md_local_persist
|
||||
MD_Node nil =
|
||||
{
|
||||
&nil,
|
||||
&nil,
|
||||
@@ -265,135 +265,135 @@ nil_node()
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
// Context lifetime Functios
|
||||
// MD_Context lifetime Functios
|
||||
|
||||
// NOTE(Ed): The are see comments in Context struct, this is only necessary when not utilizing
|
||||
// the metadesk os runtime provided entry_point interface
|
||||
// NOTE(Ed): The are see comments in MD_Context struct, this is only necessary when not utilizing
|
||||
// the metadesk os runtime provided md_entry_point interface
|
||||
|
||||
MD_API void init(Context* ctx);
|
||||
MD_API void deinit(Context* ctx); // Does nothing for now.
|
||||
MD_API void md_init(MD_Context* ctx);
|
||||
MD_API void md_deinit(MD_Context* ctx); // Does nothing for now.
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Message Type Functions
|
||||
|
||||
void msg_list_push__arena (Arena* arena, MsgList* msgs, Node* node, MsgKind kind, String8 string);
|
||||
MD_API void msg_list_push__ainfo (AllocatorInfo ainfo, MsgList* msgs, Node* node, MsgKind kind, String8 string);
|
||||
void msg_list_pushf__arena(Arena* arena, MsgList* msgs, Node* node, MsgKind kind, char *fmt, ...);
|
||||
void msg_list_pushf__ainfo(AllocatorInfo ainfo, MsgList* msgs, Node* node, MsgKind kind, char *fmt, ...);
|
||||
void md_msg_list_push__arena (MD_Arena* arena, MD_MsgList* msgs, MD_Node* node, MD_MsgKind kind, MD_String8 string);
|
||||
MD_API void md_msg_list_push__ainfo (MD_AllocatorInfo ainfo, MD_MsgList* msgs, MD_Node* node, MD_MsgKind kind, MD_String8 string);
|
||||
void md_msg_list_pushf__arena(MD_Arena* arena, MD_MsgList* msgs, MD_Node* node, MD_MsgKind kind, char *fmt, ...);
|
||||
void md_msg_list_pushf__ainfo(MD_AllocatorInfo ainfo, MD_MsgList* msgs, MD_Node* node, MD_MsgKind kind, char *fmt, ...);
|
||||
|
||||
#define msg_list_push(allocator, msgs, node, kind, string) _Generic(allocator, Arena*: msg_list_push__arena, AllocatorInfo: msg_list_push__ainfo, default: assert_generic_sel_fail) generic_call(allocator, msgs, node, kind, string)
|
||||
#define msg_list_pushf(allocator, msgs, node, kind, string, fmt, ...) _Generic(allocator, Arena*: msg_list_pushf__arena, AllocatorInfo: msg_list_pushf__ainfo, default: assert_generic_sel_fail) generic_call(allocator, msgs, node, kind, fmt, __VA_ARGS__)
|
||||
#define md_msg_list_push(allocator, msgs, node, kind, string) _Generic(allocator, MD_Arena*: md_msg_list_push__arena, MD_AllocatorInfo: md_msg_list_push__ainfo, default: md_assert_generic_sel_fail) md_generic_call(allocator, msgs, node, kind, string)
|
||||
#define md_msg_list_pushf(allocator, msgs, node, kind, string, fmt, ...) _Generic(allocator, MD_Arena*: md_msg_list_pushf__arena, MD_AllocatorInfo: md_msg_list_pushf__ainfo, default: md_assert_generic_sel_fail) md_generic_call(allocator, msgs, node, kind, fmt, __VA_ARGS__)
|
||||
|
||||
MD_API void msg_list_concat_in_place(MsgList* dst, MsgList* to_push);
|
||||
MD_API void md_msg_list_concat_in_place(MD_MsgList* dst, MD_MsgList* to_push);
|
||||
|
||||
force_inline void msg_list_push__arena(Arena* arena, MsgList* msgs, Node* node, MsgKind kind, String8 string) { msg_list_push__ainfo(arena_allocator(arena), msgs, node, kind, string); }
|
||||
md_force_inline void md_msg_list_push__arena(MD_Arena* arena, MD_MsgList* msgs, MD_Node* node, MD_MsgKind kind, MD_String8 string) { md_msg_list_push__ainfo(md_arena_allocator(arena), msgs, node, kind, string); }
|
||||
|
||||
inline void
|
||||
msg_list_pushf__arena(Arena* arena, MsgList* msgs, Node* node, MsgKind kind, char* fmt, ...) {
|
||||
md_msg_list_pushf__arena(MD_Arena* arena, MD_MsgList* msgs, MD_Node* node, MD_MsgKind kind, char* fmt, ...) {
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
String8 string = str8fv(arena, fmt, args);
|
||||
msg_list_push(arena, msgs, node, kind, string);
|
||||
MD_String8 string = md_str8fv(arena, fmt, args);
|
||||
md_msg_list_push(arena, msgs, node, kind, string);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
inline void
|
||||
msg_list_pushf__ainfo(AllocatorInfo ainfo, MsgList* msgs, Node* node, MsgKind kind, char* fmt, ...) {
|
||||
md_msg_list_pushf__ainfo(MD_AllocatorInfo ainfo, MD_MsgList* msgs, MD_Node* node, MD_MsgKind kind, char* fmt, ...) {
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
String8 string = str8fv(ainfo, fmt, args);
|
||||
msg_list_push(ainfo, msgs, node, kind, string);
|
||||
MD_String8 string = md_str8fv(ainfo, fmt, args);
|
||||
md_msg_list_push(ainfo, msgs, node, kind, string);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Token Type Functions
|
||||
//~ rjf: MD_Token Type Functions
|
||||
|
||||
Token token_make (Rng1U64 range, TokenFlags flags);
|
||||
B32 token_match(Token a, Token b);
|
||||
MD_Token md_token_make (MD_Rng1U64 range, MD_TokenFlags flags);
|
||||
MD_B32 md_token_match(MD_Token a, MD_Token b);
|
||||
|
||||
MD_API String8 content_string_from_token_flags_str8(TokenFlags flags, String8 string);
|
||||
MD_API MD_String8 content_string_from_token_flags_str8(MD_TokenFlags flags, MD_String8 string);
|
||||
|
||||
String8List string_list_from_token_flags__arena(Arena* arena, TokenFlags flags);
|
||||
MD_API String8List string_list_from_token_flags__ainfo(AllocatorInfo ainfo, TokenFlags flags);
|
||||
MD_API void token_chunk_list_push__arena (Arena* arena, TokenChunkList* list, U64 cap, Token token);
|
||||
MD_API void token_chunk_list_push__ainfo (AllocatorInfo ainfo, TokenChunkList* list, U64 cap, Token token);
|
||||
MD_API TokenArray token_array_from_chunk_list__arena (Arena* arena, TokenChunkList* chunks);
|
||||
MD_API TokenArray token_array_from_chunk_list__ainfo (AllocatorInfo ainfo, TokenChunkList* chunks);
|
||||
MD_String8List md_string_list_from_token_flags__arena(MD_Arena* arena, MD_TokenFlags flags);
|
||||
MD_API MD_String8List md_string_list_from_token_flags__ainfo(MD_AllocatorInfo ainfo, MD_TokenFlags flags);
|
||||
MD_API void md_token_chunk_list_push__arena (MD_Arena* arena, MD_TokenChunkList* list, MD_U64 cap, MD_Token token);
|
||||
MD_API void md_token_chunk_list_push__ainfo (MD_AllocatorInfo ainfo, MD_TokenChunkList* list, MD_U64 cap, MD_Token token);
|
||||
MD_API MD_TokenArray md_token_array_from_chunk_list__arena (MD_Arena* arena, MD_TokenChunkList* chunks);
|
||||
MD_API MD_TokenArray md_token_array_from_chunk_list__ainfo (MD_AllocatorInfo ainfo, MD_TokenChunkList* chunks);
|
||||
|
||||
#define string_list_from_token_flags(allocator, flags) _Generic(allocator, Arena*: string_list_from_token_flags__arena, AllocatorInfo: string_list_from_token_flags__ainfo, default: assert_generic_sel_fail) generic_call(allocator, flags)
|
||||
#define token_chunk_list_push(allocator, list, cap, token) _Generic(allocator, Arena*: token_chunk_list_push__arena, AllocatorInfo: token_chunk_list_push__ainfo, default: assert_generic_sel_fail) generic_call(allocator, list, cap, token)
|
||||
#define token_array_from_chunk_list(allocator, chunks) _Generic(allocator, Arena*: token_array_from_chunk_list__arena, AllocatorInfo: token_array_from_chunk_list__ainfo, default: assert_generic_sel_fail) generic_call(allocator, chunks)
|
||||
#define md_string_list_from_token_flags(allocator, flags) _Generic(allocator, MD_Arena*: md_string_list_from_token_flags__arena, MD_AllocatorInfo: md_string_list_from_token_flags__ainfo, default: md_assert_generic_sel_fail) md_generic_call(allocator, flags)
|
||||
#define md_token_chunk_list_push(allocator, list, cap, token) _Generic(allocator, MD_Arena*: md_token_chunk_list_push__arena, MD_AllocatorInfo: md_token_chunk_list_push__ainfo, default: md_assert_generic_sel_fail) md_generic_call(allocator, list, cap, token)
|
||||
#define md_token_array_from_chunk_list(allocator, chunks) _Generic(allocator, MD_Arena*: md_token_array_from_chunk_list__arena, MD_AllocatorInfo: md_token_array_from_chunk_list__ainfo, default: md_assert_generic_sel_fail) md_generic_call(allocator, chunks)
|
||||
|
||||
force_inline String8List string_list_from_token_flags__arena(Arena* arena, TokenFlags flags) { return string_list_from_token_flags__ainfo(arena_allocator(arena), flags); }
|
||||
force_inline void token_chunk_list_push__arena (Arena* arena, TokenChunkList* list, U64 cap, Token token) { token_chunk_list_push__ainfo(arena_allocator(arena), list, cap, token); }
|
||||
force_inline TokenArray token_array_from_chunk_list__arena (Arena* arena, TokenChunkList* chunks) { return token_array_from_chunk_list__ainfo(arena_allocator(arena), chunks); }
|
||||
md_force_inline MD_String8List md_string_list_from_token_flags__arena(MD_Arena* arena, MD_TokenFlags flags) { return md_string_list_from_token_flags__ainfo(md_arena_allocator(arena), flags); }
|
||||
md_force_inline void md_token_chunk_list_push__arena (MD_Arena* arena, MD_TokenChunkList* list, MD_U64 cap, MD_Token token) { md_token_chunk_list_push__ainfo(md_arena_allocator(arena), list, cap, token); }
|
||||
md_force_inline MD_TokenArray md_token_array_from_chunk_list__arena (MD_Arena* arena, MD_TokenChunkList* chunks) { return md_token_array_from_chunk_list__ainfo(md_arena_allocator(arena), chunks); }
|
||||
|
||||
inline Token
|
||||
token_make(Rng1U64 range, TokenFlags flags) {
|
||||
Token token = { range, flags };
|
||||
inline MD_Token
|
||||
md_token_make(MD_Rng1U64 range, MD_TokenFlags flags) {
|
||||
MD_Token token = { range, flags };
|
||||
return token;
|
||||
}
|
||||
|
||||
inline B32
|
||||
token_match(Token a, Token b) {
|
||||
return (a.range.min == b.range.min &&
|
||||
a.range.max == b.range.max &&
|
||||
inline MD_B32
|
||||
md_token_match(MD_Token a, MD_Token b) {
|
||||
return (a.range.md_min == b.range.md_min &&
|
||||
a.range.md_max == b.range.md_max &&
|
||||
a.flags == b.flags );
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Node Type Functions
|
||||
//~ rjf: MD_Node Type Functions
|
||||
|
||||
//- rjf: flag conversions
|
||||
|
||||
inline NodeFlags
|
||||
node_flags_from_token_flags(TokenFlags flags)
|
||||
md_node_flags_from_token_flags(MD_TokenFlags flags)
|
||||
{
|
||||
NodeFlags result = 0;
|
||||
result |= NodeFlag_Identifier *!! (flags & TokenFlag_Identifier );
|
||||
result |= NodeFlag_Numeric *!! (flags & TokenFlag_Numeric );
|
||||
result |= NodeFlag_StringLiteral *!! (flags & TokenFlag_StringLiteral );
|
||||
result |= NodeFlag_Symbol *!! (flags & TokenFlag_Symbol );
|
||||
result |= NodeFlag_StringSingleQuote *!! (flags & TokenFlag_StringSingleQuote);
|
||||
result |= NodeFlag_StringDoubleQuote *!! (flags & TokenFlag_StringDoubleQuote);
|
||||
result |= NodeFlag_StringTick *!! (flags & TokenFlag_StringTick );
|
||||
result |= NodeFlag_StringTriplet *!! (flags & TokenFlag_StringTriplet );
|
||||
result |= MD_NodeFlag_Identifier *!! (flags & MD_TokenFlag_Identifier );
|
||||
result |= MD_NodeFlag_Numeric *!! (flags & MD_TokenFlag_Numeric );
|
||||
result |= MD_NodeFlag_StringLiteral *!! (flags & MD_TokenFlag_StringLiteral );
|
||||
result |= MD_NodeFlag_Symbol *!! (flags & MD_TokenFlag_Symbol );
|
||||
result |= MD_NodeFlag_StringSingleQuote *!! (flags & MD_TokenFlag_StringSingleQuote);
|
||||
result |= MD_NodeFlag_StringDoubleQuote *!! (flags & MD_TokenFlag_StringDoubleQuote);
|
||||
result |= MD_NodeFlag_StringTick *!! (flags & MD_TokenFlag_StringTick );
|
||||
result |= MD_NodeFlag_StringTriplet *!! (flags & MD_TokenFlag_StringTriplet );
|
||||
return result;
|
||||
}
|
||||
|
||||
//- rjf: nil
|
||||
|
||||
B32 node_is_nil(Node* node) { return (node == 0 || node == nil_node() || node->kind == NodeKind_Nil); }
|
||||
MD_B32 md_node_is_nil(MD_Node* node) { return (node == 0 || node == md_nil_node() || node->kind == MD_NodeKind_Nil); }
|
||||
|
||||
//- rjf: iteration
|
||||
|
||||
#define each_node(it, first) (Node* it = first; !node_is_nil(it); it = it->next)
|
||||
#define md_each_node(it, first) (MD_Node* it = first; !md_node_is_nil(it); it = it->next)
|
||||
|
||||
MD_API NodeRec node_rec_depth_first(Node* node, Node* subtree_root, U64 child_off, U64 sib_off);
|
||||
MD_API MD_NodeRec md_node_rec_depth_first(MD_Node* node, MD_Node* subtree_root, MD_U64 child_off, MD_U64 sib_off);
|
||||
|
||||
#define node_rec_depth_first_pre(node, subtree_root) node_rec_depth_first((node), (subtree_root), offset_of(Node, first), offset_of(Node, next))
|
||||
#define node_rec_depth_first_pre_rev(node, subtree_root) node_rec_depth_first((node), (subtree_root), offset_of(Node, last), offset_of(Node, prev))
|
||||
#define md_node_rec_depth_first_pre(node, subtree_root) md_node_rec_depth_first((node), (subtree_root), md_offset_of(MD_Node, first), md_offset_of(MD_Node, next))
|
||||
#define md_node_rec_depth_first_pre_rev(node, subtree_root) md_node_rec_depth_first((node), (subtree_root), md_offset_of(MD_Node, last), md_offset_of(MD_Node, prev))
|
||||
|
||||
//- rjf: tree building
|
||||
|
||||
Node* push_node__arena(Arena* arena, NodeKind kind, NodeFlags flags, String8 string, String8 raw_string, U64 src_offset);
|
||||
Node* push_node__ainfo(AllocatorInfo ainfo, NodeKind kind, NodeFlags flags, String8 string, String8 raw_string, U64 src_offset);
|
||||
MD_Node* md_push_node__arena(MD_Arena* arena, MD_NodeKind kind, NodeFlags flags, MD_String8 string, MD_String8 raw_string, MD_U64 src_offset);
|
||||
MD_Node* md_push_node__ainfo(MD_AllocatorInfo ainfo, MD_NodeKind kind, NodeFlags flags, MD_String8 string, MD_String8 raw_string, MD_U64 src_offset);
|
||||
|
||||
#define push_node(allocator, kind, flags, string, raw_string, src_offset) _Generic(allocator, Arena*: push_node__arena, AllocatorInfo: push_node__ainfo, default: assert_generic_sel_fail) generic_call(allocator, kind, flags, string, raw_string, src_offset)
|
||||
#define md_push_node(allocator, kind, flags, string, raw_string, src_offset) _Generic(allocator, MD_Arena*: md_push_node__arena, MD_AllocatorInfo: md_push_node__ainfo, default: md_assert_generic_sel_fail) md_generic_call(allocator, kind, flags, string, raw_string, src_offset)
|
||||
|
||||
void node_insert_tag (Node* parent, Node* prev_child, Node* node);
|
||||
void node_insert_child(Node* parent, Node* prev_child, Node* node);
|
||||
void node_push_child (Node* parent, Node* node);
|
||||
void node_push_tag (Node* parent, Node* node);
|
||||
void unhook (Node* node);
|
||||
void md_node_insert_tag (MD_Node* parent, MD_Node* prev_child, MD_Node* node);
|
||||
void md_node_insert_child(MD_Node* parent, MD_Node* prev_child, MD_Node* node);
|
||||
void md_node_push_child (MD_Node* parent, MD_Node* node);
|
||||
void md_node_push_tag (MD_Node* parent, MD_Node* node);
|
||||
void md_unhook (MD_Node* node);
|
||||
|
||||
inline Node* push_node__arena(Arena* arena, NodeKind kind, NodeFlags flags, String8 string, String8 raw_string, U64 src_offset) { push_node__ainfo(arena_allocator(arena), kind, flags, string, raw_string, src_offset); }
|
||||
inline MD_Node* md_push_node__arena(MD_Arena* arena, MD_NodeKind kind, NodeFlags flags, MD_String8 string, MD_String8 raw_string, MD_U64 src_offset) { md_push_node__ainfo(md_arena_allocator(arena), kind, flags, string, raw_string, src_offset); }
|
||||
|
||||
inline Node*
|
||||
push_node__ainfo(AllocatorInfo ainfo, NodeKind kind, NodeFlags flags, String8 string, String8 raw_string, U64 src_offset) {
|
||||
Node* node = alloc_array(ainfo, Node, 1);
|
||||
node->first = node->last = node->parent = node->next = node->prev = node->first_tag = node->last_tag = nil_node();
|
||||
inline MD_Node*
|
||||
md_push_node__ainfo(MD_AllocatorInfo ainfo, MD_NodeKind kind, NodeFlags flags, MD_String8 string, MD_String8 raw_string, MD_U64 src_offset) {
|
||||
MD_Node* node = md_alloc_array(ainfo, MD_Node, 1);
|
||||
node->first = node->last = node->parent = node->next = node->prev = node->first_tag = node->last_tag = md_nil_node();
|
||||
node->kind = kind;
|
||||
node->flags = flags;
|
||||
node->string = string;
|
||||
@@ -403,63 +403,63 @@ push_node__ainfo(AllocatorInfo ainfo, NodeKind kind, NodeFlags flags, String8 st
|
||||
}
|
||||
|
||||
inline void
|
||||
node_insert_child(Node* parent, Node* prev_child, Node* node) {
|
||||
md_node_insert_child(MD_Node* parent, MD_Node* prev_child, MD_Node* node) {
|
||||
node->parent = parent;
|
||||
dll_insert_npz(nil_node(), parent->first, parent->last, prev_child, node, next, prev);
|
||||
md_dll_insert_npz(md_nil_node(), parent->first, parent->last, prev_child, node, next, prev);
|
||||
}
|
||||
|
||||
inline void
|
||||
node_insert_tag(Node* parent, Node* prev_child, Node* node) {
|
||||
node->kind = NodeKind_Tag;
|
||||
md_node_insert_tag(MD_Node* parent, MD_Node* prev_child, MD_Node* node) {
|
||||
node->kind = MD_NodeKind_Tag;
|
||||
node->parent = parent;
|
||||
dll_insert_npz(nil_node(), parent->first_tag, parent->last_tag, prev_child, node, next, prev);
|
||||
md_dll_insert_npz(md_nil_node(), parent->first_tag, parent->last_tag, prev_child, node, next, prev);
|
||||
}
|
||||
|
||||
inline void
|
||||
node_push_child(Node* parent, Node* node) {
|
||||
md_node_push_child(MD_Node* parent, MD_Node* node) {
|
||||
node->parent = parent;
|
||||
dll_push_back_npz(nil_node(), parent->first, parent->last, node, next, prev);
|
||||
md_dll_push_back_npz(md_nil_node(), parent->first, parent->last, node, next, prev);
|
||||
}
|
||||
|
||||
inline void
|
||||
node_push_tag(Node* parent, Node* node) {
|
||||
node->kind = NodeKind_Tag;
|
||||
md_node_push_tag(MD_Node* parent, MD_Node* node) {
|
||||
node->kind = MD_NodeKind_Tag;
|
||||
node->parent = parent;
|
||||
dll_push_back_npz(nil_node(), parent->first_tag, parent->last_tag, node, next, prev);
|
||||
md_dll_push_back_npz(md_nil_node(), parent->first_tag, parent->last_tag, node, next, prev);
|
||||
}
|
||||
|
||||
//- rjf: tree introspection
|
||||
|
||||
Node* node_from_chain_string(Node* first, Node* opl, String8 string, StringMatchFlags flags);
|
||||
Node* node_from_chain_index (Node* first, Node* opl, U64 index);
|
||||
Node* node_from_chain_flags (Node* first, Node* opl, NodeFlags flags);
|
||||
U64 index_from_node (Node* node);
|
||||
Node* root_from_node (Node* node);
|
||||
Node* child_from_string (Node* node, String8 child_string, StringMatchFlags flags);
|
||||
Node* tag_from_string (Node* node, String8 tag_string, StringMatchFlags flags);
|
||||
Node* child_from_index (Node* node, U64 index);
|
||||
Node* tag_from_index (Node* node, U64 index);
|
||||
Node* tag_arg_from_index (Node* node, String8 tag_string, StringMatchFlags flags, U64 index);
|
||||
Node* tag_arg_from_string (Node* node, String8 tag_string, StringMatchFlags tag_str_flags, String8 arg_string, StringMatchFlags arg_str_flags);
|
||||
B32 node_has_child (Node* node, String8 string, StringMatchFlags flags);
|
||||
B32 node_has_tag (Node* node, String8 string, StringMatchFlags flags);
|
||||
U64 child_count_from_node (Node* node);
|
||||
U64 tag_count_from_node (Node* node);
|
||||
MD_Node* md_node_from_chain_string(MD_Node* first, MD_Node* opl, MD_String8 string, MD_StringMatchFlags flags);
|
||||
MD_Node* md_node_from_chain_index (MD_Node* first, MD_Node* opl, MD_U64 index);
|
||||
MD_Node* md_node_from_chain_flags (MD_Node* first, MD_Node* opl, NodeFlags flags);
|
||||
MD_U64 md_index_from_node (MD_Node* node);
|
||||
MD_Node* md_root_from_node (MD_Node* node);
|
||||
MD_Node* md_child_from_string (MD_Node* node, MD_String8 child_string, MD_StringMatchFlags flags);
|
||||
MD_Node* md_tag_from_string (MD_Node* node, MD_String8 tag_string, MD_StringMatchFlags flags);
|
||||
MD_Node* md_child_from_index (MD_Node* node, MD_U64 index);
|
||||
MD_Node* md_tag_from_index (MD_Node* node, MD_U64 index);
|
||||
MD_Node* md_tag_arg_from_index (MD_Node* node, MD_String8 tag_string, MD_StringMatchFlags flags, MD_U64 index);
|
||||
MD_Node* md_tag_arg_from_string (MD_Node* node, MD_String8 tag_string, MD_StringMatchFlags tag_str_flags, MD_String8 arg_string, MD_StringMatchFlags arg_str_flags);
|
||||
MD_B32 md_node_has_child (MD_Node* node, MD_String8 string, MD_StringMatchFlags flags);
|
||||
MD_B32 md_node_has_tag (MD_Node* node, MD_String8 string, MD_StringMatchFlags flags);
|
||||
MD_U64 md_child_count_from_node (MD_Node* node);
|
||||
MD_U64 md_tag_count_from_node (MD_Node* node);
|
||||
|
||||
MD_API String8 string_from_children__arena(Arena* arena, Node* root);
|
||||
String8 string_from_children__ainfo(AllocatorInfo ainfo, Node* root);
|
||||
MD_API MD_String8 md_string_from_children__arena(MD_Arena* arena, MD_Node* root);
|
||||
MD_String8 md_string_from_children__ainfo(MD_AllocatorInfo ainfo, MD_Node* root);
|
||||
|
||||
#define string_from_children(allocator, root) _Generic(allocator, Arena*: string_from_children__arena, AllocatorInfo: string_from_children__ainfo, default: assert_generic_sel_fail) generic_call(allocator, root)
|
||||
#define md_string_from_children(allocator, root) _Generic(allocator, MD_Arena*: md_string_from_children__arena, MD_AllocatorInfo: md_string_from_children__ainfo, default: md_assert_generic_sel_fail) md_generic_call(allocator, root)
|
||||
|
||||
force_inline String8 string_from_children__arena(Arena* arena, Node* root) { return string_from_children__ainfo(arena_allocator(arena), root); }
|
||||
md_force_inline MD_String8 md_string_from_children__arena(MD_Arena* arena, MD_Node* root) { return md_string_from_children__ainfo(md_arena_allocator(arena), root); }
|
||||
|
||||
inline Node*
|
||||
node_from_chain_string(Node* first, Node* opl, String8 string, StringMatchFlags flags)
|
||||
inline MD_Node*
|
||||
md_node_from_chain_string(MD_Node* first, MD_Node* opl, MD_String8 string, MD_StringMatchFlags flags)
|
||||
{
|
||||
Node* result = nil_node();
|
||||
for (Node* n = first; !node_is_nil(n) && n != opl; n = n->next)
|
||||
MD_Node* result = md_nil_node();
|
||||
for (MD_Node* n = first; !md_node_is_nil(n) && n != opl; n = n->next)
|
||||
{
|
||||
if (str8_match(n->string, string, flags)) {
|
||||
if (md_str8_match(n->string, string, flags)) {
|
||||
result = n;
|
||||
break;
|
||||
}
|
||||
@@ -467,11 +467,11 @@ node_from_chain_string(Node* first, Node* opl, String8 string, StringMatchFlags
|
||||
return result;
|
||||
}
|
||||
|
||||
inline Node*
|
||||
node_from_chain_index(Node* first, Node* opl, U64 index) {
|
||||
Node* result = nil_node();
|
||||
S64 idx = 0;
|
||||
for (Node* n = first; !node_is_nil(n) && n != opl; n = n->next, idx += 1)
|
||||
inline MD_Node*
|
||||
md_node_from_chain_index(MD_Node* first, MD_Node* opl, MD_U64 index) {
|
||||
MD_Node* result = md_nil_node();
|
||||
MD_S64 idx = 0;
|
||||
for (MD_Node* n = first; !md_node_is_nil(n) && n != opl; n = n->next, idx += 1)
|
||||
{
|
||||
if (index == idx) {
|
||||
result = n;
|
||||
@@ -481,10 +481,10 @@ node_from_chain_index(Node* first, Node* opl, U64 index) {
|
||||
return result;
|
||||
}
|
||||
|
||||
inline Node*
|
||||
node_from_chain_flags(Node* first, Node* opl, NodeFlags flags) {
|
||||
Node* result = nil_node();
|
||||
for (Node* n = first; !node_is_nil(n) && n != opl; n = n->next)
|
||||
inline MD_Node*
|
||||
md_node_from_chain_flags(MD_Node* first, MD_Node* opl, NodeFlags flags) {
|
||||
MD_Node* result = md_nil_node();
|
||||
for (MD_Node* n = first; !md_node_is_nil(n) && n != opl; n = n->next)
|
||||
{
|
||||
if (n->flags & flags) {
|
||||
result = n;
|
||||
@@ -494,58 +494,58 @@ node_from_chain_flags(Node* first, Node* opl, NodeFlags flags) {
|
||||
return result;
|
||||
}
|
||||
|
||||
inline U64
|
||||
index_from_node(Node* node) {
|
||||
U64 index = 0;
|
||||
for (Node* n = node->prev; !node_is_nil(n); n = n->prev) {
|
||||
inline MD_U64
|
||||
md_index_from_node(MD_Node* node) {
|
||||
MD_U64 index = 0;
|
||||
for (MD_Node* n = node->prev; !md_node_is_nil(n); n = n->prev) {
|
||||
index += 1;
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
inline Node*
|
||||
root_from_node(Node* node) {
|
||||
Node* result = node;
|
||||
for (Node* p = node->parent; (p->kind == NodeKind_Main || p->kind == NodeKind_Tag) && !node_is_nil(p); p = p->parent) {
|
||||
inline MD_Node*
|
||||
md_root_from_node(MD_Node* node) {
|
||||
MD_Node* result = node;
|
||||
for (MD_Node* p = node->parent; (p->kind == MD_NodeKind_Main || p->kind == MD_NodeKind_Tag) && !md_node_is_nil(p); p = p->parent) {
|
||||
result = p;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
inline Node* child_from_string(Node* node, String8 child_string, StringMatchFlags flags) { return node_from_chain_string(node->first, nil_node(), child_string, flags); }
|
||||
inline Node* tag_from_string (Node* node, String8 tag_string, StringMatchFlags flags) { return node_from_chain_string(node->first_tag, nil_node(), tag_string, flags); }
|
||||
inline Node* child_from_index (Node* node, U64 index) { return node_from_chain_index (node->first, nil_node(), index); }
|
||||
inline Node* tag_from_index (Node* node, U64 index) { return node_from_chain_index (node->first_tag, nil_node(), index); }
|
||||
inline MD_Node* md_child_from_string(MD_Node* node, MD_String8 child_string, MD_StringMatchFlags flags) { return md_node_from_chain_string(node->first, md_nil_node(), child_string, flags); }
|
||||
inline MD_Node* md_tag_from_string (MD_Node* node, MD_String8 tag_string, MD_StringMatchFlags flags) { return md_node_from_chain_string(node->first_tag, md_nil_node(), tag_string, flags); }
|
||||
inline MD_Node* md_child_from_index (MD_Node* node, MD_U64 index) { return md_node_from_chain_index (node->first, md_nil_node(), index); }
|
||||
inline MD_Node* md_tag_from_index (MD_Node* node, MD_U64 index) { return md_node_from_chain_index (node->first_tag, md_nil_node(), index); }
|
||||
|
||||
inline Node*
|
||||
tag_arg_from_index(Node* node, String8 tag_string, StringMatchFlags flags, U64 index) {
|
||||
Node* tag = tag_from_string(node, tag_string, flags);
|
||||
return child_from_index(tag, index);
|
||||
inline MD_Node*
|
||||
md_tag_arg_from_index(MD_Node* node, MD_String8 tag_string, MD_StringMatchFlags flags, MD_U64 index) {
|
||||
MD_Node* tag = md_tag_from_string(node, tag_string, flags);
|
||||
return md_child_from_index(tag, index);
|
||||
}
|
||||
|
||||
inline Node*
|
||||
tag_arg_from_string(Node* node, String8 tag_string, StringMatchFlags tag_str_flags, String8 arg_string, StringMatchFlags arg_str_flags) {
|
||||
Node* tag = tag_from_string (node, tag_string, tag_str_flags);
|
||||
Node* arg = child_from_string(tag, arg_string, arg_str_flags);
|
||||
inline MD_Node*
|
||||
md_tag_arg_from_string(MD_Node* node, MD_String8 tag_string, MD_StringMatchFlags tag_str_flags, MD_String8 arg_string, MD_StringMatchFlags arg_str_flags) {
|
||||
MD_Node* tag = md_tag_from_string (node, tag_string, tag_str_flags);
|
||||
MD_Node* arg = md_child_from_string(tag, arg_string, arg_str_flags);
|
||||
return arg;
|
||||
}
|
||||
|
||||
inline B32 node_has_child(Node* node, String8 string, StringMatchFlags flags) { return !node_is_nil(child_from_string(node, string, flags)); }
|
||||
inline B32 node_has_tag (Node* node, String8 string, StringMatchFlags flags) { return !node_is_nil(tag_from_string (node, string, flags)); }
|
||||
inline MD_B32 md_node_has_child(MD_Node* node, MD_String8 string, MD_StringMatchFlags flags) { return !md_node_is_nil(md_child_from_string(node, string, flags)); }
|
||||
inline MD_B32 md_node_has_tag (MD_Node* node, MD_String8 string, MD_StringMatchFlags flags) { return !md_node_is_nil(md_tag_from_string (node, string, flags)); }
|
||||
|
||||
inline U64
|
||||
child_count_from_node(Node *node) {
|
||||
U64 result = 0;
|
||||
for (Node* child = node->first; !node_is_nil(child); child = child->next) {
|
||||
inline MD_U64
|
||||
md_child_count_from_node(MD_Node *node) {
|
||||
MD_U64 result = 0;
|
||||
for (MD_Node* child = node->first; !md_node_is_nil(child); child = child->next) {
|
||||
result += 1;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
inline U64
|
||||
tag_count_from_node(Node* node) {
|
||||
U64 result = 0;
|
||||
for (Node* child = node->first_tag; !node_is_nil(child); child = child->next) {
|
||||
inline MD_U64
|
||||
md_tag_count_from_node(MD_Node* node) {
|
||||
MD_U64 result = 0;
|
||||
for (MD_Node* child = node->first_tag; !md_node_is_nil(child); child = child->next) {
|
||||
result += 1;
|
||||
}
|
||||
return result;
|
||||
@@ -553,56 +553,56 @@ tag_count_from_node(Node* node) {
|
||||
|
||||
//- rjf: tree comparison
|
||||
|
||||
MD_API B32 tree_match(Node* a, Node* b, StringMatchFlags flags);
|
||||
MD_API B32 node_match(Node* a, Node* b, StringMatchFlags flags);
|
||||
MD_API MD_B32 tree_match(MD_Node* a, MD_Node* b, MD_StringMatchFlags flags);
|
||||
MD_API MD_B32 md_node_match(MD_Node* a, MD_Node* b, MD_StringMatchFlags flags);
|
||||
|
||||
//- rjf: tree duplication
|
||||
|
||||
MD_API Node* tree_copy__arena(Arena* arena, Node* src_root);
|
||||
MD_API Node* tree_copy__ainfo(AllocatorInfo ainfo, Node* src_root);
|
||||
MD_API MD_Node* md_tree_copy__arena(MD_Arena* arena, MD_Node* src_root);
|
||||
MD_API MD_Node* md_tree_copy__ainfo(MD_AllocatorInfo ainfo, MD_Node* src_root);
|
||||
|
||||
#define tree_copy(allocator, src_root) _Generic(allocator, Arena*: tree_copy__arena, AllocatorInfo: tree_copy__ainfo, default: assert_generic_sel_fail) generic_call(allocator, src_root)
|
||||
#define md_treecopy(allocator, src_root) _Generic(allocator, MD_Arena*: md_tree_copy__arena, MD_AllocatorInfo: md_tree_copy__ainfo, default: md_assert_generic_sel_fail) md_generic_call(allocator, src_root)
|
||||
|
||||
force_inline Node* tree_copy__arena(Arena* arena, Node* src_root) { return tree_copy__ainfo(arena_allocator(arena), src_root); }
|
||||
md_force_inline MD_Node* md_tree_copy__arena(MD_Arena* arena, MD_Node* src_root) { return md_tree_copy__ainfo(md_arena_allocator(arena), src_root); }
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Text -> Tokens Functions
|
||||
|
||||
MD_API TokenizeResult tokenize_from_text__arena(Arena* arena, String8 text);
|
||||
MD_API TokenizeResult tokenize_from_text__ainfo(AllocatorInfo ainfo, String8 text);
|
||||
MD_API MD_TokenizeResult md_tokenize_from_text__arena(MD_Arena* arena, MD_String8 text);
|
||||
MD_API MD_TokenizeResult md_tokenize_from_text__ainfo(MD_AllocatorInfo ainfo, MD_String8 text);
|
||||
|
||||
#define tokenize_from_text(allocator, text) _Generic(allocator, Arena*: tokenize_from_text__arena, AllocatorInfo: tokenize_from_text__ainfo, default: assert_generic_sel_fail) generic_call(allocator, text)
|
||||
#define md_tokenize_from_text(allocator, text) _Generic(allocator, MD_Arena*: md_tokenize_from_text__arena, MD_AllocatorInfo: md_tokenize_from_text__ainfo, default: md_assert_generic_sel_fail) md_generic_call(allocator, text)
|
||||
|
||||
force_inline TokenizeResult tokenize_from_text__arena(Arena* arena, String8 text) { return tokenize_from_text__ainfo(arena_allocator(arena), text); }
|
||||
md_force_inline MD_TokenizeResult md_tokenize_from_text__arena(MD_Arena* arena, MD_String8 text) { return md_tokenize_from_text__ainfo(md_arena_allocator(arena), text); }
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Tokens -> Tree Functions
|
||||
|
||||
MD_API ParseResult parse_from_text_tokens__arena(Arena* arena, String8 filename, String8 text, TokenArray tokens);
|
||||
MD_API ParseResult parse_from_text_tokens__ainfo(AllocatorInfo ainfo, String8 filename, String8 text, TokenArray tokens);
|
||||
MD_API MD_ParseResult md_parse_from_text_tokens__arena(MD_Arena* arena, MD_String8 filename, MD_String8 text, MD_TokenArray tokens);
|
||||
MD_API MD_ParseResult md_parse_from_text_tokens__ainfo(MD_AllocatorInfo ainfo, MD_String8 filename, MD_String8 text, MD_TokenArray tokens);
|
||||
|
||||
#define parse_from_text_tokens(allocator, filename, text, tokens) _Generic(allocator, Arena*: parse_from_text_tokens__arena, AllocatorInfo: parse_from_text_tokens__ainfo, default: assert_generic_sel_fail) generic_call(allocator, filename, text, tokens)
|
||||
#define md_parse_from_text_tokens(allocator, filename, text, tokens) _Generic(allocator, MD_Arena*: md_parse_from_text_tokens__arena, MD_AllocatorInfo: md_parse_from_text_tokens__ainfo, default: md_assert_generic_sel_fail) md_generic_call(allocator, filename, text, tokens)
|
||||
|
||||
force_inline ParseResult parse_from_text_tokens__arena(Arena* arena, String8 filename, String8 text, TokenArray tokens) { return parse_from_text_tokens__ainfo(arena_allocator(arena), filename, text, tokens); }
|
||||
md_force_inline MD_ParseResult md_parse_from_text_tokens__arena(MD_Arena* arena, MD_String8 filename, MD_String8 text, MD_TokenArray tokens) { return md_parse_from_text_tokens__ainfo(md_arena_allocator(arena), filename, text, tokens); }
|
||||
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Bundled Text -> Tree Functions
|
||||
|
||||
MD_API ParseResult parse_from_text__arena(Arena* arena, String8 filename, String8 text);
|
||||
MD_API ParseResult parse_from_text__ainfo(AllocatorInfo ainfo, String8 filename, String8 text);
|
||||
MD_API MD_ParseResult md_parse_from_text__arena(MD_Arena* arena, MD_String8 filename, MD_String8 text);
|
||||
MD_API MD_ParseResult md_parse_from_text__ainfo(MD_AllocatorInfo ainfo, MD_String8 filename, MD_String8 text);
|
||||
|
||||
#define parse_from_text(allocator, filename, text) _Generic(allocator, Arena*: parse_from_text__arena, AllocatorInfo: parse_from_text__ainfo, default: assert_generic_sel_fail) generic_call(allocator, filename, text)
|
||||
#define tree_from_string(allocator, string) (parse_from_text((allocator), str8_zero(), (string)).root)
|
||||
#define md_parse_from_text(allocator, filename, text) _Generic(allocator, MD_Arena*: md_parse_from_text__arena, MD_AllocatorInfo: md_parse_from_text__ainfo, default: md_assert_generic_sel_fail) md_generic_call(allocator, filename, text)
|
||||
#define tree_from_string(allocator, string) (md_parse_from_text((allocator), md_str8_zero(), (string)).root)
|
||||
|
||||
force_inline ParseResult parse_from_text__arena(Arena* arena, String8 filename, String8 text) { return parse_from_text__ainfo(arena_allocator(arena), filename, text); }
|
||||
md_force_inline MD_ParseResult md_parse_from_text__arena(MD_Arena* arena, MD_String8 filename, MD_String8 text) { return md_parse_from_text__ainfo(md_arena_allocator(arena), filename, text); }
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Tree -> Text Functions
|
||||
|
||||
MD_API String8List debug_string_list_from_tree__arena(Arena* arena, Node* root);
|
||||
MD_API String8List debug_string_list_from_tree__ainfo(AllocatorInfo ainfo, Node* root);
|
||||
MD_API MD_String8List md_debug_string_list_from_tree__arena(MD_Arena* arena, MD_Node* root);
|
||||
MD_API MD_String8List md_debug_string_list_from_tree__ainfo(MD_AllocatorInfo ainfo, MD_Node* root);
|
||||
|
||||
#define debug_string_list_from_tree(allocator, string) _Generic(allocator, Arena*: debug_string_list_from_tree__arena, AllocatorInfo: debug_string_list_from_tree__ainfo, default: assert_generic_sel_fail) generic_call(allocator, string)
|
||||
#define md_debug_string_list_from_tree(allocator, string) _Generic(allocator, MD_Arena*: md_debug_string_list_from_tree__arena, MD_AllocatorInfo: md_debug_string_list_from_tree__ainfo, default: md_assert_generic_sel_fail) md_generic_call(allocator, string)
|
||||
|
||||
force_inline String8List debug_string_list_from_tree__arena(Arena* arena, Node* root) { return debug_string_list_from_tree__ainfo(arena_allocator(arena), root); }
|
||||
md_force_inline MD_String8List md_debug_string_list_from_tree__arena(MD_Arena* arena, MD_Node* root) { return md_debug_string_list_from_tree__ainfo(md_arena_allocator(arena), root); }
|
||||
|
||||
+365
-365
File diff suppressed because it is too large
Load Diff
+74
-74
@@ -19,54 +19,54 @@ typedef struct timespec timespec;
|
||||
////////////////////////////////
|
||||
//~ rjf: File Iterator
|
||||
|
||||
typedef struct OS_LNX_FileIter OS_LNX_FileIter;
|
||||
struct OS_LNX_FileIter
|
||||
typedef struct MD_OS_LNX_FileIter MD_OS_LNX_FileIter;
|
||||
struct MD_OS_LNX_FileIter
|
||||
{
|
||||
DIR* dir;
|
||||
struct dirent* dp;
|
||||
String8 path;
|
||||
MD_String8 path;
|
||||
};
|
||||
md_assert(sizeof(Member(OS_FileIter, memory)) >= sizeof(OS_LNX_FileIter), os_lnx_file_iter_size_check);
|
||||
md_assert(sizeof(Member(MD_OS_FileIter, memory)) >= sizeof(MD_OS_LNX_FileIter), md_os_lnx_file_iter_size_check);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Safe Call Handler Chain
|
||||
|
||||
typedef struct OS_LNX_SafeCallChain OS_LNX_SafeCallChain;
|
||||
struct OS_LNX_SafeCallChain
|
||||
typedef struct MD_OS_LNX_SafeCallChain MD_OS_LNX_SafeCallChain;
|
||||
struct MD_OS_LNX_SafeCallChain
|
||||
{
|
||||
OS_LNX_SafeCallChain* next;
|
||||
OS_ThreadFunctionType* fail_handler;
|
||||
MD_OS_LNX_SafeCallChain* next;
|
||||
MD_OS_ThreadFunctionType* fail_handler;
|
||||
void *ptr;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Entities
|
||||
|
||||
typedef enum OS_LNX_EntityKind OS_LNX_EntityKind
|
||||
enum OS_LNX_EntityKind
|
||||
typedef enum MD_OS_LNX_EntityKind MD_OS_LNX_EntityKind
|
||||
enum MD_OS_LNX_EntityKind
|
||||
{
|
||||
OS_LNX_EntityKind_Thread,
|
||||
OS_LNX_EntityKind_Mutex,
|
||||
OS_LNX_EntityKind_RWMutex,
|
||||
OS_LNX_EntityKind_ConditionVariable,
|
||||
MD_OS_LNX_EntityKind_Thread,
|
||||
MD_OS_LNX_EntityKind_Mutex,
|
||||
MD_OS_LNX_EntityKind_RWMutex,
|
||||
MD_OS_LNX_EntityKind_ConditionVariable,
|
||||
};
|
||||
|
||||
typedef struct OS_LNX_EntityThread OS_LNX_EntityThread;
|
||||
struct OS_LNX_EntityThread
|
||||
typedef struct MD_OS_LNX_EntityThread MD_OS_LNX_EntityThread;
|
||||
struct MD_OS_LNX_EntityThread
|
||||
{
|
||||
pthread_t handle;
|
||||
OS_ThreadFunctionType* func;
|
||||
MD_OS_ThreadFunctionType* func;
|
||||
void* ptr;
|
||||
};
|
||||
|
||||
typedef struct OS_LNX_Entity OS_LNX_Entity;
|
||||
struct OS_LNX_Entity
|
||||
typedef struct MD_OS_LNX_Entity MD_OS_LNX_Entity;
|
||||
struct MD_OS_LNX_Entity
|
||||
{
|
||||
OS_LNX_Entity* next;
|
||||
OS_LNX_EntityKind kind;
|
||||
MD_OS_LNX_Entity* next;
|
||||
MD_OS_LNX_EntityKind kind;
|
||||
union
|
||||
{
|
||||
OS_LNX_EntityThread thread;
|
||||
MD_OS_LNX_EntityThread thread;
|
||||
pthread_mutex_t mutex_handle;
|
||||
pthread_rwlock_t rwmutex_handle;
|
||||
struct {
|
||||
@@ -79,33 +79,33 @@ struct OS_LNX_Entity
|
||||
////////////////////////////////
|
||||
//~ rjf: State
|
||||
|
||||
typedef struct OS_LNX_State OS_LNX_State;
|
||||
struct OS_LNX_State
|
||||
typedef struct MD_OS_LNX_State MD_OS_LNX_State;
|
||||
struct MD_OS_LNX_State
|
||||
{
|
||||
Arena* arena;
|
||||
OS_SystemInfo system_info;
|
||||
OS_ProcessInfo process_info;
|
||||
MD_Arena* arena;
|
||||
MD_OS_SystemInfo system_info;
|
||||
MD_OS_ProcessInfo process_info;
|
||||
pthread_mutex_t entity_mutex;
|
||||
Arena* entity_arena;
|
||||
OS_LNX_Entity* entity_free;
|
||||
MD_Arena* entity_arena;
|
||||
MD_OS_LNX_Entity* entity_free;
|
||||
};
|
||||
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Helpers
|
||||
|
||||
DateTime os_lnx_date_time_from_tm (tm in, U32 msec);
|
||||
tm os_lnx_tm_from_date_time (DateTime dt);
|
||||
timespec os_lnx_timespec_from_date_time (DateTime dt);
|
||||
DenseTime os_lnx_dense_time_from_timespec (timespec in);
|
||||
FileProperties os_lnx_file_properties_from_stat(struct stat* s);
|
||||
void os_lnx_safe_call_sig_handler (int x);
|
||||
MD_DateTime md_os_lnx_date_time_from_tm (tm in, MD_U32 msec);
|
||||
tm md_os_lnx_tm_from_date_time (MD_DateTime dt);
|
||||
timespec md_os_lnx_timespec_from_date_time (MD_DateTime dt);
|
||||
MD_DenseTime md_os_lnx_dense_time_from_timespec (timespec in);
|
||||
MD_FileProperties md_os_lnx_file_properties_from_stat(struct stat* s);
|
||||
void md_os_lnx_safe_call_sig_handler (int x);
|
||||
|
||||
inline DateTime
|
||||
os_lnx_date_time_from_tm(tm in, U32 msec) {
|
||||
DateTime dt = {0};
|
||||
inline MD_DateTime
|
||||
md_os_lnx_date_time_from_tm(tm in, MD_U32 msec) {
|
||||
MD_DateTime dt = {0};
|
||||
dt.sec = in.tm_sec;
|
||||
dt.min = in.tm_min;
|
||||
dt.md_min = in.tm_min;
|
||||
dt.hour = in.tm_hour;
|
||||
|
||||
dt.day = in.tm_mday-1;
|
||||
@@ -116,10 +116,10 @@ os_lnx_date_time_from_tm(tm in, U32 msec) {
|
||||
}
|
||||
|
||||
inline tm
|
||||
os_lnx_tm_from_date_time(DateTime dt) {
|
||||
md_os_lnx_tm_from_date_time(MD_DateTime dt) {
|
||||
tm result = {0};
|
||||
result.tm_sec = dt.sec;
|
||||
result.tm_min = dt.min;
|
||||
result.tm_min = dt.md_min;
|
||||
result.tm_hour= dt.hour;
|
||||
|
||||
result.tm_mday= dt.day+1;
|
||||
@@ -129,40 +129,40 @@ os_lnx_tm_from_date_time(DateTime dt) {
|
||||
}
|
||||
|
||||
inline timespec
|
||||
os_lnx_timespec_from_date_time(DateTime dt) {
|
||||
tm tm_val = os_lnx_tm_from_date_time(dt);
|
||||
md_os_lnx_timespec_from_date_time(MD_DateTime dt) {
|
||||
tm tm_val = md_os_lnx_tm_from_date_time(dt);
|
||||
time_t seconds = timegm(&tm_val);
|
||||
timespec result = {0};
|
||||
result.tv_sec = seconds;
|
||||
return result;
|
||||
}
|
||||
|
||||
inline DenseTime
|
||||
os_lnx_dense_time_from_timespec(timespec in) {
|
||||
DenseTime result = 0; {
|
||||
inline MD_DenseTime
|
||||
md_os_lnx_dense_time_from_timespec(timespec in) {
|
||||
MD_DenseTime result = 0; {
|
||||
struct tm tm_time = {0};
|
||||
gmtime_r(&in.tv_sec, &tm_time);
|
||||
DateTime date_time = os_lnx_date_time_from_tm(tm_time, in.tv_nsec/Million(1));
|
||||
result = dense_time_from_date_time(date_time);
|
||||
MD_DateTime date_time = md_os_lnx_date_time_from_tm(tm_time, in.tv_nsec/Million(1));
|
||||
result = md_dense_time_from_date_time(date_time);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
inline FileProperties
|
||||
os_lnx_file_properties_from_stat(struct stat* s) {
|
||||
FileProperties props = {0};
|
||||
inline MD_FileProperties
|
||||
md_os_lnx_file_properties_from_stat(struct stat* s) {
|
||||
MD_FileProperties props = {0};
|
||||
props.size = s->st_size;
|
||||
props.created = os_lnx_dense_time_from_timespec(s->st_ctim);
|
||||
props.modified = os_lnx_dense_time_from_timespec(s->st_mtim);
|
||||
props.created = md_os_lnx_dense_time_from_timespec(s->st_ctim);
|
||||
props.modified = md_os_lnx_dense_time_from_timespec(s->st_mtim);
|
||||
if (s->st_mode & S_IFDIR) {
|
||||
props.flags |= FilePropertyFlag_IsFolder;
|
||||
props.flags |= MD_FilePropertyFlag_IsFolder;
|
||||
}
|
||||
return props;
|
||||
}
|
||||
|
||||
inline void
|
||||
os_lnx_safe_call_sig_handler(int x) {
|
||||
OS_LNX_SafeCallChain* chain = os_lnx_safe_call_chain;
|
||||
md_os_lnx_safe_call_sig_handler(int x) {
|
||||
MD_OS_LNX_SafeCallChain* chain = md_os_lnx_safe_call_chain;
|
||||
if (chain != 0 && chain->fail_handler != 0) {
|
||||
chain->fail_handler(chain->ptr);
|
||||
}
|
||||
@@ -172,45 +172,45 @@ os_lnx_safe_call_sig_handler(int x) {
|
||||
////////////////////////////////
|
||||
//~ rjf: Entities
|
||||
|
||||
MD_API OS_LNX_Entity* os_lnx_entity_alloc (OS_LNX_EntityKind kind);
|
||||
MD_API void os_lnx_entity_release(OS_LNX_Entity* entity);
|
||||
MD_API MD_OS_LNX_Entity* md_os_lnx_entity_alloc (MD_OS_LNX_EntityKind kind);
|
||||
MD_API void md_os_lnx_entity_release(MD_OS_LNX_Entity* entity);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Thread Entry Point
|
||||
|
||||
MD_API void* os_lnx_thread_entry_point(void* ptr);
|
||||
MD_API void* md_os_lnx_thread_entry_point(void* ptr);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks System/Process Info (Implemented Per-OS)
|
||||
//~ rjf: @md_os_hooks System/Process Info (Implemented Per-OS)
|
||||
|
||||
inline String8
|
||||
os_get_current_path__ainfo(AllocatorInfo ainfo) {
|
||||
inline MD_String8
|
||||
md_os_get_current_path__ainfo(MD_AllocatorInfo ainfo) {
|
||||
char* cwdir = getcwd(0, 0);
|
||||
String8 string = str8_copy(ainfo, str8_cstring(cwdir));
|
||||
MD_String8 string = md_str8_copy(ainfo, md_str8_cstring(cwdir));
|
||||
return string;
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Memory Allocation (Implemented Per-OS)
|
||||
//~ rjf: @md_os_hooks Memory Allocation (Implemented Per-OS)
|
||||
|
||||
//- rjf: basic
|
||||
|
||||
inline void* os_reserve ( U64 size) { void* result = mmap(0, size, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); return result; }
|
||||
inline B32 os_commit (void *ptr, U64 size) { mprotect(ptr, size, PROT_READ | PROT_WRITE); return 1; }
|
||||
inline void os_decommit(void *ptr, U64 size) { madvise(ptr, size, MADV_DONTNEED); mprotect(ptr, size, PROT_NONE); }
|
||||
inline void os_release (void *ptr, U64 size) { munmap(ptr, size); }
|
||||
inline void* md_os_reserve ( MD_U64 size) { void* result = mmap(0, size, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); return result; }
|
||||
inline MD_B32 md_os_commit (void *ptr, MD_U64 size) { mprotect(ptr, size, PROT_READ | PROT_WRITE); return 1; }
|
||||
inline void md_os_decommit(void *ptr, MD_U64 size) { madvise(ptr, size, MADV_DONTNEED); mprotect(ptr, size, PROT_NONE); }
|
||||
inline void md_os_release (void *ptr, MD_U64 size) { munmap(ptr, size); }
|
||||
|
||||
//- rjf: large pages
|
||||
|
||||
inline void* os_reserve_large( U64 size) { void* result = mmap(0, size, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB, -1, 0); return result; }
|
||||
inline B32 os_commit_large (void *ptr, U64 size) { mprotect(ptr, size, PROT_READ | PROT_WRITE); return 1; }
|
||||
inline void* md_os_reserve_large( MD_U64 size) { void* result = mmap(0, size, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB, -1, 0); return result; }
|
||||
inline MD_B32 md_os_commit_large (void *ptr, MD_U64 size) { mprotect(ptr, size, PROT_READ | PROT_WRITE); return 1; }
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Thread Info (Implemented Per-OS)
|
||||
//~ rjf: @md_os_hooks Thread Info (Implemented Per-OS)
|
||||
|
||||
inline U32
|
||||
os_tid(void) {
|
||||
U32 result = 0;
|
||||
inline MD_U32
|
||||
md_os_tid(void) {
|
||||
MD_U32 result = 0;
|
||||
#if defined(SYS_gettid)
|
||||
result = syscall(SYS_gettid);
|
||||
#else
|
||||
|
||||
+40
-43
@@ -1,6 +1,3 @@
|
||||
#ifdef INTELLISENSE_DIRECTIVES
|
||||
# include "os.h"
|
||||
#endif
|
||||
|
||||
// Copyright (c) 2024 Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
@@ -8,80 +5,80 @@
|
||||
////////////////////////////////
|
||||
//~ rjf: Filesystem Helpers (Helpers, Implemented Once)
|
||||
|
||||
B32
|
||||
os_write_data_to_file_path(String8 path, String8 data)
|
||||
MD_B32
|
||||
md_os_write_data_to_file_path(MD_String8 path, MD_String8 data)
|
||||
{
|
||||
B32 good = 0;
|
||||
OS_Handle file = os_file_open(OS_AccessFlag_Write, path);
|
||||
if(! os_handle_match(file, os_handle_zero()))
|
||||
MD_B32 good = 0;
|
||||
MD_OS_Handle file = md_os_file_open(MD_OS_AccessFlag_Write, path);
|
||||
if(! md_os_handle_match(file, md_os_handle_zero()))
|
||||
{
|
||||
good = 1;
|
||||
os_file_write(file, r1u64(0, data.size), data.str);
|
||||
os_file_close(file);
|
||||
md_os_file_write(file, md_r1u64(0, data.size), data.str);
|
||||
md_os_file_close(file);
|
||||
}
|
||||
return good;
|
||||
}
|
||||
|
||||
B32
|
||||
os_write_data_list_to_file_path(String8 path, String8List list)
|
||||
MD_B32
|
||||
md_os_write_data_list_to_file_path(MD_String8 path, MD_String8List list)
|
||||
{
|
||||
B32 good = 0;
|
||||
OS_Handle file = os_file_open(OS_AccessFlag_Write, path);
|
||||
if( ! os_handle_match(file, os_handle_zero()))
|
||||
MD_B32 good = 0;
|
||||
MD_OS_Handle file = md_os_file_open(MD_OS_AccessFlag_Write, path);
|
||||
if( ! md_os_handle_match(file, md_os_handle_zero()))
|
||||
{
|
||||
good = 1;
|
||||
U64 off = 0;
|
||||
for(String8Node* n = list.first; n != 0; n = n->next)
|
||||
MD_U64 off = 0;
|
||||
for(MD_String8Node* n = list.first; n != 0; n = n->next)
|
||||
{
|
||||
os_file_write(file, r1u64(off, off+n->string.size), n->string.str);
|
||||
md_os_file_write(file, md_r1u64(off, off+n->string.size), n->string.str);
|
||||
off += n->string.size;
|
||||
}
|
||||
os_file_close(file);
|
||||
md_os_file_close(file);
|
||||
}
|
||||
return good;
|
||||
}
|
||||
|
||||
B32
|
||||
os_append_data_to_file_path(String8 path, String8 data)
|
||||
MD_B32
|
||||
md_os_append_data_to_file_path(MD_String8 path, MD_String8 data)
|
||||
{
|
||||
B32 good = 0;
|
||||
MD_B32 good = 0;
|
||||
if(data.size != 0)
|
||||
{
|
||||
OS_Handle file = os_file_open(OS_AccessFlag_Write|OS_AccessFlag_Append, path);
|
||||
if( ! os_handle_match(file, os_handle_zero()))
|
||||
MD_OS_Handle file = md_os_file_open(MD_OS_AccessFlag_Write|MD_OS_AccessFlag_Append, path);
|
||||
if( ! md_os_handle_match(file, md_os_handle_zero()))
|
||||
{
|
||||
good = 1;
|
||||
U64 pos = os_properties_from_file(file).size;
|
||||
os_file_write(file, r1u64(pos, pos+data.size), data.str);
|
||||
os_file_close(file);
|
||||
MD_U64 pos = md_os_properties_from_file(file).size;
|
||||
md_os_file_write(file, md_r1u64(pos, pos+data.size), data.str);
|
||||
md_os_file_close(file);
|
||||
}
|
||||
}
|
||||
return good;
|
||||
}
|
||||
|
||||
String8
|
||||
os_string_from_file_range__arena(Arena* arena, OS_Handle file, Rng1U64 range)
|
||||
MD_String8
|
||||
md_os_string_from_file_range__arena(MD_Arena* arena, MD_OS_Handle file, MD_Rng1U64 range)
|
||||
{
|
||||
U64 pre_pos = arena_pos(arena);
|
||||
String8 result;
|
||||
result.size = dim_1u64(range);
|
||||
result.str = push_array_no_zero(arena, U8, result.size);
|
||||
U64 actual_read_size = os_file_read(file, range, result.str);
|
||||
MD_U64 pre_pos = md_arena_pos(arena);
|
||||
MD_String8 result;
|
||||
result.size = md_dim_1u64(range);
|
||||
result.str = md_push_array__no_zero(arena, MD_U8, result.size);
|
||||
MD_U64 actual_read_size = md_os_file_read(file, range, result.str);
|
||||
if(actual_read_size < result.size) {
|
||||
arena_pop_to(arena, pre_pos + actual_read_size);
|
||||
md_arena_pop_to(arena, pre_pos + actual_read_size);
|
||||
result.size = actual_read_size;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
String8
|
||||
os_string_from_file_range__ainfo(AllocatorInfo ainfo, OS_Handle file, Rng1U64 range) {
|
||||
String8 result;
|
||||
result.size = dim_1u64(range);
|
||||
result.str = alloc_array_no_zero(ainfo, U8, result.size);
|
||||
U64 actual_read_size = os_file_read(file, range, result.str);
|
||||
if ((allocator_query_support(ainfo) & AllocatorQuery_ResizeShrink) && actual_read_size < result.size) {
|
||||
resize(ainfo, result.str, result.size, actual_read_size);
|
||||
MD_String8
|
||||
md_os_string_from_file_range__ainfo(MD_AllocatorInfo ainfo, MD_OS_Handle file, MD_Rng1U64 range) {
|
||||
MD_String8 result;
|
||||
result.size = md_dim_1u64(range);
|
||||
result.str = md_alloc_array_no_zero(ainfo, MD_U8, result.size);
|
||||
MD_U64 actual_read_size = md_os_file_read(file, range, result.str);
|
||||
if ((md_allocator_query_support(ainfo) & MD_AllocatorQuery_ResizeShrink) && actual_read_size < result.size) {
|
||||
md_resize(ainfo, result.str, result.size, actual_read_size);
|
||||
result.size = actual_read_size;
|
||||
}
|
||||
return result;
|
||||
|
||||
+246
-246
@@ -12,171 +12,171 @@
|
||||
////////////////////////////////
|
||||
//~ rjf: System Info
|
||||
|
||||
typedef struct OS_SystemInfo OS_SystemInfo;
|
||||
struct OS_SystemInfo
|
||||
typedef struct MD_OS_SystemInfo MD_OS_SystemInfo;
|
||||
struct MD_OS_SystemInfo
|
||||
{
|
||||
U32 logical_processor_count;
|
||||
U64 page_size;
|
||||
U64 large_page_size;
|
||||
U64 allocation_granularity;
|
||||
String8 machine_name;
|
||||
MD_U32 logical_processor_count;
|
||||
MD_U64 page_size;
|
||||
MD_U64 large_page_size;
|
||||
MD_U64 allocation_granularity;
|
||||
MD_String8 machine_name;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Process Info
|
||||
|
||||
typedef struct OS_ProcessInfo OS_ProcessInfo;
|
||||
struct OS_ProcessInfo
|
||||
typedef struct MD_OS_ProcessInfo MD_OS_ProcessInfo;
|
||||
struct MD_OS_ProcessInfo
|
||||
{
|
||||
U32 pid;
|
||||
String8 binary_path;
|
||||
String8 initial_path;
|
||||
String8 user_program_data_path;
|
||||
String8List module_load_paths;
|
||||
String8List environment;
|
||||
MD_U32 pid;
|
||||
MD_String8 binary_path;
|
||||
MD_String8 initial_path;
|
||||
MD_String8 user_program_data_path;
|
||||
MD_String8List module_load_paths;
|
||||
MD_String8List environment;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Access Flags
|
||||
|
||||
typedef U32 OS_AccessFlags;
|
||||
typedef MD_U32 MD_OS_AccessFlags;
|
||||
enum
|
||||
{
|
||||
OS_AccessFlag_Read = (1 << 0),
|
||||
OS_AccessFlag_Write = (1 << 1),
|
||||
OS_AccessFlag_Execute = (1 << 2),
|
||||
OS_AccessFlag_Append = (1 << 3),
|
||||
OS_AccessFlag_ShareRead = (1 << 4),
|
||||
OS_AccessFlag_ShareWrite = (1 << 5),
|
||||
MD_OS_AccessFlag_Read = (1 << 0),
|
||||
MD_OS_AccessFlag_Write = (1 << 1),
|
||||
MD_OS_AccessFlag_Execute = (1 << 2),
|
||||
MD_OS_AccessFlag_Append = (1 << 3),
|
||||
MD_OS_AccessFlag_ShareRead = (1 << 4),
|
||||
MD_OS_AccessFlag_ShareWrite = (1 << 5),
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Files
|
||||
|
||||
typedef U32 OS_FileIterFlags;
|
||||
typedef MD_U32 MD_OS_FileIterFlags;
|
||||
enum
|
||||
{
|
||||
OS_FileIterFlag_SkipFolders = (1 << 0),
|
||||
OS_FileIterFlag_SkipFiles = (1 << 1),
|
||||
OS_FileIterFlag_SkipHiddenFiles = (1 << 2),
|
||||
OS_FileIterFlag_Done = (1 << 31),
|
||||
MD_OS_FileIterFlag_SkipFolders = (1 << 0),
|
||||
MD_OS_FileIterFlag_SkipFiles = (1 << 1),
|
||||
MD_OS_FileIterFlag_SkipHiddenFiles = (1 << 2),
|
||||
MD_OS_FileIterFlag_Done = (1 << 31),
|
||||
};
|
||||
|
||||
typedef struct OS_FileIter OS_FileIter;
|
||||
struct OS_FileIter
|
||||
typedef struct MD_OS_FileIter MD_OS_FileIter;
|
||||
struct MD_OS_FileIter
|
||||
{
|
||||
OS_FileIterFlags flags;
|
||||
U8 memory[800];
|
||||
MD_OS_FileIterFlags flags;
|
||||
MD_U8 memory[800];
|
||||
};
|
||||
|
||||
typedef struct OS_FileInfo OS_FileInfo;
|
||||
struct OS_FileInfo
|
||||
typedef struct MD_OS_FileInfo MD_OS_FileInfo;
|
||||
struct MD_OS_FileInfo
|
||||
{
|
||||
String8 name;
|
||||
FileProperties props;
|
||||
MD_String8 name;
|
||||
MD_FileProperties props;
|
||||
};
|
||||
|
||||
// nick: on-disk file identifier
|
||||
typedef struct OS_FileID OS_FileID;
|
||||
struct OS_FileID
|
||||
typedef struct MD_OS_FileID MD_OS_FileID;
|
||||
struct MD_OS_FileID
|
||||
{
|
||||
U64 v[3];
|
||||
MD_U64 v[3];
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Process Launch Parameters
|
||||
|
||||
typedef struct OS_ProcessLaunchParams OS_ProcessLaunchParams;
|
||||
struct OS_ProcessLaunchParams
|
||||
typedef struct MD_OS_ProcessLaunchParams MD_OS_ProcessLaunchParams;
|
||||
struct MD_OS_ProcessLaunchParams
|
||||
{
|
||||
String8List cmd_line;
|
||||
String8 path;
|
||||
String8List env;
|
||||
B32 inherit_env;
|
||||
B32 consoleless;
|
||||
MD_String8List cmd_line;
|
||||
MD_String8 path;
|
||||
MD_String8List env;
|
||||
MD_B32 inherit_env;
|
||||
MD_B32 consoleless;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Handle Type
|
||||
|
||||
typedef struct OS_Handle OS_Handle;
|
||||
struct OS_Handle
|
||||
typedef struct MD_OS_Handle MD_OS_Handle;
|
||||
struct MD_OS_Handle
|
||||
{
|
||||
U64 u64[1];
|
||||
MD_U64 u64[1];
|
||||
};
|
||||
|
||||
typedef struct OS_HandleNode OS_HandleNode;
|
||||
struct OS_HandleNode
|
||||
typedef struct MD_OS_HandleNode MD_OS_HandleNode;
|
||||
struct MD_OS_HandleNode
|
||||
{
|
||||
OS_HandleNode* next;
|
||||
OS_Handle v;
|
||||
MD_OS_HandleNode* next;
|
||||
MD_OS_Handle v;
|
||||
};
|
||||
|
||||
typedef struct OS_HandleList OS_HandleList;
|
||||
struct OS_HandleList
|
||||
typedef struct MD_OS_HandleList MD_OS_HandleList;
|
||||
struct MD_OS_HandleList
|
||||
{
|
||||
OS_HandleNode* first;
|
||||
OS_HandleNode* last;
|
||||
U64 count;
|
||||
MD_OS_HandleNode* first;
|
||||
MD_OS_HandleNode* last;
|
||||
MD_U64 count;
|
||||
};
|
||||
|
||||
typedef struct OS_HandleArray OS_HandleArray;
|
||||
struct OS_HandleArray
|
||||
typedef struct MD_OS_HandleArray MD_OS_HandleArray;
|
||||
struct MD_OS_HandleArray
|
||||
{
|
||||
OS_Handle* v;
|
||||
U64 count;
|
||||
MD_OS_Handle* v;
|
||||
MD_U64 count;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Globally Unique IDs
|
||||
|
||||
typedef struct OS_Guid OS_Guid;
|
||||
struct OS_Guid
|
||||
typedef struct MD_OS_Guid MD_OS_Guid;
|
||||
struct MD_OS_Guid
|
||||
{
|
||||
U32 data1;
|
||||
U16 data2;
|
||||
U16 data3;
|
||||
U8 data4[8];
|
||||
MD_U32 data1;
|
||||
MD_U16 data2;
|
||||
MD_U16 data3;
|
||||
MD_U8 data4[8];
|
||||
};
|
||||
md_static_assert(size_of(OS_Guid) == 16, os_guid_check);
|
||||
md_static_assert(size_of(MD_OS_Guid) == 16, md_os_guid_check);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Thread Types
|
||||
|
||||
typedef void OS_ThreadFunctionType(void *ptr);
|
||||
typedef void MD_OS_ThreadFunctionType(void *ptr);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Handle Type Functions (Helpers, Implemented Once)
|
||||
|
||||
force_inline OS_Handle os_handle_zero (void) { OS_Handle handle = {0}; return handle; }
|
||||
force_inline B32 os_handle_match(OS_Handle a, OS_Handle b) { return a.u64[0] == b.u64[0]; }
|
||||
md_force_inline MD_OS_Handle md_os_handle_zero (void) { MD_OS_Handle handle = {0}; return handle; }
|
||||
md_force_inline MD_B32 md_os_handle_match(MD_OS_Handle a, MD_OS_Handle b) { return a.u64[0] == b.u64[0]; }
|
||||
|
||||
void os_handle_list_push__arena (Arena* arena, OS_HandleList* handles, OS_Handle handle);
|
||||
void os_handle_list_push__ainfo (AllocatorInfo ainfo, OS_HandleList* handles, OS_Handle handle);
|
||||
OS_HandleArray os_handle_array_from_list__arena(Arena* arena, OS_HandleList* list);
|
||||
OS_HandleArray os_handle_array_from_list__ainfo(AllocatorInfo ainfo, OS_HandleList* list);
|
||||
void md_os_handle_list_push__arena (MD_Arena* arena, MD_OS_HandleList* handles, MD_OS_Handle handle);
|
||||
void md_os_handle_list_push__ainfo (MD_AllocatorInfo ainfo, MD_OS_HandleList* handles, MD_OS_Handle handle);
|
||||
MD_OS_HandleArray md_os_handle_array_from_list__arena(MD_Arena* arena, MD_OS_HandleList* list);
|
||||
MD_OS_HandleArray md_os_handle_array_from_list__ainfo(MD_AllocatorInfo ainfo, MD_OS_HandleList* list);
|
||||
|
||||
#define os_handle_ist_push(arena, handles, handle) _Generic(allocator, Arena*: os_handle_list_push__arena, AllocatorInfo: os_handle_list_push__ainfo, default: assert_generic_sel_fail) generic_call(allocator, handles, handle)
|
||||
#define os_handle_array_from_list(allocator, list) _Generic(allocator, Arena*: os_handle_array_from_list__arena, AllocatorInfo: os_handle_list_push__ainfo, default: assert_generic_sel_fail) generic_call(allocator, list)
|
||||
#define md_os_handle_ist_push(arena, handles, handle) _Generic(allocator, MD_Arena*: md_os_handle_list_push__arena, MD_AllocatorInfo: md_os_handle_list_push__ainfo, default: md_assert_generic_sel_fail) md_generic_call(allocator, handles, handle)
|
||||
#define md_os_handle_array_from_list(allocator, list) _Generic(allocator, MD_Arena*: md_os_handle_array_from_list__arena, MD_AllocatorInfo: md_os_handle_list_push__ainfo, default: md_assert_generic_sel_fail) md_generic_call(allocator, list)
|
||||
|
||||
force_inline void os_handle_list_push__arena (Arena* arena, OS_HandleList* handles, OS_Handle handle) { os_handle_list__push_ainfo (arena_allocator(arena), handles, handle); }
|
||||
force_inline OS_HandleArray os_handle_array_from_list__arena(Arena* arena, OS_HandleList* list) { return os_handle_array_from_list__ainfo(arena_allocator(arena), list); }
|
||||
md_force_inline void md_os_handle_list_push__arena (MD_Arena* arena, MD_OS_HandleList* handles, MD_OS_Handle handle) { md_os_handle_list__push_ainfo (md_arena_allocator(arena), handles, handle); }
|
||||
md_force_inline MD_OS_HandleArray md_os_handle_array_from_list__arena(MD_Arena* arena, MD_OS_HandleList* list) { return md_os_handle_array_from_list__ainfo(md_arena_allocator(arena), list); }
|
||||
|
||||
inline void
|
||||
os_handle_list_alloc(AllocatorInfo ainfo, OS_HandleList* handles, OS_Handle handle) {
|
||||
OS_HandleNode* n = alloc_array(ainfo, OS_HandleNode, 1);
|
||||
md_os_handle_list_alloc(MD_AllocatorInfo ainfo, MD_OS_HandleList* handles, MD_OS_Handle handle) {
|
||||
MD_OS_HandleNode* n = md_alloc_array(ainfo, MD_OS_HandleNode, 1);
|
||||
n->v = handle;
|
||||
sll_queue_push(handles->first, handles->last, n);
|
||||
md_sll_queue_push(handles->first, handles->last, n);
|
||||
handles->count += 1;
|
||||
}
|
||||
|
||||
inline OS_HandleArray
|
||||
os_handle_array_from_list_alloc(AllocatorInfo ainfo, OS_HandleList* list) {
|
||||
OS_HandleArray result = {0};
|
||||
inline MD_OS_HandleArray
|
||||
md_os_handle_array_from_list_alloc(MD_AllocatorInfo ainfo, MD_OS_HandleList* list) {
|
||||
MD_OS_HandleArray result = {0};
|
||||
result.count = list->count;
|
||||
result.v = alloc_array_no_zero(ainfo, OS_Handle, result.count);
|
||||
U64 idx = 0;
|
||||
for(OS_HandleNode* n = list->first; n != 0; n = n->next, idx += 1) {
|
||||
result.v = md_alloc_array_no_zero(ainfo, MD_OS_Handle, result.count);
|
||||
MD_U64 idx = 0;
|
||||
for(MD_OS_HandleNode* n = list->first; n != 0; n = n->next, idx += 1) {
|
||||
result.v[idx] = n->v;
|
||||
}
|
||||
return result;
|
||||
@@ -185,121 +185,121 @@ os_handle_array_from_list_alloc(AllocatorInfo ainfo, OS_HandleList* list) {
|
||||
////////////////////////////////
|
||||
//~ rjf: Command Line Argc/Argv Helper (Helper, Implemented Once)
|
||||
|
||||
String8List os_string_list_from_argcv__arena(Arena* arena, int argc, char** argv);
|
||||
String8List os_string_list_from_argcv__ainfo(AllocatorInfo ainfo, int argc, char** argv);
|
||||
MD_String8List md_os_string_list_from_argcv__arena(MD_Arena* arena, int argc, char** argv);
|
||||
MD_String8List md_os_string_list_from_argcv__ainfo(MD_AllocatorInfo ainfo, int argc, char** argv);
|
||||
|
||||
inline String8List
|
||||
os_string_list_from_argcv__ainfo(AllocatorInfo ainfo, int argc, char** argv) {
|
||||
String8List result = {0};
|
||||
inline MD_String8List
|
||||
md_os_string_list_from_argcv__ainfo(MD_AllocatorInfo ainfo, int argc, char** argv) {
|
||||
MD_String8List result = {0};
|
||||
for(int i = 0; i < argc; i += 1)
|
||||
{
|
||||
String8 str = str8_cstring(argv[i]);
|
||||
str8_list_push(ainfo, &result, str);
|
||||
MD_String8 str = md_str8_cstring(argv[i]);
|
||||
md_str8_list_push(ainfo, &result, str);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
#define os_string_list_from_argcv(allocator, argc, argv) _Generic(allocator, Arena*: os_string_list_from_argcv__arena, AllocatorInfo: os_string_list_from_argcv__ainfo, default: assert_generic_sel_fail) generic_call(allocator, argc, argv)
|
||||
#define md_os_string_list_from_argcv(allocator, argc, argv) _Generic(allocator, MD_Arena*: md_os_string_list_from_argcv__arena, MD_AllocatorInfo: md_os_string_list_from_argcv__ainfo, default: md_assert_generic_sel_fail) md_generic_call(allocator, argc, argv)
|
||||
|
||||
force_inline String8List os_string_list_from_argcv__arena(Arena* arena, int argc, char** argv) { return os_string_list_from_argcv__ainfo(arena_allocator(arena), argc, argv); }
|
||||
md_force_inline MD_String8List md_os_string_list_from_argcv__arena(MD_Arena* arena, int argc, char** argv) { return md_os_string_list_from_argcv__ainfo(md_arena_allocator(arena), argc, argv); }
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks File System (Implemented Per-OS)
|
||||
//~ rjf: @md_os_hooks File System (Implemented Per-OS)
|
||||
|
||||
//- rjf: files
|
||||
MD_API OS_Handle os_file_open (OS_AccessFlags flags, String8 path);
|
||||
MD_API void os_file_close (OS_Handle file);
|
||||
MD_API U64 os_file_read (OS_Handle file, Rng1U64 rng, void *out_data);
|
||||
MD_API U64 os_file_write (OS_Handle file, Rng1U64 rng, void *data);
|
||||
MD_API B32 os_file_set_times (OS_Handle file, DateTime time);
|
||||
MD_API FileProperties os_properties_from_file (OS_Handle file);
|
||||
MD_API OS_FileID os_id_from_file (OS_Handle file);
|
||||
MD_API B32 os_delete_file_at_path (String8 path);
|
||||
MD_API B32 os_copy_file_path (String8 dst, String8 src);
|
||||
MD_API B32 os_file_path_exists (String8 path);
|
||||
MD_API FileProperties os_properties_from_file_path (String8 path);
|
||||
MD_API String8 os_full_path_from_path__arena(Arena* arena, String8 path);
|
||||
MD_API String8 os_full_path_from_path__ainfo(AllocatorInfo arena, String8 path);
|
||||
MD_API MD_OS_Handle md_os_file_open (MD_OS_AccessFlags flags, MD_String8 path);
|
||||
MD_API void md_os_file_close (MD_OS_Handle file);
|
||||
MD_API MD_U64 md_os_file_read (MD_OS_Handle file, MD_Rng1U64 rng, void *out_data);
|
||||
MD_API MD_U64 md_os_file_write (MD_OS_Handle file, MD_Rng1U64 rng, void *data);
|
||||
MD_API MD_B32 md_os_file_set_times (MD_OS_Handle file, MD_DateTime time);
|
||||
MD_API MD_FileProperties md_os_properties_from_file (MD_OS_Handle file);
|
||||
MD_API MD_OS_FileID md_os_id_from_file (MD_OS_Handle file);
|
||||
MD_API MD_B32 md_os_delete_file_at_path (MD_String8 path);
|
||||
MD_API MD_B32 md_os_copy_file_path (MD_String8 dst, MD_String8 src);
|
||||
MD_API MD_B32 md_os_file_path_exists (MD_String8 path);
|
||||
MD_API MD_FileProperties md_os_properties_from_file_path (MD_String8 path);
|
||||
MD_API MD_String8 md_os_full_path_from_path__arena(MD_Arena* arena, MD_String8 path);
|
||||
MD_API MD_String8 md_os_full_path_from_path__ainfo(MD_AllocatorInfo arena, MD_String8 path);
|
||||
|
||||
#define os_full_path_from_path(allocator, path) _Generic(allocator, Arena*: os_full_path_from_path__arena, AllocatorInfo: os_full_path_from_path__ainfo, default: assert_generic_sel_fail) generic_call(allocator, path)
|
||||
#define md_os_full_path_from_path(allocator, path) _Generic(allocator, MD_Arena*: md_os_full_path_from_path__arena, MD_AllocatorInfo: md_os_full_path_from_path__ainfo, default: md_assert_generic_sel_fail) md_generic_call(allocator, path)
|
||||
|
||||
force_inline String8 os_full_path_from_path__arena(Arena* arena, String8 path) { return os_full_path_from_path__ainfo(arena_allocator(arena), path); }
|
||||
md_force_inline MD_String8 md_os_full_path_from_path__arena(MD_Arena* arena, MD_String8 path) { return md_os_full_path_from_path__ainfo(md_arena_allocator(arena), path); }
|
||||
|
||||
//- rjf: file maps
|
||||
MD_API OS_Handle os_file_map_open (OS_AccessFlags flags, OS_Handle file);
|
||||
MD_API void os_file_map_close (OS_Handle map);
|
||||
MD_API void* os_file_map_view_open (OS_Handle map, OS_AccessFlags flags, Rng1U64 range);
|
||||
MD_API void os_file_map_view_close(OS_Handle map, void* ptr, Rng1U64 range);
|
||||
MD_API MD_OS_Handle md_os_file_map_open (MD_OS_AccessFlags flags, MD_OS_Handle file);
|
||||
MD_API void md_os_file_map_close (MD_OS_Handle map);
|
||||
MD_API void* md_os_file_map_view_open (MD_OS_Handle map, MD_OS_AccessFlags flags, MD_Rng1U64 range);
|
||||
MD_API void md_os_file_map_view_close(MD_OS_Handle map, void* ptr, MD_Rng1U64 range);
|
||||
|
||||
//- rjf: directory iteration
|
||||
OS_FileIter* os_file_iter_begin__arena(Arena* arena, String8 path, OS_FileIterFlags flags);
|
||||
MD_API OS_FileIter* os_file_iter_begin__ainfo(AllocatorInfo ainfo, String8 path, OS_FileIterFlags flags);
|
||||
B32 os_file_iter_next__arena (Arena* arena, OS_FileIter* iter, OS_FileInfo* info_out);
|
||||
MD_API B32 os_file_iter_next__ainfo (AllocatorInfo arena, OS_FileIter* iter, OS_FileInfo* info_out);
|
||||
MD_API void os_file_iter_end ( OS_FileIter* iter);
|
||||
MD_OS_FileIter* md_os_file_iter_begin__arena(MD_Arena* arena, MD_String8 path, MD_OS_FileIterFlags flags);
|
||||
MD_API MD_OS_FileIter* md_os_file_iter_begin__ainfo(MD_AllocatorInfo ainfo, MD_String8 path, MD_OS_FileIterFlags flags);
|
||||
MD_B32 md_os_file_iter_next__arena (MD_Arena* arena, MD_OS_FileIter* iter, MD_OS_FileInfo* info_out);
|
||||
MD_API MD_B32 md_os_file_iter_next__ainfo (MD_AllocatorInfo arena, MD_OS_FileIter* iter, MD_OS_FileInfo* info_out);
|
||||
MD_API void md_os_file_iter_end ( MD_OS_FileIter* iter);
|
||||
|
||||
#define os_file_iter_begin(allocator, path, flags) _Generic(allocator, Arena*: os_file_iter_begin__arena, AllocatorInfo: os_file_iter_begin__ainfo, default: assert_generic_sel_fail) generic_call(allocator, path)
|
||||
#define os_file_iter_next(allocator, iter, info_out) _Generic(allocator, Arena*: os_file_iter_next__arena, AllocatorInfo: os_file_iter_next__ainfo, default: assert_generic_sel_fail) generic_call(allocator, path)
|
||||
#define md_os_file_iter_begin(allocator, path, flags) _Generic(allocator, MD_Arena*: md_os_file_iter_begin__arena, MD_AllocatorInfo: md_os_file_iter_begin__ainfo, default: md_assert_generic_sel_fail) md_generic_call(allocator, path)
|
||||
#define md_os_file_iter_next(allocator, iter, info_out) _Generic(allocator, MD_Arena*: md_os_file_iter_next__arena, MD_AllocatorInfo: md_os_file_iter_next__ainfo, default: md_assert_generic_sel_fail) md_generic_call(allocator, path)
|
||||
|
||||
force_inline OS_FileIter* os_file_iter_begin__arena(Arena* arena, String8 path, OS_FileIterFlags flags) { reutrn (); }
|
||||
force_inline B32 os_file_iter_next__arena (Arena* arena, OS_FileIter* iter, OS_FileInfo* info_out) { reutrn (); }
|
||||
md_force_inline MD_OS_FileIter* md_os_file_iter_begin__arena(MD_Arena* arena, MD_String8 path, MD_OS_FileIterFlags flags) { reutrn (); }
|
||||
md_force_inline MD_B32 md_os_file_iter_next__arena (MD_Arena* arena, MD_OS_FileIter* iter, MD_OS_FileInfo* info_out) { reutrn (); }
|
||||
|
||||
//- rjf: directory creation
|
||||
MD_API B32 os_make_directory(String8 path);
|
||||
MD_API MD_B32 md_os_make_directory(MD_String8 path);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Filesystem Helpers (Helpers, Implemented Once)
|
||||
|
||||
MD_API B32 os_write_data_to_file_path (String8 path, String8 data);
|
||||
MD_API B32 os_write_data_list_to_file_path(String8 path, String8List list);
|
||||
MD_API B32 os_append_data_to_file_path (String8 path, String8 data);
|
||||
OS_FileID os_id_from_file_path (String8 path);
|
||||
S64 os_file_id_compare (OS_FileID a, OS_FileID b);
|
||||
MD_API MD_B32 md_os_write_data_to_file_path (MD_String8 path, MD_String8 data);
|
||||
MD_API MD_B32 md_os_write_data_list_to_file_path(MD_String8 path, MD_String8List list);
|
||||
MD_API MD_B32 md_os_append_data_to_file_path (MD_String8 path, MD_String8 data);
|
||||
MD_OS_FileID md_os_id_from_file_path (MD_String8 path);
|
||||
MD_S64 md_os_file_id_compare (MD_OS_FileID a, MD_OS_FileID b);
|
||||
|
||||
String8 os_data_from_file_path__arena (Arena* arena, String8 path);
|
||||
String8 os_data_from_file_path__ainfo (AllocatorInfo ainfo, String8 path);
|
||||
MD_API String8 os_string_from_file_range__arena(Arena* arena, OS_Handle file, Rng1U64 range);
|
||||
MD_API String8 os_string_from_file_range__ainfo(AllocatorInfo ainfo, OS_Handle file, Rng1U64 range);
|
||||
MD_String8 md_os_data_from_file_path__arena (MD_Arena* arena, MD_String8 path);
|
||||
MD_String8 md_os_data_from_file_path__ainfo (MD_AllocatorInfo ainfo, MD_String8 path);
|
||||
MD_API MD_String8 md_os_string_from_file_range__arena(MD_Arena* arena, MD_OS_Handle file, MD_Rng1U64 range);
|
||||
MD_API MD_String8 md_os_string_from_file_range__ainfo(MD_AllocatorInfo ainfo, MD_OS_Handle file, MD_Rng1U64 range);
|
||||
|
||||
#define os_data_from_file_path(allocator, path) _Generic(allocator, Arena*: os_data_from_file_path__arena, AllocatorInfo: os_data_from_file_path__ainfo, default: assert_generic_sel_fail) generic_call(allocator, path)
|
||||
#define os_string_from_file_range(allocator, file, range) _Generic(allocator, Arena*: os_string_from_file_range__arena, AllocatorInfo: os_string_from_file_range__ainfo, default: assert_generic_sel_fail) generic_call(allocator, file, range)
|
||||
#define md_os_data_from_file_path(allocator, path) _Generic(allocator, MD_Arena*: md_os_data_from_file_path__arena, MD_AllocatorInfo: md_os_data_from_file_path__ainfo, default: md_assert_generic_sel_fail) md_generic_call(allocator, path)
|
||||
#define md_os_string_from_file_range(allocator, file, range) _Generic(allocator, MD_Arena*: md_os_string_from_file_range__arena, MD_AllocatorInfo: md_os_string_from_file_range__ainfo, default: md_assert_generic_sel_fail) md_generic_call(allocator, file, range)
|
||||
|
||||
force_inline String8 os_data_from_file_path__arena(Arena* arena, String8 path) { return os_data_from_file_path__ainfo(arena_allocator(arena), path); }
|
||||
md_force_inline MD_String8 md_os_data_from_file_path__arena(MD_Arena* arena, MD_String8 path) { return md_os_data_from_file_path__ainfo(md_arena_allocator(arena), path); }
|
||||
|
||||
inline String8
|
||||
os_data_from_file_path__ainfo(AllocatorInfo ainfo, String8 path)
|
||||
inline MD_String8
|
||||
md_os_data_from_file_path__ainfo(MD_AllocatorInfo ainfo, MD_String8 path)
|
||||
{
|
||||
OS_Handle file = os_file_open(OS_AccessFlag_Read | OS_AccessFlag_ShareRead, path);
|
||||
FileProperties props = os_properties_from_file(file);
|
||||
String8 data = os_string_from_file_range(ainfo, file, r1u64(0, props.size));
|
||||
os_file_close(file);
|
||||
MD_OS_Handle file = md_os_file_open(MD_OS_AccessFlag_Read | MD_OS_AccessFlag_ShareRead, path);
|
||||
MD_FileProperties props = md_os_properties_from_file(file);
|
||||
MD_String8 data = md_os_string_from_file_range(ainfo, file, md_r1u64(0, props.size));
|
||||
md_os_file_close(file);
|
||||
return data;
|
||||
}
|
||||
|
||||
inline OS_FileID
|
||||
os_id_from_file_path(String8 path) {
|
||||
OS_Handle file = os_file_open(OS_AccessFlag_Read | OS_AccessFlag_ShareRead, path);
|
||||
OS_FileID id = os_id_from_file(file);
|
||||
os_file_close(file);
|
||||
inline MD_OS_FileID
|
||||
md_os_id_from_file_path(MD_String8 path) {
|
||||
MD_OS_Handle file = md_os_file_open(MD_OS_AccessFlag_Read | MD_OS_AccessFlag_ShareRead, path);
|
||||
MD_OS_FileID id = md_os_id_from_file(file);
|
||||
md_os_file_close(file);
|
||||
return id;
|
||||
}
|
||||
|
||||
inline S64 os_file_id_compare(OS_FileID a, OS_FileID b) { S64 cmp = memory_compare((void*)&a.v[0], (void*)&b.v[0], sizeof(a.v)); return cmp; }
|
||||
inline MD_S64 md_os_file_id_compare(MD_OS_FileID a, MD_OS_FileID b) { MD_S64 cmp = md_memory_compare((void*)&a.v[0], (void*)&b.v[0], sizeof(a.v)); return cmp; }
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: GUID Helpers (Helpers, Implemented Once)
|
||||
|
||||
String8 os_string_from_guid__arena(Arena* arena, OS_Guid guid);
|
||||
String8 os_string_from_guid__ainfo(AllocatorInfo ainfo, OS_Guid guid);
|
||||
MD_String8 md_os_string_from_guid__arena(MD_Arena* arena, MD_OS_Guid guid);
|
||||
MD_String8 md_os_string_from_guid__ainfo(MD_AllocatorInfo ainfo, MD_OS_Guid guid);
|
||||
|
||||
#define os_string_from_guid(allocator, guid) _Generic(allocator, Arena*: os_string_from_guid__arena, AllocatorInfo: os_string_from_guid__ainfo, default: assert_generic_sel_fail) generic_call(allocator, guid)
|
||||
#define md_os_string_from_guid(allocator, guid) _Generic(allocator, MD_Arena*: md_os_string_from_guid__arena, MD_AllocatorInfo: md_os_string_from_guid__ainfo, default: md_assert_generic_sel_fail) md_generic_call(allocator, guid)
|
||||
|
||||
force_inline String8 os_string_from_guid__arena(Arena* arena, OS_Guid guid) { os_string_from_guid__ainfo(arena_allocator(arena), guid); }
|
||||
md_force_inline MD_String8 md_os_string_from_guid__arena(MD_Arena* arena, MD_OS_Guid guid) { md_os_string_from_guid__ainfo(md_arena_allocator(arena), guid); }
|
||||
|
||||
inline String8
|
||||
os_string_from_guid_alloc(AllocatorInfo ainfo, OS_Guid guid) {
|
||||
inline MD_String8
|
||||
md_os_string_from_guid_alloc(MD_AllocatorInfo ainfo, MD_OS_Guid guid) {
|
||||
|
||||
String8 result = str8f(ainfo,
|
||||
MD_String8 result = md_str8f(ainfo,
|
||||
"%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X",
|
||||
guid.data1,
|
||||
guid.data2,
|
||||
@@ -317,155 +317,155 @@ os_string_from_guid_alloc(AllocatorInfo ainfo, OS_Guid guid) {
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks System/Process Info (Implemented Per-OS)
|
||||
//~ rjf: @md_os_hooks System/Process Info (Implemented Per-OS)
|
||||
|
||||
MD_API OS_SystemInfo* os_get_system_info (void);
|
||||
MD_API OS_ProcessInfo* os_get_process_info(void);
|
||||
MD_API MD_OS_SystemInfo* md_os_get_system_info (void);
|
||||
MD_API MD_OS_ProcessInfo* md_os_get_process_info(void);
|
||||
|
||||
String8 os_get_current_path__arena(Arena* arena);
|
||||
String8 os_get_current_path__ainfo(AllocatorInfo arena);
|
||||
MD_String8 md_os_get_current_path__arena(MD_Arena* arena);
|
||||
MD_String8 md_os_get_current_path__ainfo(MD_AllocatorInfo arena);
|
||||
|
||||
#define os_get_current_path(allocator) _Generic(allocator, Arena*: os_get_current_path__arena, AllocatorInfo: os_get_current_path__ainfo) generic_call(allocator)
|
||||
#define md_os_get_current_path(allocator) _Generic(allocator, MD_Arena*: md_os_get_current_path__arena, MD_AllocatorInfo: md_os_get_current_path__ainfo) md_generic_call(allocator)
|
||||
|
||||
force_inline String8 os_get_current_path__arena(Arena* arena) { return os_get_current_path__ainfo(arena_allocator(arena)); }
|
||||
md_force_inline MD_String8 md_os_get_current_path__arena(MD_Arena* arena) { return md_os_get_current_path__ainfo(md_arena_allocator(arena)); }
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Memory Allocation (Implemented Per-OS)
|
||||
//~ rjf: @md_os_hooks Memory Allocation (Implemented Per-OS)
|
||||
|
||||
//- rjf: basic
|
||||
void* os_reserve ( U64 size);
|
||||
B32 os_commit (void* ptr, U64 size);
|
||||
void os_decommit(void* ptr, U64 size);
|
||||
void os_release (void* ptr, U64 size);
|
||||
void* md_os_reserve ( MD_U64 size);
|
||||
MD_B32 md_os_commit (void* ptr, MD_U64 size);
|
||||
void md_os_decommit(void* ptr, MD_U64 size);
|
||||
void md_os_release (void* ptr, MD_U64 size);
|
||||
|
||||
//- rjf: large pages
|
||||
void* os_reserve_large( U64 size);
|
||||
B32 os_commit_large (void* ptr, U64 size);
|
||||
void* md_os_reserve_large( MD_U64 size);
|
||||
MD_B32 md_os_commit_large (void* ptr, MD_U64 size);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Thread Info (Implemented Per-OS)
|
||||
//~ rjf: @md_os_hooks Thread Info (Implemented Per-OS)
|
||||
|
||||
U32 os_tid(void);
|
||||
MD_U32 md_os_tid(void);
|
||||
|
||||
MD_API void os_set_thread_name(String8 string);
|
||||
MD_API void md_os_set_thread_name(MD_String8 string);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Aborting (Implemented Per-OS)
|
||||
//~ rjf: @md_os_hooks Aborting (Implemented Per-OS)
|
||||
|
||||
MD_API void os_abort(S32 exit_code);
|
||||
MD_API void md_os_abort(MD_S32 exit_code);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Shared Memory (Implemented Per-OS)
|
||||
//~ rjf: @md_os_hooks Shared Memory (Implemented Per-OS)
|
||||
|
||||
MD_API OS_Handle os_shared_memory_alloc (U64 size, String8 name);
|
||||
MD_API OS_Handle os_shared_memory_open (String8 name);
|
||||
MD_API void os_shared_memory_close (OS_Handle handle);
|
||||
MD_API void* os_shared_memory_view_open (OS_Handle handle, Rng1U64 range);
|
||||
MD_API void os_shared_memory_view_close(OS_Handle handle, void* ptr, Rng1U64 range);
|
||||
MD_API MD_OS_Handle md_os_shared_memory_alloc (MD_U64 size, MD_String8 name);
|
||||
MD_API MD_OS_Handle md_os_shared_memory_open (MD_String8 name);
|
||||
MD_API void md_os_shared_memory_close (MD_OS_Handle handle);
|
||||
MD_API void* md_os_shared_memory_view_open (MD_OS_Handle handle, MD_Rng1U64 range);
|
||||
MD_API void md_os_shared_memory_view_close(MD_OS_Handle handle, void* ptr, MD_Rng1U64 range);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Time (Implemented Per-OS)
|
||||
//~ rjf: @md_os_hooks Time (Implemented Per-OS)
|
||||
|
||||
MD_API U64 os_now_microseconds (void);
|
||||
MD_API U32 os_now_unix (void);
|
||||
MD_API DateTime os_now_universal_time (void);
|
||||
MD_API DateTime os_universal_time_from_local(DateTime* local_time);
|
||||
MD_API DateTime os_local_time_from_universal(DateTime* universal_time);
|
||||
MD_API void os_sleep_milliseconds (U32 msec);
|
||||
MD_API MD_U64 md_os_now_microseconds (void);
|
||||
MD_API MD_U32 md_os_now_unix (void);
|
||||
MD_API MD_DateTime md_os_now_universal_time (void);
|
||||
MD_API MD_DateTime md_os_universal_time_from_local(MD_DateTime* local_time);
|
||||
MD_API MD_DateTime md_os_local_time_from_universal(MD_DateTime* universal_time);
|
||||
MD_API void md_os_sleep_milliseconds (MD_U32 msec);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Child Processes (Implemented Per-OS)
|
||||
//~ rjf: @md_os_hooks Child Processes (Implemented Per-OS)
|
||||
|
||||
MD_API OS_Handle os_process_launch(OS_ProcessLaunchParams* params);
|
||||
MD_API B32 os_process_join (OS_Handle handle, U64 endt_us);
|
||||
MD_API void os_process_detach(OS_Handle handle);
|
||||
MD_API MD_OS_Handle md_os_process_launch(MD_OS_ProcessLaunchParams* params);
|
||||
MD_API MD_B32 md_os_process_join (MD_OS_Handle handle, MD_U64 endt_us);
|
||||
MD_API void md_os_process_detach(MD_OS_Handle handle);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Threads (Implemented Per-OS)
|
||||
//~ rjf: @md_os_hooks Threads (Implemented Per-OS)
|
||||
|
||||
MD_API OS_Handle os_thread_launch(OS_ThreadFunctionType* func, void* ptr, void* params);
|
||||
MD_API B32 os_thread_join (OS_Handle handle, U64 endt_us);
|
||||
MD_API void os_thread_detach(OS_Handle handle);
|
||||
MD_API MD_OS_Handle md_os_thread_launch(MD_OS_ThreadFunctionType* func, void* ptr, void* params);
|
||||
MD_API MD_B32 md_os_thread_join (MD_OS_Handle handle, MD_U64 endt_us);
|
||||
MD_API void md_os_thread_detach(MD_OS_Handle handle);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Synchronization Primitives (Implemented Per-OS)
|
||||
//~ rjf: @md_os_hooks Synchronization Primitives (Implemented Per-OS)
|
||||
|
||||
//- rjf: recursive mutexes
|
||||
MD_API OS_Handle os_mutex_alloc (void);
|
||||
MD_API void os_mutex_release(OS_Handle mutex);
|
||||
MD_API void os_mutex_take (OS_Handle mutex);
|
||||
MD_API void os_mutex_drop (OS_Handle mutex);
|
||||
MD_API MD_OS_Handle md_os_mutex_alloc (void);
|
||||
MD_API void md_os_mutex_release(MD_OS_Handle mutex);
|
||||
MD_API void md_os_mutex_take (MD_OS_Handle mutex);
|
||||
MD_API void md_os_mutex_drop (MD_OS_Handle mutex);
|
||||
|
||||
//- rjf: reader/writer mutexes
|
||||
MD_API OS_Handle os_rw_mutex_alloc (void);
|
||||
MD_API void os_rw_mutex_release(OS_Handle rw_mutex);
|
||||
MD_API void os_rw_mutex_take_r (OS_Handle mutex);
|
||||
MD_API void os_rw_mutex_drop_r (OS_Handle mutex);
|
||||
MD_API void os_rw_mutex_take_w (OS_Handle mutex);
|
||||
MD_API void os_rw_mutex_drop_w (OS_Handle mutex);
|
||||
MD_API MD_OS_Handle md_os_rw_mutex_alloc (void);
|
||||
MD_API void md_os_rw_mutex_release(MD_OS_Handle rw_mutex);
|
||||
MD_API void md_os_rw_mutex_take_r (MD_OS_Handle mutex);
|
||||
MD_API void md_os_rw_mutex_drop_r (MD_OS_Handle mutex);
|
||||
MD_API void md_os_rw_mutex_take_w (MD_OS_Handle mutex);
|
||||
MD_API void md_os_rw_mutex_drop_w (MD_OS_Handle mutex);
|
||||
|
||||
//- rjf: condition variables
|
||||
MD_API OS_Handle os_condition_variable_alloc (void);
|
||||
MD_API void os_condition_variable_release(OS_Handle cv);
|
||||
MD_API MD_OS_Handle md_os_condition_variable_alloc (void);
|
||||
MD_API void md_os_condition_variable_release(MD_OS_Handle cv);
|
||||
// returns false on timeout, true on signal, (max_wait_ms = max_U64) -> no timeout
|
||||
MD_API B32 os_condition_variable_wait (OS_Handle cv, OS_Handle mutex, U64 endt_us);
|
||||
MD_API B32 os_condition_variable_wait_rw_r(OS_Handle cv, OS_Handle mutex_rw, U64 endt_us);
|
||||
MD_API B32 os_condition_variable_wait_rw_w(OS_Handle cv, OS_Handle mutex_rw, U64 endt_us);
|
||||
MD_API void os_condition_variable_signal (OS_Handle cv);
|
||||
MD_API void os_condition_variable_broadcast(OS_Handle cv);
|
||||
MD_API MD_B32 md_os_condition_variable_wait (MD_OS_Handle cv, MD_OS_Handle mutex, MD_U64 endt_us);
|
||||
MD_API MD_B32 md_os_condition_variable_wait_rw_r(MD_OS_Handle cv, MD_OS_Handle mutex_rw, MD_U64 endt_us);
|
||||
MD_API MD_B32 md_os_condition_variable_wait_rw_w(MD_OS_Handle cv, MD_OS_Handle mutex_rw, MD_U64 endt_us);
|
||||
MD_API void md_os_condition_variable_signal (MD_OS_Handle cv);
|
||||
MD_API void md_os_condition_variable_broadcast(MD_OS_Handle cv);
|
||||
|
||||
//- rjf: cross-process semaphores
|
||||
MD_API OS_Handle os_semaphore_alloc (U32 initial_count, U32 max_count, String8 name);
|
||||
MD_API void os_semaphore_release(OS_Handle semaphore);
|
||||
MD_API OS_Handle os_semaphore_open (String8 name);
|
||||
MD_API void os_semaphore_close (OS_Handle semaphore);
|
||||
MD_API B32 os_semaphore_take (OS_Handle semaphore, U64 endt_us);
|
||||
MD_API void os_semaphore_drop (OS_Handle semaphore);
|
||||
MD_API MD_OS_Handle md_os_semaphore_alloc (MD_U32 initial_count, MD_U32 max_count, MD_String8 name);
|
||||
MD_API void md_os_semaphore_release(MD_OS_Handle semaphore);
|
||||
MD_API MD_OS_Handle md_os_semaphore_open (MD_String8 name);
|
||||
MD_API void md_os_semaphore_close (MD_OS_Handle semaphore);
|
||||
MD_API MD_B32 md_os_semaphore_take (MD_OS_Handle semaphore, MD_U64 endt_us);
|
||||
MD_API void md_os_semaphore_drop (MD_OS_Handle semaphore);
|
||||
|
||||
//- rjf: scope macros
|
||||
#define os_mutex_scope(mutex) defer_loop( os_mutex_take (mutex), os_mutex_drop (mutex))
|
||||
#define os_mutex_scope_r(mutex) defer_loop( os_rw_mutex_take_r(mutex), os_rw_mutex_drop_r(mutex))
|
||||
#define os_mutex_scope_W(mutex) defer_loop( os_rw_mutex_take_w(mutex), os_rw_mutex_drop_w(mutex))
|
||||
#define os_mutex_scope_rw_promote(mutex) defer_loop((os_rw_mutex_drop_r(mutex), os_rw_mutex_take_w(mutex)), (os_rw_mutex_drop_w(mutex), os_rw_mutex_take_r(mutex)))
|
||||
#define md_os_mutex_scope(mutex) md_defer_loop( md_os_mutex_take (mutex), md_os_mutex_drop (mutex))
|
||||
#define md_os_mutex_scope_r(mutex) md_defer_loop( md_os_rw_mutex_take_r(mutex), md_os_rw_mutex_drop_r(mutex))
|
||||
#define md_os_mutex_scope_W(mutex) md_defer_loop( md_os_rw_mutex_take_w(mutex), md_os_rw_mutex_drop_w(mutex))
|
||||
#define md_os_mutex_scope_rw_promote(mutex) md_defer_loop((md_os_rw_mutex_drop_r(mutex), md_os_rw_mutex_take_w(mutex)), (md_os_rw_mutex_drop_w(mutex), md_os_rw_mutex_take_r(mutex)))
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Dynamically-Loaded Libraries (Implemented Per-OS)
|
||||
//~ rjf: @md_os_hooks Dynamically-Loaded Libraries (Implemented Per-OS)
|
||||
|
||||
MD_API OS_Handle os_library_open (String8 path);
|
||||
MD_API void os_library_close (OS_Handle lib);
|
||||
MD_API VoidProc* os_library_load_proc(OS_Handle lib, String8 name);
|
||||
MD_API MD_OS_Handle md_os_library_open (MD_String8 path);
|
||||
MD_API void md_os_library_close (MD_OS_Handle lib);
|
||||
MD_API MD_VoidProc* md_os_library_load_proc(MD_OS_Handle lib, MD_String8 name);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Safe Calls (Implemented Per-OS)
|
||||
//~ rjf: @md_os_hooks Safe Calls (Implemented Per-OS)
|
||||
|
||||
MD_API void os_safe_call(OS_ThreadFunctionType* func, OS_ThreadFunctionType* fail_handler, void* ptr);
|
||||
MD_API void md_os_safe_call(MD_OS_ThreadFunctionType* func, MD_OS_ThreadFunctionType* fail_handler, void* ptr);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks GUIDs (Implemented Per-OS)
|
||||
//~ rjf: @md_os_hooks GUIDs (Implemented Per-OS)
|
||||
|
||||
MD_API OS_Guid os_make_guid(void);
|
||||
MD_API MD_OS_Guid md_os_make_guid(void);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Entry Points (Implemented Per-OS)
|
||||
//~ rjf: @md_os_hooks Entry Points (Implemented Per-OS)
|
||||
|
||||
// NOTE(rjf): The implementation of `os_core` will define low-level entry
|
||||
// points if BUILD_ENTRY_DEFINING_UNIT is defined to 1. These will call
|
||||
// into the standard codebase program entry points, named "entry_point".
|
||||
// NOTE(rjf): The implementation of `md_os_core` will define low-level entry
|
||||
// points if MD_BUILD_ENTRY_DEFINING_UNIT is defined to 1. These will call
|
||||
// into the standard codebase program entry points, named "md_entry_point".
|
||||
|
||||
#if BUILD_ENTRY_DEFINING_UNIT
|
||||
void entry_point(CmdLine* cmdline);
|
||||
#if MD_BUILD_ENTRY_DEFINING_UNIT
|
||||
void md_entry_point(MD_CmdLine* cmdline);
|
||||
#endif
|
||||
|
||||
////////////////////////////////
|
||||
//~ Ed: Manual OS Bootstrap (Implemented Per-OS)
|
||||
|
||||
typedef struct OS_Context OS_Context;
|
||||
struct OS_Context
|
||||
typedef struct MD_OS_Context MD_OS_Context;
|
||||
struct MD_OS_Context
|
||||
{
|
||||
Arena* state_arena;
|
||||
Arena* entity_arena;
|
||||
B32 enable_large_pages;
|
||||
MD_Arena* state_arena;
|
||||
MD_Arena* entity_arena;
|
||||
MD_B32 enable_large_pages;
|
||||
};
|
||||
|
||||
// OS layer initialization
|
||||
MD_API void os_init(OS_Context* ctx, TCTX* thread_ctx);
|
||||
MD_API void md_os_init(MD_OS_Context* ctx, MD_TCTX* thread_ctx);
|
||||
|
||||
+484
-488
File diff suppressed because it is too large
Load Diff
+70
-70
@@ -12,47 +12,47 @@
|
||||
////////////////////////////////
|
||||
//~ rjf: File Iterator Types
|
||||
|
||||
typedef struct OS_W32_FileIter OS_W32_FileIter;
|
||||
struct OS_W32_FileIter
|
||||
typedef struct MD_OS_W32_FileIter MD_OS_W32_FileIter;
|
||||
struct MD_OS_W32_FileIter
|
||||
{
|
||||
HANDLE handle;
|
||||
WIN32_FIND_DATAW find_data;
|
||||
B32 is_volume_iter;
|
||||
String8Array drive_strings;
|
||||
U64 drive_strings_iter_idx;
|
||||
MD_B32 is_volume_iter;
|
||||
MD_String8Array drive_strings;
|
||||
MD_U64 drive_strings_iter_idx;
|
||||
};
|
||||
md_static_assert(sizeof(member(OS_FileIter, memory)) >= sizeof(OS_W32_FileIter), file_iter_memory_size);
|
||||
md_static_assert(sizeof(md_member(MD_OS_FileIter, memory)) >= sizeof(MD_OS_W32_FileIter), file_iter_memory_size);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Entity Types
|
||||
|
||||
typedef enum OS_W32_EntityKind OS_W32_EntityKind;
|
||||
enum OS_W32_EntityKind
|
||||
typedef enum MD_OS_W32_EntityKind MD_OS_W32_EntityKind;
|
||||
enum MD_OS_W32_EntityKind
|
||||
{
|
||||
OS_W32_EntityKind_Null,
|
||||
OS_W32_EntityKind_Thread,
|
||||
OS_W32_EntityKind_Mutex,
|
||||
OS_W32_EntityKind_RWMutex,
|
||||
OS_W32_EntityKind_ConditionVariable,
|
||||
MD_OS_W32_EntityKind_Null,
|
||||
MD_OS_W32_EntityKind_Thread,
|
||||
MD_OS_W32_EntityKind_Mutex,
|
||||
MD_OS_W32_EntityKind_RWMutex,
|
||||
MD_OS_W32_EntityKind_ConditionVariable,
|
||||
};
|
||||
|
||||
typedef struct OS_W32_EntityThread OS_W32_EntityThread;
|
||||
struct OS_W32_EntityThread
|
||||
typedef struct MD_OS_W32_EntityThread MD_OS_W32_EntityThread;
|
||||
struct MD_OS_W32_EntityThread
|
||||
{
|
||||
OS_ThreadFunctionType* func;
|
||||
MD_OS_ThreadFunctionType* func;
|
||||
void* ptr;
|
||||
HANDLE handle;
|
||||
DWORD tid;
|
||||
};
|
||||
|
||||
typedef struct OS_W32_Entity OS_W32_Entity;
|
||||
struct OS_W32_Entity
|
||||
typedef struct MD_OS_W32_Entity MD_OS_W32_Entity;
|
||||
struct MD_OS_W32_Entity
|
||||
{
|
||||
OS_W32_Entity* next;
|
||||
OS_W32_EntityKind kind;
|
||||
MD_OS_W32_Entity* next;
|
||||
MD_OS_W32_EntityKind kind;
|
||||
union
|
||||
{
|
||||
OS_W32_EntityThread thread;
|
||||
MD_OS_W32_EntityThread thread;
|
||||
CRITICAL_SECTION mutex;
|
||||
SRWLOCK rw_mutex;
|
||||
CONDITION_VARIABLE cv;
|
||||
@@ -62,38 +62,38 @@ struct OS_W32_Entity
|
||||
////////////////////////////////
|
||||
//~ rjf: State
|
||||
|
||||
typedef struct OS_W32_State OS_W32_State;
|
||||
struct OS_W32_State
|
||||
typedef struct MD_OS_W32_State MD_OS_W32_State;
|
||||
struct MD_OS_W32_State
|
||||
{
|
||||
Arena* arena;
|
||||
MD_Arena* arena;
|
||||
|
||||
// rjf: info
|
||||
OS_SystemInfo system_info;
|
||||
OS_ProcessInfo process_info;
|
||||
U64 microsecond_resolution;
|
||||
MD_OS_SystemInfo system_info;
|
||||
MD_OS_ProcessInfo process_info;
|
||||
MD_U64 microsecond_resolution;
|
||||
|
||||
// rjf: entity storage
|
||||
CRITICAL_SECTION entity_mutex;
|
||||
Arena* entity_arena;
|
||||
OS_W32_Entity* entity_free;
|
||||
MD_Arena* entity_arena;
|
||||
MD_OS_W32_Entity* entity_free;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Globals
|
||||
|
||||
MD_API extern OS_W32_State os_w32_state;
|
||||
MD_API extern MD_OS_W32_State md_os_w32_state;
|
||||
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Time Conversion Helpers
|
||||
|
||||
void os_w32_date_time_from_system_time(DateTime* out, SYSTEMTIME* in);
|
||||
void os_w32_system_time_from_date_time(SYSTEMTIME* out, DateTime* in);
|
||||
void os_w32_dense_time_from_file_time (DenseTime* out, FILETIME* in);
|
||||
MD_API U32 os_w32_sleep_ms_from_endt_us(U64 endt_us);
|
||||
void md_os_w32_date_time_from_system_time(MD_DateTime* out, SYSTEMTIME* in);
|
||||
void md_os_w32_system_time_from_date_time(SYSTEMTIME* out, MD_DateTime* in);
|
||||
void md_os_w32_dense_time_from_file_time (MD_DenseTime* out, FILETIME* in);
|
||||
MD_API MD_U32 md_os_w32_sleep_ms_from_endt_us(MD_U64 endt_us);
|
||||
|
||||
inline void
|
||||
os_w32_date_time_from_system_time(DateTime* out, SYSTEMTIME* in)
|
||||
md_os_w32_date_time_from_system_time(MD_DateTime* out, SYSTEMTIME* in)
|
||||
{
|
||||
out->year = in->wYear;
|
||||
out->mon = in->wMonth - 1;
|
||||
@@ -101,93 +101,93 @@ os_w32_date_time_from_system_time(DateTime* out, SYSTEMTIME* in)
|
||||
out->day = in->wDay;
|
||||
|
||||
out->hour = in->wHour;
|
||||
out->min = in->wMinute;
|
||||
out->md_min = in->wMinute;
|
||||
out->sec = in->wSecond;
|
||||
out->msec = in->wMilliseconds;
|
||||
}
|
||||
|
||||
inline void
|
||||
os_w32_system_time_from_date_time(SYSTEMTIME* out, DateTime* in)
|
||||
md_os_w32_system_time_from_date_time(SYSTEMTIME* out, MD_DateTime* in)
|
||||
{
|
||||
out->wYear = (WORD)(in->year);
|
||||
out->wMonth = in->mon + 1;
|
||||
out->wDay = in->day;
|
||||
|
||||
out->wHour = in->hour;
|
||||
out->wMinute = in->min;
|
||||
out->wMinute = in->md_min;
|
||||
out->wSecond = in->sec;
|
||||
out->wMilliseconds = in->msec;
|
||||
}
|
||||
|
||||
inline void
|
||||
os_w32_dense_time_from_file_time(DenseTime* out, FILETIME* in) {
|
||||
md_os_w32_dense_time_from_file_time(MD_DenseTime* out, FILETIME* in) {
|
||||
SYSTEMTIME systime = {0};
|
||||
DateTime date_time = {0};
|
||||
MD_DateTime date_time = {0};
|
||||
FileTimeToSystemTime(in, &systime);
|
||||
os_w32_date_time_from_system_time(&date_time, &systime);
|
||||
*out = dense_time_from_date_time(date_time);
|
||||
md_os_w32_date_time_from_system_time(&date_time, &systime);
|
||||
*out = md_dense_time_from_date_time(date_time);
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: File Info Conversion Helpers
|
||||
|
||||
inline FilePropertyFlags
|
||||
os_w32_file_property_flags_from_dwFileAttributes(DWORD dwFileAttributes)
|
||||
inline MD_FilePropertyFlags
|
||||
md_os_w32_file_property_flags_from_dwFileAttributes(DWORD dwFileAttributes)
|
||||
{
|
||||
FilePropertyFlags flags = 0;
|
||||
MD_FilePropertyFlags flags = 0;
|
||||
if (dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
|
||||
flags |= FilePropertyFlag_IsFolder;
|
||||
flags |= MD_FilePropertyFlag_IsFolder;
|
||||
}
|
||||
return flags;
|
||||
}
|
||||
|
||||
inline void
|
||||
os_w32_file_properties_from_attribute_data(FileProperties* properties, WIN32_FILE_ATTRIBUTE_DATA* attributes) {
|
||||
properties->size = compose_64bit(attributes->nFileSizeHigh, attributes->nFileSizeLow);
|
||||
os_w32_dense_time_from_file_time(&properties->created, &attributes->ftCreationTime);
|
||||
os_w32_dense_time_from_file_time(&properties->modified, &attributes->ftLastWriteTime);
|
||||
properties->flags = os_w32_file_property_flags_from_dwFileAttributes(attributes->dwFileAttributes);
|
||||
md_os_w32_file_properties_from_attribute_data(MD_FileProperties* properties, WIN32_FILE_ATTRIBUTE_DATA* attributes) {
|
||||
properties->size = md_compose_64bit(attributes->nFileSizeHigh, attributes->nFileSizeLow);
|
||||
md_os_w32_dense_time_from_file_time(&properties->created, &attributes->ftCreationTime);
|
||||
md_os_w32_dense_time_from_file_time(&properties->modified, &attributes->ftLastWriteTime);
|
||||
properties->flags = md_os_w32_file_property_flags_from_dwFileAttributes(attributes->dwFileAttributes);
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Entity Functions
|
||||
|
||||
MD_API OS_W32_Entity* os_w32_entity_alloc (OS_W32_EntityKind kind);
|
||||
MD_API void os_w32_entity_release(OS_W32_Entity* entity);
|
||||
MD_API MD_OS_W32_Entity* md_os_w32_entity_alloc (MD_OS_W32_EntityKind kind);
|
||||
MD_API void md_os_w32_entity_release(MD_OS_W32_Entity* entity);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Thread Entry Point
|
||||
|
||||
MD_API DWORD os_w32_thread_entry_point(void* ptr);
|
||||
MD_API DWORD md_os_w32_thread_entry_point(void* ptr);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks System/Process Info (Implemented Per-OS)
|
||||
//~ rjf: @md_os_hooks System/Process Info (Implemented Per-OS)
|
||||
|
||||
inline String8
|
||||
os_get_current_path__ainfo(AllocatorInfo ainfo) {
|
||||
String8 name;
|
||||
TempArena scratch = scratch_begin(ainfo);
|
||||
inline MD_String8
|
||||
md_os_get_current_path__ainfo(MD_AllocatorInfo ainfo) {
|
||||
MD_String8 name;
|
||||
MD_TempArena scratch = md_scratch_begin(ainfo);
|
||||
{
|
||||
DWORD length = GetCurrentDirectoryW(0, 0);
|
||||
U16* memory = push_array_no_zero(scratch.arena, U16, length + 1);
|
||||
MD_U16* memory = md_push_array__no_zero(scratch.arena, MD_U16, length + 1);
|
||||
length = GetCurrentDirectoryW(length + 1, (WCHAR*)memory);
|
||||
name = str8_from(ainfo, str16(memory, length));
|
||||
name = md_str8_from(ainfo, md_str16(memory, length));
|
||||
}
|
||||
scratch_end(scratch);
|
||||
return name;
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Memory Allocation (Implemented Per-OS)
|
||||
//~ rjf: @md_os_hooks Memory Allocation (Implemented Per-OS)
|
||||
|
||||
//- rjf: basic
|
||||
|
||||
inline void* os_reserve ( U64 size) { void* result = VirtualAlloc( 0, size, MEM_RESERVE, PAGE_READWRITE); return result; }
|
||||
inline B32 os_commit (void* ptr, U64 size) { B32 result = (VirtualAlloc(ptr, size, MEM_COMMIT, PAGE_READWRITE) != 0); return result; }
|
||||
inline void os_decommit(void* ptr, U64 size) { VirtualFree (ptr, size, MEM_DECOMMIT); }
|
||||
inline void* md_os_reserve ( MD_U64 size) { void* result = VirtualAlloc( 0, size, MEM_RESERVE, PAGE_READWRITE); return result; }
|
||||
inline MD_B32 md_os_commit (void* ptr, MD_U64 size) { MD_B32 result = (VirtualAlloc(ptr, size, MEM_COMMIT, PAGE_READWRITE) != 0); return result; }
|
||||
inline void md_os_decommit(void* ptr, MD_U64 size) { VirtualFree (ptr, size, MEM_DECOMMIT); }
|
||||
|
||||
inline void
|
||||
os_release(void* ptr, U64 size) {
|
||||
md_os_release(void* ptr, MD_U64 size) {
|
||||
// NOTE(rjf): size not used - not necessary on Windows, but necessary for other OSes.
|
||||
VirtualFree(ptr, 0, MEM_RELEASE);
|
||||
}
|
||||
@@ -195,15 +195,15 @@ os_release(void* ptr, U64 size) {
|
||||
//- rjf: large pages
|
||||
|
||||
inline void*
|
||||
os_reserve_large(U64 size) {
|
||||
md_os_reserve_large(MD_U64 size) {
|
||||
// we commit on reserve because windows
|
||||
void* result = VirtualAlloc(0, size, MEM_RESERVE|MEM_COMMIT|MEM_LARGE_PAGES, PAGE_READWRITE);
|
||||
return result;
|
||||
}
|
||||
|
||||
inline B32 os_commit_large(void* ptr, U64 size) { return 1; }
|
||||
inline MD_B32 md_os_commit_large(void* ptr, MD_U64 size) { return 1; }
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Thread Info (Implemented Per-OS)
|
||||
//~ rjf: @md_os_hooks Thread Info (Implemented Per-OS)
|
||||
|
||||
inline U32 os_tid(void) { DWORD id = GetCurrentThreadId(); return (U32)id; }
|
||||
inline MD_U32 md_os_tid(void) { DWORD id = GetCurrentThreadId(); return (MD_U32)id; }
|
||||
|
||||
Vendored
+19
-19
@@ -666,9 +666,9 @@ STBSP__PUBLICDEF int STB_SPRINTF_DECORATE(vsprintfcb)(STBSP_SPRINTFCB *callback,
|
||||
//
|
||||
case 'S':
|
||||
{
|
||||
String8 string = va_arg(va, String8);
|
||||
MD_String8 string = va_arg(va, MD_String8);
|
||||
s = (char *)string.str;
|
||||
l = (U32)string.size;
|
||||
l = (MD_U32)string.size;
|
||||
lead[0] = 0;
|
||||
tail[0] = 0;
|
||||
pr = 0;
|
||||
@@ -680,21 +680,21 @@ STBSP__PUBLICDEF int STB_SPRINTF_DECORATE(vsprintfcb)(STBSP_SPRINTFCB *callback,
|
||||
case 'm':
|
||||
case 'M':
|
||||
{
|
||||
static const U64 one_kib = 1ull * 1024;
|
||||
static const U64 one_mib = 1ull * 1024 * 1024;
|
||||
static const U64 one_gib = 1ull * 1024 * 1024 * 1024;
|
||||
static const U64 one_tib = 1ull * 1024 * 1024 * 1024 * 1024;
|
||||
static const MD_U64 one_kib = 1ull * 1024;
|
||||
static const MD_U64 one_mib = 1ull * 1024 * 1024;
|
||||
static const MD_U64 one_gib = 1ull * 1024 * 1024 * 1024;
|
||||
static const MD_U64 one_tib = 1ull * 1024 * 1024 * 1024 * 1024;
|
||||
|
||||
U64 size;
|
||||
MD_U64 size;
|
||||
if (f[0] == 'M') {
|
||||
size = va_arg(va, U64);
|
||||
size = va_arg(va, MD_U64);
|
||||
}
|
||||
else {
|
||||
size = va_arg(va, U32);
|
||||
size = va_arg(va, MD_U32);
|
||||
}
|
||||
|
||||
U64 lo = 0;
|
||||
U64 hi = 0;
|
||||
MD_U64 lo = 0;
|
||||
MD_U64 hi = 0;
|
||||
char* units = "";
|
||||
|
||||
if (size < one_kib) {
|
||||
@@ -718,7 +718,7 @@ STBSP__PUBLICDEF int STB_SPRINTF_DECORATE(vsprintfcb)(STBSP_SPRINTFCB *callback,
|
||||
units = "GiB";
|
||||
}
|
||||
else {
|
||||
assert(size <= MAX_U64 / 100ull);
|
||||
md_assert(size <= MD_MAX_U64 / 100ull);
|
||||
hi = size / one_tib;
|
||||
lo = ((size * 100) / one_tib) % 100;
|
||||
units = "TiB";
|
||||
@@ -728,12 +728,12 @@ STBSP__PUBLICDEF int STB_SPRINTF_DECORATE(vsprintfcb)(STBSP_SPRINTFCB *callback,
|
||||
if (hi > 0)
|
||||
{
|
||||
s = num;
|
||||
for (U64 n = hi; n > 0; n /= 10ull)
|
||||
for (MD_U64 n = hi; n > 0; n /= 10ull)
|
||||
{
|
||||
*s = (char)(n % 10ull) + '0';
|
||||
++s;
|
||||
}
|
||||
for (S64 i = (S64)(s-num)-1; i >= 0; --i)
|
||||
for (MD_S64 i = (MD_S64)(s-num)-1; i >= 0; --i)
|
||||
{
|
||||
*bf = num[i];
|
||||
++ bf;
|
||||
@@ -752,18 +752,18 @@ STBSP__PUBLICDEF int STB_SPRINTF_DECORATE(vsprintfcb)(STBSP_SPRINTFCB *callback,
|
||||
++ bf;
|
||||
|
||||
s = num;
|
||||
for (U64 n = lo; n > 0; n /= 10ull) {
|
||||
for (MD_U64 n = lo; n > 0; n /= 10ull) {
|
||||
*s = (char)(n % 10ull) + '0';
|
||||
++ s;
|
||||
}
|
||||
|
||||
U64 lead_zero_count = 3 - (U64)(s-num);
|
||||
for (U64 i = 1; i < lead_zero_count; ++i) {
|
||||
MD_U64 lead_zero_count = 3 - (MD_U64)(s-num);
|
||||
for (MD_U64 i = 1; i < lead_zero_count; ++i) {
|
||||
*bf = '0';
|
||||
++ bf;
|
||||
}
|
||||
|
||||
for (S64 i = (S64)(s-num)-1; i >= 0; --i) {
|
||||
for (MD_S64 i = (MD_S64)(s-num)-1; i >= 0; --i) {
|
||||
*bf = num[i];
|
||||
++ bf;
|
||||
}
|
||||
@@ -773,7 +773,7 @@ STBSP__PUBLICDEF int STB_SPRINTF_DECORATE(vsprintfcb)(STBSP_SPRINTFCB *callback,
|
||||
++ bf;
|
||||
|
||||
// copy units
|
||||
for(U64 i = 0; units[i] != 0; ++i) {
|
||||
for(MD_U64 i = 0; units[i] != 0; ++i) {
|
||||
*bf = units[i];
|
||||
++ bf;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user