adding prefixes to source

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