adding prefixes to source

They'll be removed on demand in libgen repo
This commit is contained in:
2025-02-12 14:38:18 -05:00
parent aa5c1efb36
commit 0ab226f739
45 changed files with 5811 additions and 5820 deletions
+79 -79
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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();
}
+4 -4
View File
@@ -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
View File
@@ -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;
};
+63 -65
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
+3 -3
View File
@@ -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);
}
+7 -7
View File
@@ -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
View File
File diff suppressed because it is too large Load Diff
+357 -357
View File
File diff suppressed because it is too large Load Diff
+163 -163
View File
@@ -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
View File
@@ -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 );
}
+2 -2
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
File diff suppressed because it is too large Load Diff
+687 -687
View File
File diff suppressed because it is too large Load Diff
+19 -19
View File
@@ -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
View File
@@ -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;
}
+35 -35
View File
@@ -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;
}
}
+48 -48
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
File diff suppressed because it is too large Load Diff
+308 -308
View File
@@ -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
View File
File diff suppressed because it is too large Load Diff
+74 -74
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
File diff suppressed because it is too large Load Diff
+70 -70
View File
@@ -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; }
+19 -19
View File
@@ -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;
}