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/)
////////////////////////////////
//~ rjf: Arena Functions
//~ rjf: MD_Arena Functions
//- rjf: arena creation/destruction
Arena*
arena__alloc(ArenaParams* optional_params)
MD_Arena*
md_arena__alloc(MD_ArenaParams* optional_params)
{
ArenaParams params = optional_params ? *optional_params : (ArenaParams){0};
MD_ArenaParams params = optional_params ? *optional_params : (MD_ArenaParams){0};
SPTR const varena_header_size = align_pow2(size_of(VArena), MD_DEFAULT_MEMORY_ALIGNMENT);
SPTR const header_size = align_pow2(size_of(Arena), MD_DEFAULT_MEMORY_ALIGNMENT);
MD_SPTR const varena_header_size = md_align_pow2(size_of(MD_VArena), MD_DEFAULT_MEMORY_ALIGNMENT);
MD_SPTR const header_size = md_align_pow2(size_of(MD_Arena), MD_DEFAULT_MEMORY_ALIGNMENT);
U64 const varena_reserve_size = VARENA_DEFAULT_RESERVE;
MD_U64 const varena_reserve_size = MD_VARENA_DEFAULT_RESERVE;
B32 is_virtual = allocator_type(params.backing) & AllocatorType_VArena;
params.flags |= ArenaFlag_Virtual * is_virtual;
MD_B32 is_virtual = md_allocator_type(params.backing) & MD_AllocatorType_VArena;
params.flags |= MD_ArenaFlag_Virtual * is_virtual;
if (params.backing.proc == nullptr) params.backing = default_allocator();
if (params.block_size == 0 ) params.block_size = ARENA_DEFAULT_BLOCK_SIZE;
if (params.backing.proc == md_nullptr) params.backing = md_default_allocator();
if (params.block_size == 0 ) params.block_size = MD_ARENA_DEFAULT_BLOCK_SIZE;
SSIZE alloc_size = is_virtual ? header_size : params.block_size;
MD_SSIZE md_alloc_size = is_virtual ? header_size : params.block_size;
void* base = alloc(params.backing, alloc_size);
void* base = md_alloc(params.backing, md_alloc_size);
// rjf: extract arena header & fill
Arena* arena = (Arena*) base;
arena->prev = nullptr;
MD_Arena* arena = (MD_Arena*) base;
arena->prev = md_nullptr;
arena->current = arena;
arena->backing = params.backing;
arena->base_pos = 0;
arena->pos = header_size;
arena->block_size = params.block_size;
arena->flags = params.flags;
asan_unpoison_memory_region(base, sizeof(Arena));
md_asan_unpoison_memory_region(base, sizeof(MD_Arena));
return arena;
}
//- rjf: arena push/pop core functions
void*
arena_push(Arena* arena, SSIZE size, SSIZE align)
md_arena_push(MD_Arena* arena, MD_SSIZE size, MD_SSIZE align)
{
SPTR const header_size = align_pow2(size_of(Arena), MD_DEFAULT_MEMORY_ALIGNMENT);
MD_SPTR const header_size = md_align_pow2(size_of(MD_Arena), MD_DEFAULT_MEMORY_ALIGNMENT);
Arena* current = arena->current;
SPTR curr_sptr = scast(SPTR, current);
MD_Arena* current = arena->current;
MD_SPTR curr_sptr = md_scast(MD_SPTR, current);
SSIZE aligned_size = align_pow2(size, align);
MD_SSIZE aligned_size = md_align_pow2(size, align);
SPTR pos_pre = current->pos;
SPTR pos_pst = pos_pre + aligned_size;
MD_SPTR pos_pre = current->pos;
MD_SPTR pos_pst = pos_pre + aligned_size;
B32 is_virtual = arena->flags & ArenaFlag_Virtual;
MD_B32 is_virtual = arena->flags & MD_ArenaFlag_Virtual;
// rjf: chain, if needed
if ( current->block_size < pos_pst && ! (arena->flags & ArenaFlag_NoChain) )
if ( current->block_size < pos_pst && ! (arena->flags & MD_ArenaFlag_NoChain) )
{
Arena* new_block = nullptr;
MD_Arena* new_block = md_nullptr;
B32 vmem_chain = is_virtual && (arena->flags & ArenaFlag_NoChainVirtual);
MD_B32 vmem_chain = is_virtual && (arena->flags & MD_ArenaFlag_NoChainVirtual);
if (vmem_chain) {
SPTR const varena_header_size = align_pow2(size_of(VArena), MD_DEFAULT_MEMORY_ALIGNMENT);
SPTR const arena_block_size = VARENA_DEFAULT_RESERVE - varena_header_size;
MD_SPTR const varena_header_size = md_align_pow2(size_of(MD_VArena), MD_DEFAULT_MEMORY_ALIGNMENT);
MD_SPTR const md_arena_block_size = MD_VARENA_DEFAULT_RESERVE - varena_header_size;
VArena* vcurrent = rcast(VArena*, arena->backing.data);
MD_VArena* vcurrent = md_rcast(MD_VArena*, arena->backing.data);
VArena* new_vm = varena_alloc(.reserve_size = vcurrent->reserve, .commit_size = vcurrent->commit_size);
new_block = arena_alloc(.backing = varena_allocator(new_vm), .block_size = arena_block_size);
MD_VArena* new_vm = md_varena_alloc(.reserve_size = vcurrent->reserve, .commit_size = vcurrent->commit_size);
new_block = md_arena_alloc(.backing = md_varena_allocator(new_vm), .block_size = md_arena_block_size);
}
else {
SPTR const arena_block_size = arena->block_size + header_size;
new_block = arena_alloc(.backing = arena->backing, .block_size = arena_block_size);
MD_SPTR const md_arena_block_size = arena->block_size + header_size;
new_block = md_arena_alloc(.backing = arena->backing, .block_size = md_arena_block_size);
}
new_block->base_pos = current->base_pos + current->block_size;
sll_stack_push_n(arena->current, new_block, prev);
md_sll_stack_push_n(arena->current, new_block, prev);
current = new_block;
pos_pre = current->pos;
@@ -92,23 +92,23 @@ arena_push(Arena* arena, SSIZE size, SSIZE align)
// rjf: push onto current block
void* result = 0;
{
result = scast(void*, curr_sptr + pos_pre);
result = md_scast(void*, curr_sptr + pos_pre);
current->pos = pos_pst;
asan_unpoison_memory_region(result, size);
md_asan_unpoison_memory_region(result, size);
}
if (is_virtual) {
// Sync virtual arena
void* vresult = alloc_align(arena->backing, size, align);
assert(vresult == result);
void* vresult = md_alloc_align(arena->backing, size, align);
md_assert(vresult == result);
}
// rjf: panic on failure
#if OS_FEATURE_GRAPHICAL
if(unlikely(result == 0))
#if MD_OS_FEATURE_GRAPHICAL
if(md_unlikely(result == 0))
{
os_graphical_message(1, str8_lit("Fatal Allocation Failure"), str8_lit("Unexpected memory allocation failure."));
os_abort(1);
md_os_graphical_message(1, md_str8_lit("Fatal Allocation Failure"), md_str8_lit("Unexpected memory allocation failure."));
md_os_abort(1);
}
#endif
@@ -116,77 +116,77 @@ arena_push(Arena* arena, SSIZE size, SSIZE align)
}
void
arena_pop_to(Arena *arena, SSIZE pos)
md_arena_pop_to(MD_Arena *arena, MD_SSIZE pos)
{
SPTR const header_size = align_pow2(size_of(Arena), MD_DEFAULT_MEMORY_ALIGNMENT);
MD_SPTR const header_size = md_align_pow2(size_of(MD_Arena), MD_DEFAULT_MEMORY_ALIGNMENT);
Arena* current = arena->current;
AllocatorInfo backing = current->backing;
B32 is_virtual = allocator_type(backing) & AllocatorType_VArena;
MD_Arena* current = arena->current;
MD_AllocatorInfo backing = current->backing;
MD_B32 is_virtual = md_allocator_type(backing) & MD_AllocatorType_VArena;
SSIZE big_pos = clamp_bot(header_size, pos);
MD_SSIZE big_pos = md_clamp_bot(header_size, pos);
// If base position is larger than the position to pop to:
// We are in a previous arena and msut free the current
for(Arena* prev = 0; current->base_pos >= big_pos; current = prev)
for(MD_Arena* prev = 0; current->base_pos >= big_pos; current = prev)
{
prev = current->prev;
if (is_virtual) {
varena_release(rcast(VArena*, current->backing.data));
md_varena_release(md_rcast(MD_VArena*, current->backing.data));
}
else if (allocator_query_support(backing) & AllocatorQuery_Free) {
alloc_free(current->backing, current);
else if (md_allocator_query_support(backing) & MD_AllocatorQuery_Free) {
md_alloc_free(current->backing, current);
}
}
arena->current = current;
SSIZE new_pos = big_pos - current->base_pos;
assert_always(new_pos <= current->pos);
asan_poison_memory_region((U8*)current + new_pos, (current->pos - new_pos));
MD_SSIZE new_pos = big_pos - current->base_pos;
md_assert_always(new_pos <= current->pos);
md_asan_poison_memory_region((MD_U8*)current + new_pos, (current->pos - new_pos));
current->pos = new_pos;
if (is_virtual) {
varena_rewind(rcast(VArena*, current->backing.data), current->pos);
varena_rewind(md_rcast(MD_VArena*, current->backing.data), current->pos);
}
}
void* arena_allocator_proc(void* allocator_data, AllocatorMode mode, SSIZE size, SSIZE alignment, void* old_memory, SSIZE old_size, U64 flags)
void* md_arena_allocator_proc(void* allocator_data, MD_AllocatorMode mode, MD_SSIZE size, MD_SSIZE alignment, void* old_memory, MD_SSIZE old_size, MD_U64 flags)
{
Arena* arena = rcast(Arena*, allocator_data);
MD_Arena* arena = md_rcast(MD_Arena*, allocator_data);
void* allocated_ptr = nullptr;
void* allocated_ptr = md_nullptr;
switch (mode)
{
case AllocatorMode_Alloc:
case MD_AllocatorMode_Alloc:
{
allocated_ptr = arena_push(arena, size, alignment);
allocated_ptr = md_arena_push(arena, size, alignment);
}
break;
case AllocatorMode_Free:
case MD_AllocatorMode_Free:
{
}
break;
case AllocatorMode_FreeAll:
case MD_AllocatorMode_FreeAll:
{
arena_release(arena);
md_arena_release(arena);
}
break;
case AllocatorMode_Resize:
case MD_AllocatorMode_Resize:
{
assert(old_memory != nullptr);
assert(old_size > 0);
assert_msg(old_size == size, "Requested resize when none needed");
md_assert(old_memory != md_nullptr);
md_assert(old_size > 0);
md_assert_msg(old_size == size, "Requested md_resize when none needed");
size = align_pow2(size, alignment);
old_size = align_pow2(size, alignment);
size = md_align_pow2(size, alignment);
old_size = md_align_pow2(size, alignment);
SPTR old_memory_offset = scast(SPTR, old_memory) + old_size;
SPTR current_offset = arena->pos;
MD_SPTR old_memory_offset = md_scast(MD_SPTR, old_memory) + old_size;
MD_SPTR current_offset = arena->pos;
assert_msg(old_memory_offset == current_offset, "Cannot resize existing allocation in VArena unless it was the last allocated");
md_assert_msg(old_memory_offset == current_offset, "Cannot md_resize existing allocation in MD_VArena unless it was the last allocated");
B32 requested_shrink = size >= old_size;
MD_B32 requested_shrink = size >= old_size;
if (requested_shrink) {
arena->pos -= size;
allocated_ptr = old_memory;
@@ -198,15 +198,15 @@ void* arena_allocator_proc(void* allocator_data, AllocatorMode mode, SSIZE size,
}
break;
case AllocatorMode_QueryType:
case MD_AllocatorMode_QueryType:
{
return (void*) AllocatorType_Arena;
return (void*) MD_AllocatorType_Arena;
}
break;
case AllocatorMode_QuerySupport:
case MD_AllocatorMode_QuerySupport:
{
return (void*) (AllocatorQuery_Alloc | AllocatorQuery_Resize | AllocatorQuery_FreeAll);
return (void*) (MD_AllocatorQuery_Alloc | MD_AllocatorQuery_Resize | MD_AllocatorQuery_FreeAll);
}
break;
}
+79 -79
View File
@@ -11,27 +11,27 @@
////////////////////////////////
//~ rjf: Types
typedef U32 ArenaFlags;
typedef MD_U32 MD_ArenaFlags;
enum
{
// Don't chain this arena
ArenaFlag_NoChain = (1 << 0),
// Only relevant if backing is virtual memory, will prevent allocating a new backing VArena when the current block exhausts
// Will assume backing can chain multiple block_size arenas however. If there is an allocation failure it will assert.
ArenaFlag_NoChainVirtual = (1 << 1),
// Backing allocator identified as VArena during initialization
ArenaFlag_Virtual = (1 << 2),
MD_ArenaFlag_NoChain = (1 << 0),
// Only relevant if backing is virtual memory, will prevent allocating a new backing MD_VArena when the current block exhausts
// Will assume backing can chain multiple block_size arenas however. If there is an allocation failure it will md_assert.
MD_ArenaFlag_NoChainVirtual = (1 << 1),
// Backing allocator identified as MD_VArena during initialization
MD_ArenaFlag_Virtual = (1 << 2),
};
typedef struct ArenaParams ArenaParams;
struct ArenaParams
typedef struct MD_ArenaParams MD_ArenaParams;
struct MD_ArenaParams
{
AllocatorInfo backing;
ArenaFlags flags;
U64 block_size; // If chaining VArenas set this to the reserve size
MD_AllocatorInfo backing;
MD_ArenaFlags flags;
MD_U64 block_size; // If chaining VArenas set this to the reserve size
};
#define ARENA_DEFAULT_BLOCK_SIZE VARENA_DEFAULT_RESERVE - align_pow2(size_of(VArena), MD_DEFAULT_MEMORY_ALIGNMENT)
#define MD_ARENA_DEFAULT_BLOCK_SIZE MD_VARENA_DEFAULT_RESERVE - md_align_pow2(size_of(MD_VArena), MD_DEFAULT_MEMORY_ALIGNMENT)
/* NOTE(Ed): The original metadesk arena is a combination of several concepts into a single interface
* An OS virtual memory allocation scheme
@@ -40,136 +40,136 @@ struct ArenaParams
The virtual memory has been abstracted into a backing allocator,
and chaining still supports reserving new virtual address regions .
(can be disabled with ArenaFlag_NoChainVirtual)
(can be disabled with MD_ArenaFlag_NoChainVirtual)
If large pages are desired, see VArena.
If large pages are desired, see MD_VArena.
*/
typedef struct Arena Arena;
struct Arena
typedef struct MD_Arena MD_Arena;
struct MD_Arena
{
Arena* prev; // Previous arena in chain
Arena* current; // Current arena in chain
AllocatorInfo backing;
SSIZE base_pos; // Tracks how main arenas have been chained
SSIZE pos;
SSIZE block_size;
ArenaFlags flags;
MD_Arena* prev; // Previous arena in chain
MD_Arena* current; // Current arena in chain
MD_AllocatorInfo backing;
MD_SSIZE base_pos; // Tracks how main arenas have been chained
MD_SSIZE pos;
MD_SSIZE block_size;
MD_ArenaFlags flags;
};
// static_assert(size_of(Arena) <= ARENA_HEADER_SIZE, "sizeof(Arena) <= ARENA_HEADER_SIZE");
// static_assert(size_of(MD_Arena) <= ARENA_HEADER_SIZE, "sizeof(MD_Arena) <= ARENA_HEADER_SIZE");
typedef struct TempArena TempArena;
struct TempArena
typedef struct MD_TempArena MD_TempArena;
struct MD_TempArena
{
Arena* arena;
SSIZE pos;
MD_Arena* arena;
MD_SSIZE pos;
};
////////////////////////////////
//~ rjf: Arena Functions
//~ rjf: MD_Arena Functions
MD_API void* arena_allocator_proc(void* allocator_data, AllocatorMode mode, SSIZE size, SSIZE alignment, void* old_memory, SSIZE old_size, U64 flags);
MD_API void* md_arena_allocator_proc(void* allocator_data, MD_AllocatorMode mode, MD_SSIZE size, MD_SSIZE alignment, void* old_memory, MD_SSIZE old_size, MD_U64 flags);
force_inline AllocatorInfo arena_allocator(Arena* arena) { AllocatorInfo info = { arena_allocator_proc, arena}; return info; }
md_force_inline MD_AllocatorInfo md_arena_allocator(MD_Arena* arena) { MD_AllocatorInfo info = { md_arena_allocator_proc, arena}; return info; }
// Useful for providing an arena to scratch_begin_alloc
force_inline Arena*
extract_arena(AllocatorInfo ainfo) {
if (allocator_type(ainfo) == AllocatorType_Arena) {
return (Arena*) ainfo.data;
// Useful for providing an arena to md_scratch_begin_alloc
md_force_inline MD_Arena*
md_extract_arena(MD_AllocatorInfo ainfo) {
if (md_allocator_type(ainfo) == MD_AllocatorType_Arena) {
return (MD_Arena*) ainfo.data;
}
return nullptr;
return md_nullptr;
}
//- rjf: arena creation/destruction
MD_API Arena* arena__alloc(ArenaParams* params);
#define arena_alloc(...) arena__alloc( &(ArenaParams){ __VA_ARGS__ } )
MD_API MD_Arena* md_arena__alloc(MD_ArenaParams* params);
#define md_arena_alloc(...) md_arena__alloc( &(MD_ArenaParams){ __VA_ARGS__ } )
void arena_release(Arena *arena);
void md_arena_release(MD_Arena *arena);
//- rjf: arena push/pop/pos core functions
MD_API void* arena_push (Arena* arena, SSIZE size, SSIZE align);
U64 arena_pos (Arena* arena);
MD_API void arena_pop_to(Arena* arena, SSIZE pos);
MD_API void* md_arena_push (MD_Arena* arena, MD_SSIZE size, MD_SSIZE align);
MD_U64 md_arena_pos (MD_Arena* arena);
MD_API void md_arena_pop_to(MD_Arena* arena, MD_SSIZE pos);
//- rjf: arena push/pop helpers
void arena_clear(Arena* arena);
void arena_pop (Arena* arena, SSIZE amt);
void md_arena_clear(MD_Arena* arena);
void md_arena_pop (MD_Arena* arena, MD_SSIZE amt);
//- rjf: temporary arena scopes
TempArena temp_arena_begin(Arena* arena);
void temp_arena_end(TempArena temp);
MD_TempArena temp_arena_begin(MD_Arena* arena);
void temp_arena_end(MD_TempArena temp);
//- rjf: push helper macros
#ifndef push_array
#define push_array_no_zero_aligned(a, T, c, align) (T *)arena_push((a), sizeof(T) * (c), (align))
#define push_array_aligned(a, T, c, align) (T *)memory_zero(push_array_no_zero_aligned(a, T, c, align), sizeof(T) * (c))
#define push_array_no_zero(a, T, c) push_array_no_zero_aligned(a, T, c, max(8, align_of(T)))
#define push_array(a, T, c) push_array_aligned (a, T, c, max(8, align_of(T)))
#ifndef md_push_array_
#define md_push_array__no_zero_aligned(a, T, c, align) (T *)md_arena_push((a), sizeof(T) * (c), (align))
#define md_push_array__aligned(a, T, c, align) (T *)md_memory_zero(md_push_array__no_zero_aligned(a, T, c, align), sizeof(T) * (c))
#define md_push_array__no_zero(a, T, c) md_push_array__no_zero_aligned(a, T, c, md_max(8, md_align_of(T)))
#define md_push_array_(a, T, c) md_push_array__aligned (a, T, c, md_max(8, md_align_of(T)))
#endif
// Inlines
inline void
arena_release(Arena* arena) {
for (Arena* n = arena->current, *prev = 0; n != 0; n = prev) {
md_arena_release(MD_Arena* arena) {
for (MD_Arena* n = arena->current, *prev = 0; n != 0; n = prev) {
prev = n->prev;
alloc_free(arena->backing, n);
md_alloc_free(arena->backing, n);
}
}
inline U64
arena_pos(Arena *arena) {
Arena* current = arena->current;
U64 pos = current->base_pos + current->pos;
inline MD_U64
md_arena_pos(MD_Arena *arena) {
MD_Arena* current = arena->current;
MD_U64 pos = current->base_pos + current->pos;
return pos;
}
//- rjf: arena push/pop helpers
force_inline void arena_clear(Arena* arena) { arena_pop_to(arena, 0); }
md_force_inline void md_arena_clear(MD_Arena* arena) { md_arena_pop_to(arena, 0); }
inline void
arena_pop(Arena* arena, SSIZE amt) {
SSIZE pos_old = arena_pos(arena);
SSIZE pos_new = pos_old;
md_arena_pop(MD_Arena* arena, MD_SSIZE amt) {
MD_SSIZE pos_old = md_arena_pos(arena);
MD_SSIZE pos_new = pos_old;
if (amt < pos_old)
{
pos_new = pos_old - amt;
}
arena_pop_to(arena, pos_new);
md_arena_pop_to(arena, pos_new);
}
//- rjf: temporary arena scopes
inline TempArena
temp_begin(Arena* arena) {
U64 pos = arena_pos(arena);
TempArena temp = {arena, pos};
inline MD_TempArena
md_temp_begin(MD_Arena* arena) {
MD_U64 pos = md_arena_pos(arena);
MD_TempArena temp = {arena, pos};
return temp;
}
force_inline void temp_end(TempArena temp) { arena_pop_to(temp.arena, temp.pos); }
md_force_inline void md_temp_end(MD_TempArena temp) { md_arena_pop_to(temp.arena, temp.pos); }
// ======================================== DEFAULT_ALLOCATOR =====================================================
#ifndef MD_OVERRIDE_DEFAULT_ALLOCATOR
// The default allocator for this base module is the Arena allocator with a VArena backing
// NOTE(Ed): In order for this to work, either the os entry_point must have been utilized or os_init needs to be called.
inline AllocatorInfo
default_allocator()
// The default allocator for this base module is the MD_Arena allocator with a MD_VArena backing
// NOTE(Ed): In order for this to work, either the os md_entry_point must have been utilized or md_os_init needs to be called.
inline MD_AllocatorInfo
md_default_allocator()
{
local_persist thread_local Arena* arena = nullptr;
if (arena == nullptr) {
VArena* backing_vmem = varena_alloc(.flags = 0, .base_addr = 0x0, .reserve_size = VARENA_DEFAULT_RESERVE, .commit_size = VARENA_DEFAULT_COMMIT);
arena = arena_alloc(.backing = varena_allocator(backing_vmem), .block_size = VARENA_DEFAULT_RESERVE);
md_local_persist md_thread_local MD_Arena* arena = md_nullptr;
if (arena == md_nullptr) {
MD_VArena* backing_vmem = md_varena_alloc(.flags = 0, .base_addr = 0x0, .reserve_size = MD_VARENA_DEFAULT_RESERVE, .commit_size = MD_VARENA_DEFAULT_COMMIT);
arena = md_arena_alloc(.backing = md_varena_allocator(backing_vmem), .block_size = MD_VARENA_DEFAULT_RESERVE);
}
AllocatorInfo info = { arena_allocator_proc, arena };
MD_AllocatorInfo info = { md_arena_allocator_proc, arena };
return info;
}
#endif
+236 -236
View File
@@ -7,65 +7,65 @@
# include "platform.h"
#endif
#if defined( COMPILER_MSVC )
#if defined( MD_COMPILER_MSVC )
# if _MSC_VER < 1300
typedef unsigned char, U8;
typedef signed char, S8;
typedef unsigned short, U16;
typedef signed short, S16;
typedef unsigned int, U32;
typedef signed int, S32;
typedef unsigned char, MD_U8;
typedef signed char, MD_S8;
typedef unsigned short, MD_U16;
typedef signed short, MD_S16;
typedef unsigned int, MD_U32;
typedef signed int, MD_S32;
# else
typedef unsigned __int8 U8;
typedef signed __int8 S8;
typedef unsigned __int16 U16;
typedef signed __int16 S16;
typedef unsigned __int32 U32;
typedef signed __int32 S32;
typedef unsigned __int8 MD_U8;
typedef signed __int8 MD_S8;
typedef unsigned __int16 MD_U16;
typedef signed __int16 MD_S16;
typedef unsigned __int32 MD_U32;
typedef signed __int32 MD_S32;
# endif
typedef unsigned __int64 U64;
typedef signed __int64 S64;
typedef unsigned __int64 MD_U64;
typedef signed __int64 MD_S64;
#else
# include <stdint.h>
typedef uint8_t, U8;
typedef int8_t, S8;
typedef uint16_t, U16;
typedef int16_t, S16;
typedef uint32_t, U32;
typedef int32_t, S32;
typedef uint64_t, U64;
typedef int64_t, S64;
typedef uint8_t, MD_U8;
typedef int8_t, MD_S8;
typedef uint16_t, MD_U16;
typedef int16_t, MD_S16;
typedef uint32_t, MD_U32;
typedef int32_t, MD_S32;
typedef uint64_t, MD_U64;
typedef int64_t, MD_S64;
#endif
typedef struct U128 U128;
struct U128 {
U64 data[2];
MD_U64 data[2];
};
static_assert( sizeof( U8 ) == sizeof( S8 ), "sizeof(U8) != sizeof(S8)" );
static_assert( sizeof( U16 ) == sizeof( S16 ), "sizeof(U16) != sizeof(sS6)" );
static_assert( sizeof( U32 ) == sizeof( S32 ), "sizeof(U32) != sizeof(sS2)" );
static_assert( sizeof( U64 ) == sizeof( S64 ), "sizeof(U64) != sizeof(sS4)" );
static_assert( sizeof( MD_U8 ) == sizeof( MD_S8 ), "sizeof(MD_U8) != sizeof(MD_S8)" );
static_assert( sizeof( MD_U16 ) == sizeof( MD_S16 ), "sizeof(MD_U16) != sizeof(sS6)" );
static_assert( sizeof( MD_U32 ) == sizeof( MD_S32 ), "sizeof(MD_U32) != sizeof(sS2)" );
static_assert( sizeof( MD_U64 ) == sizeof( MD_S64 ), "sizeof(MD_U64) != sizeof(sS4)" );
static_assert( sizeof( U8 ) == 1, "sizeof(U8) != 1" );
static_assert( sizeof( U16 ) == 2, "sizeof(U16) != 2" );
static_assert( sizeof( U32 ) == 4, "sizeof(U32) != 4" );
static_assert( sizeof( U64 ) == 8, "sizeof(U64) != 8" );
static_assert( sizeof( MD_U8 ) == 1, "sizeof(MD_U8) != 1" );
static_assert( sizeof( MD_U16 ) == 2, "sizeof(MD_U16) != 2" );
static_assert( sizeof( MD_U32 ) == 4, "sizeof(MD_U32) != 4" );
static_assert( sizeof( MD_U64 ) == 8, "sizeof(MD_U64) != 8" );
typedef size_t USIZE;
typedef ptrdiff_t SSIZE;
typedef size_t MD_USIZE;
typedef ptrdiff_t MD_SSIZE;
static_assert( sizeof( USIZE ) == sizeof( SSIZE ), "sizeof(USIZE) != sizeof(SSIZE)" );
static_assert( sizeof( MD_USIZE ) == sizeof( MD_SSIZE ), "sizeof(MD_USIZE) != sizeof(MD_SSIZE)" );
#ifndef size_of
#define size_of( x ) ( SSIZE )( sizeof( x ) )
#define size_of( x ) ( MD_SSIZE )( sizeof( x ) )
#endif
// NOTE: (u)zpl_intptr is only here for semantic reasons really as this library will only support 32/64 bit OSes.
#if defined( _WIN64 )
typedef signed __int64 SPTR;
typedef unsigned __int64 UPTR;
typedef signed __int64 MD_SPTR;
typedef unsigned __int64 MD_UPTR;
#elif defined( _WIN32 )
// NOTE; To mark types changing their size, e.g. zpl_intptr
# ifndef _W64
@@ -75,254 +75,254 @@ typedef unsigned __int64 UPTR;
# define _W64
# endif
# endif
typedef _W64 signed int SPTR;
typedef _W64 unsigned int UPTR;
typedef _W64 signed int MD_SPTR;
typedef _W64 unsigned int MD_UPTR;
#else
typedef uintptr_t UPTR;
typedef intptr_t SPTR;
typedef uintptr_t MD_UPTR;
typedef intptr_t MD_SPTR;
#endif
static_assert( sizeof( UPTR ) == sizeof( SPTR ), "sizeof(UPTR) != sizeof(SPTR)" );
static_assert( sizeof( MD_UPTR ) == sizeof( MD_SPTR ), "sizeof(MD_UPTR) != sizeof(MD_SPTR)" );
typedef float F32;
typedef double F64;
typedef float MD_F32;
typedef double MD_F64;
static_assert( sizeof( F32 ) == 4, "sizeof(F32) != 4" );
static_assert( sizeof( F64 ) == 8, "sizeof(F64) != 8" );
static_assert( sizeof( MD_F32 ) == 4, "sizeof(MD_F32) != 4" );
static_assert( sizeof( MD_F64 ) == 8, "sizeof(MD_F64) != 8" );
typedef S8 B8;
typedef S16 B16;
typedef S32 B32;
typedef MD_S8 MD_B8;
typedef MD_S16 MD_B16;
typedef MD_S32 MD_B32;
typedef void VoidProc(void);
distinct_register_selector(VoidProc);
typedef void MD_VoidProc(void);
md_distinct_register_selector(MD_VoidProc);
////////////////////////////////
//~ NOTE(allen): Constants
#define SIGN32 0x80000000
#define EXPONENT32 0x7F800000
#define MANTISSA32 0x007FFFFF
#define MD_SIGN32 0x80000000
#define MD_EXPONENT32 0x7F800000
#define MD_MANTISSA32 0x007FFFFF
#define BIG_GOLDEN32 1.61803398875f
#define SMALL_GOLDEN32 0.61803398875f
#define MD_BIG_GOLDEN32 1.61803398875f
#define MD_SMALL_GOLDEN32 0.61803398875f
#define PI32 3.1415926535897f
#define MD_PI32 3.1415926535897f
#define MACHINE_EPSILON64 4.94065645841247e-324
#define MD_MACHINE_EPSILON64 4.94065645841247e-324
#define MIN_U8 0u
#define MAX_U8 0xffu
#define MIN_S8 ( -0x7f - 1 )
#define MAX_S8 0x7f
#define MD_MIN_U8 0u
#define MD_MAX_U8 0xffu
#define MD_MIN_S8 ( -0x7f - 1 )
#define MD_MAX_S8 0x7f
#define MIN_U16 0u
#define MAX_U16 0xffffu
#define MIN_S16 ( -0x7fff - 1 )
#define MAX_S16 0x7fff
#define MD_MIN_U16 0u
#define MD_MAX_U16 0xffffu
#define MD_MIN_S16 ( -0x7fff - 1 )
#define MD_MAX_S16 0x7fff
#define MIN_U32 0u
#define MAX_U32 0xffffffffu
#define MIN_S32 ( -0x7fffffff - 1 )
#define MAX_S32 0x7fffffff
#define MD_MIN_U32 0u
#define MD_MAX_U32 0xffffffffu
#define MD_MIN_S32 ( -0x7fffffff - 1 )
#define MD_MAX_S32 0x7fffffff
#define MIN_U64 0ull
#define MAX_U64 0xffffffffffffffffull
#define MIN_S64 ( -0x7fffffffffffffffll - 1 )
#define MAX_S64 0x7fffffffffffffffll
#define MD_MIN_U64 0ull
#define MD_MAX_U64 0xffffffffffffffffull
#define MD_MIN_S64 ( -0x7fffffffffffffffll - 1 )
#define MD_MAX_S64 0x7fffffffffffffffll
#if ARCH_32BIT
# define MIN_USIZE U32_MIN
# define MAX_USIZE U32_MAX
#if MD_ARCH_32BIT
# define MD_MIN_USIZE U32_MIN
# define MD_MAX_USIZE U32_MAX
# define MIN_SSIZE S32_MIN
# define MAX_SSIZE S32_MAX
#elif ARCH_64BIT
# define MIN_USIZE U64_MIN
# define MAX_USIZE U64_MAX
#elif MD_ARCH_64BIT
# define MD_MIN_USIZE U64_MIN
# define MD_MAX_USIZE U64_MAX
# define MIN_SSIZE S64_MIN
# define MAX_SSIZE S64_MAX
#else
# error Unknown architecture size. This library only supports 32 bit and 64 bit architectures.
#endif
#define MIN_F32 1.17549435e-38f
#define MAX_F32 3.40282347e+38f
#define MIN_F64 2.2250738585072014e-308
#define MAX_F64 1.7976931348623157e+308
#define MD_MIN_F32 1.17549435e-38f
#define MD_MAX_F32 3.40282347e+38f
#define MD_MIN_F64 2.2250738585072014e-308
#define MD_MAX_F64 1.7976931348623157e+308
#define BITMASK1 0x00000001
#define BITMASK2 0x00000003
#define BITMASK3 0x00000007
#define BITMASK4 0x0000000f
#define BITMASK5 0x0000001f
#define BITMASK6 0x0000003f
#define BITMASK7 0x0000007f
#define BITMASK8 0x000000ff
#define BITMASK9 0x000001ff
#define BITMASK10 0x000003ff
#define BITMASK11 0x000007ff
#define BITMASK12 0x00000fff
#define BITMASK13 0x00001fff
#define BITMASK14 0x00003fff
#define BITMASK15 0x00007fff
#define BITMASK16 0x0000ffff
#define BITMASK17 0x0001ffff
#define BITMASK18 0x0003ffff
#define BITMASK19 0x0007ffff
#define BITMASK20 0x000fffff
#define BITMASK21 0x001fffff
#define BITMASK22 0x003fffff
#define BITMASK23 0x007fffff
#define BITMASK24 0x00ffffff
#define BITMASK25 0x01ffffff
#define BITMASK26 0x03ffffff
#define BITMASK27 0x07ffffff
#define BITMASK28 0x0fffffff
#define BITMASK29 0x1fffffff
#define BITMASK30 0x3fffffff
#define BITMASK31 0x7fffffff
#define BITMASK32 0xffffffff
#define MD_BITMASK1 0x00000001
#define MD_BITMASK2 0x00000003
#define MD_BITMASK3 0x00000007
#define MD_BITMASK4 0x0000000f
#define MD_BITMASK5 0x0000001f
#define MD_BITMASK6 0x0000003f
#define MD_BITMASK7 0x0000007f
#define MD_BITMASK8 0x000000ff
#define MD_BITMASK9 0x000001ff
#define MD_BITMASK10 0x000003ff
#define MD_BITMASK11 0x000007ff
#define MD_BITMASK12 0x00000fff
#define MD_BITMASK13 0x00001fff
#define MD_BITMASK14 0x00003fff
#define MD_BITMASK15 0x00007fff
#define MD_BITMASK16 0x0000ffff
#define MD_BITMASK17 0x0001ffff
#define MD_BITMASK18 0x0003ffff
#define MD_BITMASK19 0x0007ffff
#define MD_BITMASK20 0x000fffff
#define MD_BITMASK21 0x001fffff
#define MD_BITMASK22 0x003fffff
#define MD_BITMASK23 0x007fffff
#define MD_BITMASK24 0x00ffffff
#define MD_BITMASK25 0x01ffffff
#define MD_BITMASK26 0x03ffffff
#define MD_BITMASK27 0x07ffffff
#define MD_BITMASK28 0x0fffffff
#define MD_BITMASK29 0x1fffffff
#define MD_BITMASK30 0x3fffffff
#define MD_BITMASK31 0x7fffffff
#define MD_BITMASK32 0xffffffff
#define BITMASK33 0x00000001ffffffffull
#define BITMASK34 0x00000003ffffffffull
#define BITMASK35 0x00000007ffffffffull
#define BITMASK36 0x0000000fffffffffull
#define BITMASK37 0x0000001fffffffffull
#define BITMASK38 0x0000003fffffffffull
#define BITMASK39 0x0000007fffffffffull
#define BITMASK40 0x000000ffffffffffull
#define BITMASK41 0x000001ffffffffffull
#define BITMASK42 0x000003ffffffffffull
#define BITMASK43 0x000007ffffffffffull
#define BITMASK44 0x00000fffffffffffull
#define BITMASK45 0x00001fffffffffffull
#define BITMASK46 0x00003fffffffffffull
#define BITMASK47 0x00007fffffffffffull
#define BITMASK48 0x0000ffffffffffffull
#define BITMASK49 0x0001ffffffffffffull
#define BITMASK50 0x0003ffffffffffffull
#define BITMASK51 0x0007ffffffffffffull
#define BITMASK52 0x000fffffffffffffull
#define BITMASK53 0x001fffffffffffffull
#define BITMASK54 0x003fffffffffffffull
#define BITMASK55 0x007fffffffffffffull
#define BITMASK56 0x00ffffffffffffffull
#define BITMASK57 0x01ffffffffffffffull
#define BITMASK58 0x03ffffffffffffffull
#define BITMASK59 0x07ffffffffffffffull
#define BITMASK60 0x0fffffffffffffffull
#define BITMASK61 0x1fffffffffffffffull
#define BITMASK62 0x3fffffffffffffffull
#define BITMASK63 0x7fffffffffffffffull
#define BITMASK64 0xffffffffffffffffull
#define MD_BITMASK33 0x00000001ffffffffull
#define MD_BITMASK34 0x00000003ffffffffull
#define MD_BITMASK35 0x00000007ffffffffull
#define MD_BITMASK36 0x0000000fffffffffull
#define MD_BITMASK37 0x0000001fffffffffull
#define MD_BITMASK38 0x0000003fffffffffull
#define MD_BITMASK39 0x0000007fffffffffull
#define MD_BITMASK40 0x000000ffffffffffull
#define MD_BITMASK41 0x000001ffffffffffull
#define MD_BITMASK42 0x000003ffffffffffull
#define MD_BITMASK43 0x000007ffffffffffull
#define MD_BITMASK44 0x00000fffffffffffull
#define MD_BITMASK45 0x00001fffffffffffull
#define MD_BITMASK46 0x00003fffffffffffull
#define MD_BITMASK47 0x00007fffffffffffull
#define MD_BITMASK48 0x0000ffffffffffffull
#define MD_BITMASK49 0x0001ffffffffffffull
#define MD_BITMASK50 0x0003ffffffffffffull
#define MD_BITMASK51 0x0007ffffffffffffull
#define MD_BITMASK52 0x000fffffffffffffull
#define MD_BITMASK53 0x001fffffffffffffull
#define MD_BITMASK54 0x003fffffffffffffull
#define MD_BITMASK55 0x007fffffffffffffull
#define MD_BITMASK56 0x00ffffffffffffffull
#define MD_BITMASK57 0x01ffffffffffffffull
#define MD_BITMASK58 0x03ffffffffffffffull
#define MD_BITMASK59 0x07ffffffffffffffull
#define MD_BITMASK60 0x0fffffffffffffffull
#define MD_BITMASK61 0x1fffffffffffffffull
#define MD_BITMASK62 0x3fffffffffffffffull
#define MD_BITMASK63 0x7fffffffffffffffull
#define MD_BITMASK64 0xffffffffffffffffull
#define BIT1 (1 << 0)
#define BIT2 (1 << 1)
#define BIT3 (1 << 2)
#define BIT4 (1 << 3)
#define BIT5 (1 << 4)
#define BIT6 (1 << 5)
#define BIT7 (1 << 6)
#define BIT8 (1 << 7)
#define BIT9 (1 << 8)
#define BIT10 (1 << 9)
#define BIT11 (1 << 10)
#define BIT12 (1 << 11)
#define BIT13 (1 << 12)
#define BIT14 (1 << 13)
#define BIT15 (1 << 14)
#define BIT16 (1 << 15)
#define BIT17 (1 << 16)
#define BIT18 (1 << 17)
#define BIT19 (1 << 18)
#define BIT20 (1 << 19)
#define BIT21 (1 << 20)
#define BIT22 (1 << 21)
#define BIT23 (1 << 22)
#define BIT24 (1 << 23)
#define BIT25 (1 << 24)
#define BIT26 (1 << 25)
#define BIT27 (1 << 26)
#define BIT28 (1 << 27)
#define BIT29 (1 << 28)
#define BIT30 (1 << 29)
#define BIT31 (1 << 30)
#define BIT32 (1 << 31)
#define MD_BIT1 (1 << 0)
#define MD_BIT2 (1 << 1)
#define MD_BIT3 (1 << 2)
#define MD_BIT4 (1 << 3)
#define MD_BIT5 (1 << 4)
#define MD_BIT6 (1 << 5)
#define MD_BIT7 (1 << 6)
#define MD_BIT8 (1 << 7)
#define MD_BIT9 (1 << 8)
#define MD_BIT10 (1 << 9)
#define MD_BIT11 (1 << 10)
#define MD_BIT12 (1 << 11)
#define MD_BIT13 (1 << 12)
#define MD_BIT14 (1 << 13)
#define MD_BIT15 (1 << 14)
#define MD_BIT16 (1 << 15)
#define MD_BIT17 (1 << 16)
#define MD_BIT18 (1 << 17)
#define MD_BIT19 (1 << 18)
#define MD_BIT20 (1 << 19)
#define MD_BIT21 (1 << 20)
#define MD_BIT22 (1 << 21)
#define MD_BIT23 (1 << 22)
#define MD_BIT24 (1 << 23)
#define MD_BIT25 (1 << 24)
#define MD_BIT26 (1 << 25)
#define MD_BIT27 (1 << 26)
#define MD_BIT28 (1 << 27)
#define MD_BIT29 (1 << 28)
#define MD_BIT30 (1 << 29)
#define MD_BIT31 (1 << 30)
#define MD_BIT32 (1 << 31)
#define BIT33 (1ull << 32)
#define BIT34 (1ull << 33)
#define BIT35 (1ull << 34)
#define BIT36 (1ull << 35)
#define BIT37 (1ull << 36)
#define BIT38 (1ull << 37)
#define BIT39 (1ull << 38)
#define BIT40 (1ull << 39)
#define BIT41 (1ull << 40)
#define BIT42 (1ull << 41)
#define BIT43 (1ull << 42)
#define BIT44 (1ull << 43)
#define BIT45 (1ull << 44)
#define BIT46 (1ull << 45)
#define BIT47 (1ull << 46)
#define BIT48 (1ull << 47)
#define BIT49 (1ull << 48)
#define BIT50 (1ull << 49)
#define BIT51 (1ull << 50)
#define BIT52 (1ull << 51)
#define BIT53 (1ull << 52)
#define BIT54 (1ull << 53)
#define BIT55 (1ull << 54)
#define BIT56 (1ull << 55)
#define BIT57 (1ull << 56)
#define BIT58 (1ull << 57)
#define BIT59 (1ull << 58)
#define BIT60 (1ull << 59)
#define BIT61 (1ull << 60)
#define BIT62 (1ull << 61)
#define BIT63 (1ull << 62)
#define BIT64 (1ull << 63)
#define MD_BIT33 (1ull << 32)
#define MD_BIT34 (1ull << 33)
#define MD_BIT35 (1ull << 34)
#define MD_BIT36 (1ull << 35)
#define MD_BIT37 (1ull << 36)
#define MD_BIT38 (1ull << 37)
#define MD_BIT39 (1ull << 38)
#define MD_BIT40 (1ull << 39)
#define MD_BIT41 (1ull << 40)
#define MD_BIT42 (1ull << 41)
#define MD_BIT43 (1ull << 42)
#define MD_BIT44 (1ull << 43)
#define MD_BIT45 (1ull << 44)
#define MD_BIT46 (1ull << 45)
#define MD_BIT47 (1ull << 46)
#define MD_BIT48 (1ull << 47)
#define MD_BIT49 (1ull << 48)
#define MD_BIT50 (1ull << 49)
#define MD_BIT51 (1ull << 50)
#define MD_BIT52 (1ull << 51)
#define MD_BIT53 (1ull << 52)
#define MD_BIT54 (1ull << 53)
#define MD_BIT55 (1ull << 54)
#define MD_BIT56 (1ull << 55)
#define MD_BIT57 (1ull << 56)
#define MD_BIT58 (1ull << 57)
#define MD_BIT59 (1ull << 58)
#define MD_BIT60 (1ull << 59)
#define MD_BIT61 (1ull << 60)
#define MD_BIT62 (1ull << 61)
#define MD_BIT63 (1ull << 62)
#define MD_BIT64 (1ull << 63)
////////////////////////////////
//~ Globally Unique Ids
typedef union Guid Guid;
union Guid
typedef union MD_Guid MD_Guid;
union MD_Guid
{
struct
{
U32 data1;
U16 data2;
U16 data3;
U8 data4[8];
MD_U32 data1;
MD_U16 data2;
MD_U16 data3;
MD_U8 data4[8];
};
U8 v[16];
MD_U8 v[16];
};
static_assert(size_of(Guid) == 16, "Guid is not 16 bytes");
static_assert(size_of(MD_Guid) == 16, "MD_Guid is not 16 bytes");
////////////////////////////////
//~ Arrays
typedef struct U16Array U16Array;
struct U16Array
typedef struct MD_U16Array MD_U16Array;
struct MD_U16Array
{
U64 count;
U16* v;
MD_U64 count;
MD_U16* v;
};
typedef struct U32Array U32Array;
struct U32Array
typedef struct MD_U32Array MD_U32Array;
struct MD_U32Array
{
U64 count;
U32* v;
MD_U64 count;
MD_U32* v;
};
typedef struct U64Array U64Array;
struct U64Array
typedef struct MD_U64Array MD_U64Array;
struct MD_U64Array
{
U64 count;
U64* v;
MD_U64 count;
MD_U64* v;
};
typedef struct U128Array U128Array;
struct U128Array
typedef struct MD_U128Array MD_U128Array;
struct MD_U128Array
{
U64 count;
MD_U64 count;
U128* v;
};
+55 -55
View File
@@ -8,24 +8,24 @@
////////////////////////////////
//~ NOTE(rjf): Command Line Option Parsing
CmdLineOpt**
cmd_line_slot_from_string(CmdLine* cmd_line, String8 string) {
CmdLineOpt** slot = 0;
MD_CmdLineOpt**
md_cmd_line_slot_from_string(MD_CmdLine* cmd_line, MD_String8 string) {
MD_CmdLineOpt** slot = 0;
if (cmd_line->option_table_size != 0)
{
U64 hash = cmd_line_hash_from_string(string);
U64 bucket = hash % cmd_line->option_table_size;
MD_U64 hash = md_cmd_line_hash_from_string(string);
MD_U64 bucket = hash % cmd_line->option_table_size;
slot = &cmd_line->option_table[bucket];
}
return slot;
}
CmdLineOpt*
cmd_line_opt_from_slot(CmdLineOpt** slot, String8 string) {
CmdLineOpt* result = 0;
for (CmdLineOpt* var = *slot; var; var = var->hash_next)
MD_CmdLineOpt*
md_cmd_line_opt_from_slot(MD_CmdLineOpt** slot, MD_String8 string) {
MD_CmdLineOpt* result = 0;
for (MD_CmdLineOpt* var = *slot; var; var = var->hash_next)
{
if (str8_match(string, var->string, 0)) {
if (md_str8_match(string, var->string, 0)) {
result = var;
break;
}
@@ -33,73 +33,73 @@ cmd_line_opt_from_slot(CmdLineOpt** slot, String8 string) {
return result;
}
CmdLineOpt*
cmd_line_insert_opt__ainfo(AllocatorInfo ainfo, CmdLine* cmd_line, String8 string, String8List values)
MD_CmdLineOpt*
md_cmd_line_insert_opt__ainfo(MD_AllocatorInfo ainfo, MD_CmdLine* cmd_line, MD_String8 string, MD_String8List values)
{
CmdLineOpt *var = 0;
CmdLineOpt **slot = cmd_line_slot_from_string(cmd_line, string);
CmdLineOpt *existing_var = cmd_line_opt_from_slot(slot, string);
MD_CmdLineOpt *var = 0;
MD_CmdLineOpt **slot = md_cmd_line_slot_from_string(cmd_line, string);
MD_CmdLineOpt *existing_var = md_cmd_line_opt_from_slot(slot, string);
if(existing_var != 0)
{
var = existing_var;
}
else
{
var = alloc_array(ainfo, CmdLineOpt, 1);
var = md_alloc_array(ainfo, MD_CmdLineOpt, 1);
var->hash_next = *slot;
var->hash = cmd_line_hash_from_string(string);
var->string = str8_copy(ainfo, string);
var->hash = md_cmd_line_hash_from_string(string);
var->string = md_str8_copy(ainfo, string);
var->value_strings = values;
StringJoin join = {0};
join.pre = str8_lit("");
join.sep = str8_lit(",");
join.post = str8_lit("");
MD_StringJoin join = {0};
join.pre = md_str8_lit("");
join.sep = md_str8_lit(",");
join.post = md_str8_lit("");
var->value_string = str8_list_join(ainfo, &var->value_strings, &join);
var->value_string = md_str8_list_join(ainfo, &var->value_strings, &join);
*slot = var;
cmd_line_push_opt(&cmd_line->options, var);
md_cmd_line_push_opt(&cmd_line->options, var);
}
return var;
}
CmdLine
cmd_line_from_string_list__ainfo(AllocatorInfo ainfo, String8List command_line)
MD_CmdLine
md_cmd_line_from_string_list__ainfo(MD_AllocatorInfo ainfo, MD_String8List command_line)
{
CmdLine parsed = {0};
MD_CmdLine parsed = {0};
parsed.exe_name = command_line.first->string;
// NOTE(rjf): Set up config option table.
{
parsed.option_table_size = 4096;
parsed.option_table = alloc_array(ainfo, CmdLineOpt*, parsed.option_table_size);
parsed.option_table = md_alloc_array(ainfo, MD_CmdLineOpt*, parsed.option_table_size);
}
// NOTE(rjf): Parse command line.
B32 after_passthrough_option = 0;
B32 first_passthrough = 1;
for (String8Node* node = command_line.first->next, *next = 0; node != 0; node = next)
MD_B32 after_passthrough_option = 0;
MD_B32 first_passthrough = 1;
for (MD_String8Node* node = command_line.first->next, *next = 0; node != 0; node = next)
{
next = node->next;
String8 option_name = node->string;
MD_String8 option_name = node->string;
// NOTE(rjf): Look at -- or - at the start of an argument to determine if it's
// a flag option. All arguments after a single "--" (with no trailing string
// on the command line will be considered as input files.
B32 is_option = 1;
MD_B32 is_option = 1;
if(after_passthrough_option == 0)
{
if (str8_match(node->string, str8_lit("--"), 0)) {
if (md_str8_match(node->string, md_str8_lit("--"), 0)) {
after_passthrough_option = 1;
is_option = 0;
}
else if (str8_match(str8_prefix(node->string, 2), str8_lit("--"), 0)) {
option_name = str8_skip(option_name, 2);
else if (md_str8_match(md_str8_prefix(node->string, 2), md_str8_lit("--"), 0)) {
option_name = md_str8_skip(option_name, 2);
}
else if (str8_match(str8_prefix(node->string, 1), str8_lit("-"), 0)) {
option_name = str8_skip(option_name, 1);
else if (md_str8_match(md_str8_prefix(node->string, 1), md_str8_lit("-"), 0)) {
option_name = md_str8_skip(option_name, 1);
}
else {
is_option = 0;
@@ -113,49 +113,49 @@ cmd_line_from_string_list__ainfo(AllocatorInfo ainfo, String8List command_line)
// NOTE(rjf): This string is an option.
if(is_option)
{
B32 has_arguments = 0;
U64 arg_signifier_position1 = str8_find_needle(option_name, 0, str8_lit(":"), 0);
U64 arg_signifier_position2 = str8_find_needle(option_name, 0, str8_lit("="), 0);
U64 arg_signifier_position = min(arg_signifier_position1, arg_signifier_position2);
String8 arg_portion_this_string = str8_skip(option_name, arg_signifier_position+1);
MD_B32 has_arguments = 0;
MD_U64 arg_signifier_position1 = md_str8_find_needle(option_name, 0, md_str8_lit(":"), 0);
MD_U64 arg_signifier_position2 = md_str8_find_needle(option_name, 0, md_str8_lit("="), 0);
MD_U64 arg_signifier_position = md_min(arg_signifier_position1, arg_signifier_position2);
MD_String8 arg_portion_this_string = md_str8_skip(option_name, arg_signifier_position+1);
if (arg_signifier_position < option_name.size) {
has_arguments = 1;
}
option_name = str8_prefix(option_name, arg_signifier_position);
option_name = md_str8_prefix(option_name, arg_signifier_position);
String8List arguments = {0};
MD_String8List arguments = {0};
// NOTE(rjf): Parse arguments.
if (has_arguments)
{
for (String8Node* n = node; n; n = n->next)
for (MD_String8Node* n = node; n; n = n->next)
{
next = n->next;
String8 string = n->string;
MD_String8 string = n->string;
if (n == node) {
string = arg_portion_this_string;
}
U8 splits[] = { ',' };
String8List args_in_this_string = str8_split(ainfo, string, splits, array_count(splits), 0);
for (String8Node* sub_arg = args_in_this_string.first; sub_arg; sub_arg = sub_arg->next) {
str8_list_push(ainfo, &arguments, sub_arg->string);
MD_U8 splits[] = { ',' };
MD_String8List args_in_this_string = md_str8_split(ainfo, string, splits, md_array_count(splits), 0);
for (MD_String8Node* sub_arg = args_in_this_string.first; sub_arg; sub_arg = sub_arg->next) {
md_str8_list_push(ainfo, &arguments, sub_arg->string);
}
if ( !str8_match(str8_postfix(n->string, 1), str8_lit(","), 0) && (n != node || arg_portion_this_string.size != 0)) {
if ( !md_str8_match(md_str8_postfix(n->string, 1), md_str8_lit(","), 0) && (n != node || arg_portion_this_string.size != 0)) {
break;
}
}
}
// NOTE(rjf): Register config variable.
cmd_line_insert_opt(ainfo, &parsed, option_name, arguments);
md_cmd_line_insert_opt(ainfo, &parsed, option_name, arguments);
}
// NOTE(rjf): Default path, treat as a passthrough config option to be
// handled by tool-specific code.
else if ( !str8_match(node->string, str8_lit("--"), 0) || !first_passthrough) {
str8_list_push(ainfo, &parsed.inputs, node->string);
else if ( !md_str8_match(node->string, md_str8_lit("--"), 0) || !first_passthrough) {
md_str8_list_push(ainfo, &parsed.inputs, node->string);
after_passthrough_option = 1;
first_passthrough = 0;
}
+61 -61
View File
@@ -9,98 +9,98 @@
////////////////////////////////
//~ rjf: Parsed Command Line Types
typedef struct CmdLineOpt CmdLineOpt;
struct CmdLineOpt
typedef struct MD_CmdLineOpt MD_CmdLineOpt;
struct MD_CmdLineOpt
{
CmdLineOpt* next;
CmdLineOpt* hash_next;
U64 hash;
String8 string;
String8List value_strings;
String8 value_string;
MD_CmdLineOpt* next;
MD_CmdLineOpt* hash_next;
MD_U64 hash;
MD_String8 string;
MD_String8List value_strings;
MD_String8 value_string;
};
typedef struct CmdLineOptList CmdLineOptList;
struct CmdLineOptList
typedef struct MD_CmdLineOptList MD_CmdLineOptList;
struct MD_CmdLineOptList
{
U64 count;
CmdLineOpt* first;
CmdLineOpt* last;
MD_U64 count;
MD_CmdLineOpt* first;
MD_CmdLineOpt* last;
};
typedef struct CmdLine CmdLine;
struct CmdLine
typedef struct MD_CmdLine MD_CmdLine;
struct MD_CmdLine
{
String8 exe_name;
CmdLineOptList options;
String8List inputs;
U64 option_table_size;
CmdLineOpt** option_table;
MD_String8 exe_name;
MD_CmdLineOptList options;
MD_String8List inputs;
MD_U64 option_table_size;
MD_CmdLineOpt** option_table;
};
////////////////////////////////
//~ NOTE(rjf): Command Line Option Parsing
U64 cmd_line_hash_from_string(String8 string);
MD_API CmdLineOpt** cmd_line_slot_from_string(CmdLine* cmd_line, String8 string);
MD_API CmdLineOpt* cmd_line_opt_from_slot (CmdLineOpt** slot, String8 string);
void cmd_line_push_opt (CmdLineOptList* list, CmdLineOpt* var);
MD_U64 md_cmd_line_hash_from_string(MD_String8 string);
MD_API MD_CmdLineOpt** md_cmd_line_slot_from_string(MD_CmdLine* cmd_line, MD_String8 string);
MD_API MD_CmdLineOpt* md_cmd_line_opt_from_slot (MD_CmdLineOpt** slot, MD_String8 string);
void md_cmd_line_push_opt (MD_CmdLineOptList* list, MD_CmdLineOpt* var);
CmdLineOpt* cmd_line_opt_from_string (CmdLine* cmd_line, String8 name);
String8List cmd_line_strings (CmdLine* cmd_line, String8 name);
String8 cmd_line_string (CmdLine* cmd_line, String8 name);
B32 cmd_line_has_flag (CmdLine* cmd_line, String8 name);
B32 cmd_line_has_argument (CmdLine* cmd_line, String8 name);
MD_CmdLineOpt* md_cmd_line_opt_from_string (MD_CmdLine* cmd_line, MD_String8 name);
MD_String8List md_cmd_line_strings (MD_CmdLine* cmd_line, MD_String8 name);
MD_String8 md_cmd_line_string (MD_CmdLine* cmd_line, MD_String8 name);
MD_B32 md_cmd_line_has_flag (MD_CmdLine* cmd_line, MD_String8 name);
MD_B32 md_cmd_line_has_argument (MD_CmdLine* cmd_line, MD_String8 name);
inline CmdLineOpt* cmd_line_insert_opt__arena (Arena* arena, CmdLine* cmd_line, String8 string, String8List values);
MD_API CmdLineOpt* cmd_line_insert_opt__ainfo (AllocatorInfo ainfo, CmdLine* cmd_line, String8 string, String8List values);
inline CmdLine cmd_line_from_string_list__arena(Arena* arena, String8List arguments);
MD_API CmdLine cmd_line_from_string_list__ainfo(AllocatorInfo ainfo, String8List arguments);
inline MD_CmdLineOpt* md_cmd_line_insert_opt__arena (MD_Arena* arena, MD_CmdLine* cmd_line, MD_String8 string, MD_String8List values);
MD_API MD_CmdLineOpt* md_cmd_line_insert_opt__ainfo (MD_AllocatorInfo ainfo, MD_CmdLine* cmd_line, MD_String8 string, MD_String8List values);
inline MD_CmdLine md_cmd_line_from_string_list__arena(MD_Arena* arena, MD_String8List arguments);
MD_API MD_CmdLine md_cmd_line_from_string_list__ainfo(MD_AllocatorInfo ainfo, MD_String8List arguments);
#define cmd_line_insert_opt(allocator, cmd_line, string, values) \
#define md_cmd_line_insert_opt(allocator, cmd_line, string, values) \
_Generic(allocator, \
Arena*: cmd_line_insert_opt__arena, \
AllocatorInfo: cmd_line_insert_opt__ainfo, \
default: assert_generic_sel_fail \
) generic_call(allocator, cmd_line, string, values)
MD_Arena*: md_cmd_line_insert_opt__arena, \
MD_AllocatorInfo: md_cmd_line_insert_opt__ainfo, \
default: md_assert_generic_sel_fail \
) md_generic_call(allocator, cmd_line, string, values)
#define cmd_line_from_string_list(allocator, arguments) \
#define md_cmd_line_from_string_list(allocator, arguments) \
_Generic(allocator, \
Arena*: cmd_line_from_string_list__arena, \
AllocatorInfo: cmd_line_from_string_list__ainfo, \
default: assert_generic_sel_fail \
) generic_call(allocator, arguments)
MD_Arena*: md_cmd_line_from_string_list__arena, \
MD_AllocatorInfo: md_cmd_line_from_string_list__ainfo, \
default: md_assert_generic_sel_fail \
) md_generic_call(allocator, arguments)
inline U64
cmd_line_hash_from_string(String8 string) {
U64 result = 5381;
for(U64 i = 0; i < string.size; i += 1) {
inline MD_U64
md_cmd_line_hash_from_string(MD_String8 string) {
MD_U64 result = 5381;
for(MD_U64 i = 0; i < string.size; i += 1) {
result = ((result << 5) + result) + string.str[i];
}
return result;
}
force_inline CmdLineOpt* cmd_line_insert_opt__arena (Arena* arena, CmdLine* cmd_line, String8 string, String8List values) { return cmd_line_insert_opt__ainfo (arena_allocator(arena), cmd_line, string, values); }
force_inline CmdLine cmd_line_from_string_list__arena(Arena* arena, String8List command_line) { return cmd_line_from_string_list__ainfo(arena_allocator(arena), command_line); }
md_force_inline MD_CmdLineOpt* md_cmd_line_insert_opt__arena (MD_Arena* arena, MD_CmdLine* cmd_line, MD_String8 string, MD_String8List values) { return md_cmd_line_insert_opt__ainfo (md_arena_allocator(arena), cmd_line, string, values); }
md_force_inline MD_CmdLine md_cmd_line_from_string_list__arena(MD_Arena* arena, MD_String8List command_line) { return md_cmd_line_from_string_list__ainfo(md_arena_allocator(arena), command_line); }
inline CmdLineOpt* cmd_line_opt_from_string(CmdLine *cmd_line, String8 name) { return cmd_line_opt_from_slot(cmd_line_slot_from_string(cmd_line, name), name); }
inline B32 cmd_line_has_flag (CmdLine *cmd_line, String8 name) { CmdLineOpt *var = cmd_line_opt_from_string(cmd_line, name); return(var != 0); }
inline B32 cmd_line_has_argument (CmdLine *cmd_line, String8 name) { CmdLineOpt *var = cmd_line_opt_from_string(cmd_line, name); return(var != 0 && var->value_strings.node_count > 0); }
inline MD_CmdLineOpt* md_cmd_line_opt_from_string(MD_CmdLine *cmd_line, MD_String8 name) { return md_cmd_line_opt_from_slot(md_cmd_line_slot_from_string(cmd_line, name), name); }
inline MD_B32 md_cmd_line_has_flag (MD_CmdLine *cmd_line, MD_String8 name) { MD_CmdLineOpt *var = md_cmd_line_opt_from_string(cmd_line, name); return(var != 0); }
inline MD_B32 md_cmd_line_has_argument (MD_CmdLine *cmd_line, MD_String8 name) { MD_CmdLineOpt *var = md_cmd_line_opt_from_string(cmd_line, name); return(var != 0 && var->value_strings.md_node_count > 0); }
inline String8List
cmd_line_strings(CmdLine *cmd_line, String8 name) {
String8List result = {0};
CmdLineOpt* var = cmd_line_opt_from_string(cmd_line, name);
inline MD_String8List
md_cmd_line_strings(MD_CmdLine *cmd_line, MD_String8 name) {
MD_String8List result = {0};
MD_CmdLineOpt* var = md_cmd_line_opt_from_string(cmd_line, name);
if (var != 0) { result = var->value_strings; }
return result;
}
inline String8
cmd_line_string(CmdLine *cmd_line, String8 name) {
String8 result = {0};
CmdLineOpt* var = cmd_line_opt_from_string(cmd_line, name);
inline MD_String8
md_cmd_line_string(MD_CmdLine *cmd_line, MD_String8 name) {
MD_String8 result = {0};
MD_CmdLineOpt* var = md_cmd_line_opt_from_string(cmd_line, name);
if (var != 0) { result = var->value_string; }
return result;
}
inline void cmd_line_push_opt(CmdLineOptList* list, CmdLineOpt* var) { sll_queue_push(list->first, list->last, var); list->count += 1; }
inline void md_cmd_line_push_opt(MD_CmdLineOptList* list, MD_CmdLineOpt* var) { md_sll_queue_push(list->first, list->last, var); list->count += 1; }
+140 -140
View File
@@ -7,68 +7,68 @@
////////////////////////////////
//~ rjf: Build Options
#if ! defined(BUILD_DEBUG)
# define BUILD_DEBUG 1
#if ! defined(MD_BUILD_DEBUG)
# define MD_BUILD_DEBUG 1
#endif
#if ! defined(BUILD_STATIC)
# define BUILD_STATIC 0
#if ! defined(MD_BUILD_STATIC)
# define MD_BUILD_STATIC 0
#endif
#if ! defined(BUILD_DYANMIC)
# define BUILD_DYANMIC 0
#if ! defined(MD_BUILD_DYANMIC)
# define MD_BUILD_DYANMIC 0
#endif
#if ! defined(BUILD_API_EXPORT)
# define BUILD_API_EXPORT 0
#if ! defined(MD_BUILD_API_EXPORT)
# define MD_BUILD_API_EXPORT 0
#endif
#if !defined(BUILD_ENTRY_DEFINING_UNIT)
# define BUILD_ENTRY_DEFINING_UNIT 0
#if !defined(MD_BUILD_ENTRY_DEFINING_UNIT)
# define MD_BUILD_ENTRY_DEFINING_UNIT 0
#endif
#if !defined(BUILD_CONSOLE_INTERFACE)
# define BUILD_CONSOLE_INTERFACE 0
#if !defined(MD_BUILD_CONSOLE_INTERFACE)
# define MD_BUILD_CONSOLE_INTERFACE 0
#endif
#if !defined(BUILD_VERSION_MAJOR)
# define BUILD_VERSION_MAJOR 0
#if !defined(MD_BUILD_VERSION_MAJOR)
# define MD_BUILD_VERSION_MAJOR 0
#endif
#if !defined(BUILD_VERSION_MINOR)
# define BUILD_VERSION_MINOR 1
#if !defined(MD_BUILD_VERSION_MINOR)
# define MD_BUILD_VERSION_MINOR 1
#endif
#if !defined(BUILD_VERSION_PATCH)
# define BUILD_VERSION_PATCH 0
#if !defined(MD_BUILD_VERSION_PATCH)
# define MD_BUILD_VERSION_PATCH 0
#endif
#define BUILD_VERSION_STRING_LITERAL stringify(BUILD_VERSION_MAJOR) "." stringify(BUILD_VERSION_MINOR) "." stringify(BUILD_VERSION_PATCH)
#define MD_BUILD_VERSION_STRING_LITERAL md_stringify(MD_BUILD_VERSION_MAJOR) "." md_stringify(MD_BUILD_VERSION_MINOR) "." md_stringify(MD_BUILD_VERSION_PATCH)
#if BUILD_DEBUG
# define BUILD_MODE_STRING_LITERAL_APPEND " [Debug]"
#if MD_BUILD_DEBUG
# define MD_BUILD_MODE_STRING_LITERAL_APPEND " [Debug]"
#else
# define BUILD_MODE_STRING_LITERAL_APPEND ""
# define MD_BUILD_MODE_STRING_LITERAL_APPEND ""
#endif
#if defined(BUILD_GIT_HASH)
# define BUILD_GIT_HASH_STRING_LITERAL_APPEND " [" BUILD_GIT_HASH "]"
#if defined(MD_BUILD_GIT_HASH)
# define MD_BUILD_GIT_HASH_STRING_LITERAL_APPEND " [" MD_BUILD_GIT_HASH "]"
#else
# define BUILD_GIT_HASH_STRING_LITERAL_APPEND ""
# define MD_BUILD_GIT_HASH_STRING_LITERAL_APPEND ""
#endif
#if !defined(BUILD_TITLE)
# define BUILD_TITLE "Untitled"
#if !defined(MD_BUILD_TITLE)
# define MD_BUILD_TITLE "Untitled"
#endif
#if !defined(BUILD_RELEASE_PHASE_STRING_LITERAL)
# define BUILD_RELEASE_PHASE_STRING_LITERAL "ALPHA"
#if !defined(MD_BUILD_RELEASE_PHASE_STRING_LITERAL)
# define MD_BUILD_RELEASE_PHASE_STRING_LITERAL "ALPHA"
#endif
#if !defined(BUILD_ISSUES_LINK_STRING_LITERAL)
# define BUILD_ISSUES_LINK_STRING_LITERAL "ADD_BUILD_ISSUES_LINK"
#if !defined(MD_BUILD_ISSUES_LINK_STRING_LITERAL)
# define MD_BUILD_ISSUES_LINK_STRING_LITERAL "ADD_BUILD_ISSUES_LINK"
#endif
#define BUILD_TITLE_STRING_LITERAL BUILD_TITLE " (" BUILD_VERSION_STRING_LITERAL " " BUILD_RELEASE_PHASE_STRING_LITERAL ") - " __DATE__ "" BUILD_GIT_HASH_STRING_LITERAL_APPEND BUILD_MODE_STRING_LITERAL_APPEND
#define MD_BUILD_TITLE_STRING_LITERAL MD_BUILD_TITLE " (" MD_BUILD_VERSION_STRING_LITERAL " " MD_BUILD_RELEASE_PHASE_STRING_LITERAL ") - " __DATE__ "" MD_BUILD_GIT_HASH_STRING_LITERAL_APPEND MD_BUILD_MODE_STRING_LITERAL_APPEND
#pragma endregion Build Options
@@ -76,83 +76,83 @@
#if defined( _MSC_VER )
# pragma message("Detected MSVC")
// # define COMPILER_CLANG 0
# define COMPILER_MSVC 1
// # define COMPILER_GCC 0
// # define MD_COMPILER_CLANG 0
# define MD_COMPILER_MSVC 1
// # define MD_COMPILER_GCC 0
# if _MSC_VER >= 1920
# define COMPILER_MSVC_YEAR 2019
# define MD_COMPILER_MSVC_YEAR 2019
# elif _MSC_VER >= 1910
# define COMPILER_MSVC_YEAR 2017
# define MD_COMPILER_MSVC_YEAR 2017
# elif _MSC_VER >= 1900
# define COMPILER_MSVC_YEAR 2015
# define MD_COMPILER_MSVC_YEAR 2015
# elif _MSC_VER >= 1800
# define COMPILER_MSVC_YEAR 2013
# define MD_COMPILER_MSVC_YEAR 2013
# elif _MSC_VER >= 1700
# define COMPILER_MSVC_YEAR 2012
# define MD_COMPILER_MSVC_YEAR 2012
# elif _MSC_VER >= 1600
# define COMPILER_MSVC_YEAR 2010
# define MD_COMPILER_MSVC_YEAR 2010
# elif _MSC_VER >= 1500
# define M_DCOMPILER_MSVC_YEAR 2008
# elif _MSC_VER >= 1400
# define COMPILER_MSVC_YEAR 2005
# define MD_COMPILER_MSVC_YEAR 2005
# else
# define COMPILER_MSVC_YEAR 0
# define MD_COMPILER_MSVC_YEAR 0
# endif
#elif defined( __GNUC__ )
# pragma message("Detected GCC")
// # define COMPILER_CLANG 0
// # define COMPILER_MSVC 0
# define COMPILER_GCC 1
// # define MD_COMPILER_CLANG 0
// # define MD_COMPILER_MSVC 0
# define MD_COMPILER_GCC 1
#elif defined( __clang__ )
# pragma message("Detected CLANG")
# define COMPILER_CLANG 1
// # define COMPILER_MSVC 0
// # define COMPILER_GCC 0
# define MD_COMPILER_CLANG 1
// # define MD_COMPILER_MSVC 0
// # define MD_COMPILER_GCC 0
#else
# error Unknown compiler
#endif
#if defined( __has_attribute )
# define HAS_ATTRIBUTE( attribute ) __has_attribute( attribute )
# define MD_HAS_ATTRIBUTE( attribute ) __has_attribute( attribute )
#else
# define HAS_ATTRIBUTE( attribute ) ( 0 )
# define MD_HAS_ATTRIBUTE( attribute ) ( 0 )
#endif
#if defined(GCC_VERSION_CHECK)
# undef GCC_VERSION_CHECK
#if defined(MD_GCC_VERSION_CHECK)
# undef MD_GCC_VERSION_CHECK
#endif
#if defined(GEN_GCC_VERSION)
# define GCC_VERSION_CHECK(major,minor,patch) (GEN_GCC_VERSION >= GEN_VERSION_ENCODE(major, minor, patch))
# define MD_GCC_VERSION_CHECK(major,minor,patch) (GEN_GCC_VERSION >= GEN_VERSION_ENCODE(major, minor, patch))
#else
# define GCC_VERSION_CHECK(major,minor,patch) (0)
# define MD_GCC_VERSION_CHECK(major,minor,patch) (0)
#endif
#pragma endregion Vendor
#pragma region Language
#if ! defined(LANG_C)
#if ! defined(MD_LANG_C)
# ifdef __cplusplus
# define LANG_C 0
# define LANG_CPP 1
# define MD_LANG_C 0
# define MD_LANG_CPP 1
# else
# if defined(__STDC__)
# define LANG_C 1
# define LANG_CPP 0
# define MD_LANG_C 1
# define MD_LANG_CPP 0
# else
// Fallback for very old C compilers
# define LANG_C 1
# define LANG_CPP 0
# define MD_LANG_C 1
# define MD_LANG_CPP 0
# endif
# endif
#endif
#if LANG_C
#if MD_LANG_C
# pragma message("MD: Detected C")
#endif
#if LANG_CPP
#if MD_LANG_CPP
# pragma message("MD: Detected CPP")
#endif
@@ -160,56 +160,56 @@
#pragma region Hardware Architecture
#if COMPILER_CLANG
#if MD_COMPILER_CLANG
# if defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64)
# define ARCH_X64 1
# define MD_ARCH_X64 1
# elif defined(i386) || defined(__i386) || defined(__i386__)
# define ARCH_X86 1
# define MD_ARCH_X86 1
# elif defined(__aarch64__)
# define ARCH_ARM64 1
# define MD_ARCH_ARM64 1
# elif defined(__arm__)
# define ARCH_ARM32 1
# define MD_ARCH_ARM32 1
# else
# error Architecture not supported.
# endif
#endif // COMPILER_CLANG
#endif // MD_COMPILER_CLANG
#if COMPILER_MSVC
#if MD_COMPILER_MSVC
# if defined(_M_AMD64)
# define ARCH_X64 1
# define MD_ARCH_X64 1
# elif defined(_M_IX86)
# define ARCH_X86 1
# define MD_ARCH_X86 1
# elif defined(_M_ARM64)
# define ARCH_ARM64 1
# define MD_ARCH_ARM64 1
# elif defined(_M_ARM)
# define ARCH_ARM32 1
# define MD_ARCH_ARM32 1
# else
# error Architecture not supported.
# endif
#endif // COMPILER_MSVC
#endif // MD_COMPILER_MSVC
#if COMPILER_GCC
#if MD_COMPILER_GCC
# if defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64)
# define ARCH_X64 1
# define MD_ARCH_X64 1
# elif defined(i386) || defined(__i386) || defined(__i386__)
# define ARCH_X86 1
# define MD_ARCH_X86 1
# elif defined(__aarch64__)
# define ARCH_ARM64 1
# define MD_ARCH_ARM64 1
# elif defined(__arm__)
# define ARCH_ARM32 1
# define MD_ARCH_ARM32 1
# else
# error Architecture not supported.
# endif
#endif // COMPILER_GCC
#endif // MD_COMPILER_GCC
#if defined(ARCH_X64)
# define ARCH_64BIT 1
#elif defined(ARCH_X86)
# define ARCH_32BIT 1
#if defined(MD_ARCH_X64)
# define MD_ARCH_64BIT 1
#elif defined(MD_ARCH_X86)
# define MD_ARCH_32BIT 1
#endif
#if ARCH_ARM32 || ARCH_ARM64 || ARCH_X64 || ARCH_X86
# define ARCH_LITTLE_ENDIAN 1
#if MD_ARCH_ARM32 || MD_ARCH_ARM64 || MD_ARCH_X64 || MD_ARCH_X86
# define MD_ARCH_LITTLE_ENDIAN 1
#else
# error Endianness of this architecture not understood by context cracker.
#endif
@@ -219,46 +219,46 @@
#pragma region Operating System
#if defined( _WIN32 ) || defined( _WIN64 )
# ifndef OS_WINDOWS
# define OS_WINDOWS 1
# ifndef MD_OS_WINDOWS
# define MD_OS_WINDOWS 1
# endif
#elif defined( __APPLE__ ) && defined( __MACH__ )
# ifndef OS_OSX
# define OS_OSX 1
# ifndef MD_OS_OSX
# define MD_OS_OSX 1
# endif
# ifndef OS_MACOS
# define OS_MACOS 1
# ifndef MD_OS_MACOS
# define MD_OS_MACOS 1
# endif
#elif defined( __unix__ )
# ifndef OS_UNIX
# define OS_UNIX 1
# ifndef MD_OS_UNIX
# define MD_OS_UNIX 1
# endif
# if defined( ANDROID ) || defined( __ANDROID__ )
# ifndef OS_ANDROID
# define OS_ANDROID 1
# ifndef MD_OS_ANDROID
# define MD_OS_ANDROID 1
# endif
# ifndef OS_LINUX
# define OS_LINUX 1
# ifndef MD_OS_LINUX
# define MD_OS_LINUX 1
# endif
# elif defined( __linux__ )
# ifndef OS_LINUX
# define OS_LINUX 1
# ifndef MD_OS_LINUX
# define MD_OS_LINUX 1
# endif
# elif defined( __FreeBSD__ ) || defined( __FreeBSD_kernel__ )
# ifndef OS_FREEBSD
# define OS_FREEBSD 1
# ifndef MD_OS_FREEBSD
# define MD_OS_FREEBSD 1
# endif
# elif defined( __OpenBSD__ )
# ifndef OS_OPENBSD
# define OS_OPENBSD 1
# ifndef MD_OS_OPENBSD
# define MD_OS_OPENBSD 1
# endif
# elif defined( __EMSCRIPTEN__ )
# ifndef OS_EMSCRIPTEN
# define OS_EMSCRIPTEN 1
# ifndef MD_OS_EMSCRIPTEN
# define MD_OS_EMSCRIPTEN 1
# endif
# elif defined( __CYGWIN__ )
# ifndef OS_CYGWIN
# define OS_CYGWIN 1
# ifndef MD_OS_CYGWIN
# define MD_OS_CYGWIN 1
# endif
# else
# error This UNIX operating system is not supported
@@ -272,55 +272,55 @@
////////////////////////////////
//~ rjf: Zero All Undefined Options
#if !defined(ARCH_32BIT)
# define ARCH_32BIT 0
#if !defined(MD_ARCH_32BIT)
# define MD_ARCH_32BIT 0
#endif
#if !defined(ARCH_64BIT)
# define ARCH_64BIT 0
#if !defined(MD_ARCH_64BIT)
# define MD_ARCH_64BIT 0
#endif
#if !defined(ARCH_X64)
# define ARCH_X64 0
#if !defined(MD_ARCH_X64)
# define MD_ARCH_X64 0
#endif
#if !defined(ARCH_X86)
# define ARCH_X86 0
#if !defined(MD_ARCH_X86)
# define MD_ARCH_X86 0
#endif
#if !defined(ARCH_ARM64)
# define ARCH_ARM64 0
#if !defined(MD_ARCH_ARM64)
# define MD_ARCH_ARM64 0
#endif
#if !defined(ARCH_ARM32)
# define ARCH_ARM32 0
#if !defined(MD_ARCH_ARM32)
# define MD_ARCH_ARM32 0
#endif
#if !defined(COMPILER_MSVC)
# define COMPILER_MSVC 0
#if !defined(MD_COMPILER_MSVC)
# define MD_COMPILER_MSVC 0
#endif
#if !defined(COMPILER_GCC)
# define COMPILER_GCC 0
#if !defined(MD_COMPILER_GCC)
# define MD_COMPILER_GCC 0
#endif
#if !defined(COMPILER_CLANG)
# define COMPILER_CLANG 0
#if !defined(MD_COMPILER_CLANG)
# define MD_COMPILER_CLANG 0
#endif
#if !defined(OS_WINDOWS)
# define OS_WINDOWS 0
#if !defined(MD_OS_WINDOWS)
# define MD_OS_WINDOWS 0
#endif
#if !defined(OS_LINUX)
# define OS_LINUX 0
#if !defined(MD_OS_LINUX)
# define MD_OS_LINUX 0
#endif
#if !defined(OS_MAC)
# define OS_MAC 0
#if !defined(MD_OS_MAC)
# define MD_OS_MAC 0
#endif
#if !defined(LANG_CPP)
# define LANG_CPP 0
#if !defined(MD_LANG_CPP)
# define MD_LANG_CPP 0
#endif
#if !defined(LANG_C)
# define LANG_C 0
#if !defined(MD_LANG_C)
# define MD_LANG_C 0
#endif
////////////////////////////////
//~ rjf: Unsupported Errors
#if ARCH_X86
#if MD_ARCH_X86
# error You tried to build in x86 (32 bit) mode, but currently, only building in x64 (64 bit) mode is supported.
#endif
#if ! ARCH_X64
#if ! MD_ARCH_X64
# error You tried to build with an unsupported architecture. Currently, only building in x64 mode is supported.
#endif
+1 -1
View File
@@ -7,7 +7,7 @@
#define md__printf_err( fmt, ... ) fprintf( stderr, fmt, __VA_ARGS__ )
#define md__printf_err_va( fmt, va ) vfprintf( stderr, fmt, va )
void assert_handler( char const* condition, char const* file, char const* function, S32 line, char const* msg, ... )
void md_assert_handler( char const* condition, char const* file, char const* function, MD_S32 line, char const* msg, ... )
{
md__printf_err( "%s - %s:(%d): Assert Failure: ", file, function, line );
+24 -24
View File
@@ -11,53 +11,53 @@
////////////////////////////////
//~ rjf: Asserts
#ifndef trap
# if COMPILER_MSVC
#ifndef md_trap
# if MD_COMPILER_MSVC
# if _MSC_VER < 1300
# define trap() __asm int 3 /* Trap to debugger! */
# define md_trap() __asm int 3 /* Trap to debugger! */
# else
# define trap() __debugbreak()
# define md_trap() __debugbreak()
# endif
# elif COMPILER_CLANG || COMPILER_GCC
# define trap() __builtin_trap()
# elif MD_COMPILER_CLANG || MD_COMPILER_GCC
# define md_trap() __builtin_trap()
# else
# error Unknown trap intrinsic for this compiler.
# error Unknown md_trap intrinsic for this compiler.
# endif
#endif
#define assert_msg( cond, msg, ... ) \
#define md_assert_msg( cond, msg, ... ) \
do \
{ \
if ( ! ( cond ) ) \
{ \
assert_handler( #cond, __FILE__, __func__, scast( S64, __LINE__ ), msg, ##__VA_ARGS__ ); \
trap(); \
md_assert_handler( #cond, __FILE__, __func__, md_scast( MD_S64, __LINE__ ), msg, ##__VA_ARGS__ ); \
md_trap(); \
} \
} while ( 0 )
#ifndef assert_always
#define assert_always(x) do { if ( !(x) ) { trap(); } } while(0)
#ifndef md_assert_always
#define md_assert_always(x) do { if ( !(x) ) { md_trap(); } } while(0)
#endif
#ifndef assert
# if BUILD_DEBUG
# define assert(x) assert_always(x)
#ifndef md_assert
# if MD_BUILD_DEBUG
# define md_assert(x) md_assert_always(x)
# else
# define assert(x) (void)(x)
# define md_assert(x) (void)(x)
# endif
#endif
#ifndef invalid_path
#define invalid_path assert( ! "Invalid Path!")
#ifndef md_invalid_path
#define md_invalid_path md_assert( ! "Invalid Path!")
#endif
#ifndef not_implemented
#define not_implemented assert( ! "Not Implemented!")
#ifndef md_not_implemented
#define md_not_implemented md_assert( ! "Not Implemented!")
#endif
#ifndef no_op
#define no_op ((void)0)
#ifndef md_no_op
#define md_no_op ((void)0)
#endif
#ifndef md_static_assert
#define md_static_assert(C, ID) global U8 glue(ID, __LINE__)[ (C) ? 1 : -1 ]
#define md_static_assert(C, ID) md_global MD_U8 md_glue(ID, __LINE__)[ (C) ? 1 : -1 ]
#endif
MD_API void assert_handler( char const* condition, char const* file, char const* function, S32 line, char const* msg, ... );
MD_API void md_assert_handler( char const* condition, char const* file, char const* function, MD_S32 line, char const* msg, ... );
+16 -16
View File
@@ -9,39 +9,39 @@
// Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
void main_thread_base_entry_point(MainThread_EntryPointProc* entry_point, char** arguments, U64 arguments_count)
void md_main_thread_base_entry_point(MD_MainThread_EntryPointProc* md_entry_point, char** arguments, MD_U64 arguments_count)
{
#if PROFILE_TELEMETRY
local_persist U8 tm_data[MB(64)];
#if MD_PROFILE_TELEMETRY
md_local_persist MD_U8 tm_data[MD_MB(64)];
tmLoadLibrary(TM_RELEASE);
tmSetMaxThreadCount(256);
tmInitialize(sizeof(tm_data), (char *)tm_data);
#endif
thread_namef("[main thread]");
md_thread_namef("[main thread]");
TempArena scratch = scratch_begin(0, 0);
MD_TempArena scratch = md_scratch_begin(0, 0);
String8List command_line_argument_strings = os_string_list_from_argcv(scratch.arena, (int)arguments_count, arguments);
CmdLine cmdline = cmd_line_from_string_list(scratch.arena, command_line_argument_strings);
B32 capture = cmd_line_has_flag(&cmdline, str8_lit("capture"));
MD_String8List command_line_argument_strings = md_os_string_list_from_argcv(scratch.arena, (int)arguments_count, arguments);
MD_CmdLine cmdline = md_cmd_line_from_string_list(scratch.arena, command_line_argument_strings);
MD_B32 capture = md_cmd_line_has_flag(&cmdline, md_str8_lit("capture"));
if (capture) {
prof_begin_capture(arguments[0]);
md_prof_begin_capture(arguments[0]);
}
entry_point(&cmdline);
md_entry_point(&cmdline);
if (capture) {
prof_end_capture();
md_prof_end_capture();
}
scratch_end(scratch);
}
void
supplement_thread_base_entry_point(SupplementThread_EntryPointProc* entry_point, void* params)
md_supplement_thread_base_entry_point(MD_SupplementThread_EntryPointProc* md_entry_point, void* params)
{
TCTX tctx;
tctx_init_and_equip(&tctx);
entry_point(params);
tctx_release();
MD_TCTX md_tctx;
md_tctx_init_and_equip(&md_tctx);
md_entry_point(params);
md_tctx_release();
}
+4 -4
View File
@@ -8,8 +8,8 @@
// Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
typedef void (MainThread_EntryPointProc) (CmdLine* cmd_line);
typedef void (SupplementThread_EntryPointProc)(void* params);
typedef void (MD_MainThread_EntryPointProc) (MD_CmdLine* cmd_line);
typedef void (MD_SupplementThread_EntryPointProc)(void* params);
MD_API void main_thread_base_entry_point (MainThread_EntryPointProc* entry_point, char** arguments, U64 arguments_count);
MD_API void supplement_thread_base_entry_point(SupplementThread_EntryPointProc* entry_point, void* params);
MD_API void md_main_thread_base_entry_point (MD_MainThread_EntryPointProc* md_entry_point, char** arguments, MD_U64 arguments_count);
MD_API void md_supplement_thread_base_entry_point(MD_SupplementThread_EntryPointProc* md_entry_point, void* params);
+8 -8
View File
@@ -7,17 +7,17 @@
////////////////////////////////
//~ allen: Files
typedef U32 FilePropertyFlags;
typedef MD_U32 MD_FilePropertyFlags;
enum
{
FilePropertyFlag_IsFolder = (1 << 0),
MD_FilePropertyFlag_IsFolder = (1 << 0),
};
typedef struct FileProperties FileProperties;
struct FileProperties
typedef struct MD_FileProperties MD_FileProperties;
struct MD_FileProperties
{
U64 size;
DenseTime modified;
DenseTime created;
FilePropertyFlags flags;
MD_U64 size;
MD_DenseTime modified;
MD_DenseTime created;
MD_FilePropertyFlags flags;
};
+63 -65
View File
@@ -1,7 +1,5 @@
#ifdef INTELLISENSE_DIRECTIVES
# pragma once
// NOTE(Ed): For C++ generation, this file will not be injected, any macros that are used will either be injected as transparent defines
// or have their usage removed during the library generation pass.
#endif
// ____ _ ______ _ _ ____ _ __ _
@@ -19,42 +17,42 @@
// Additional info: https://www.chiark.greenend.org.uk/~sgtatham/quasiblog/c11-generic/
// --------------------------------------------------------------------------------------------------------------------------------------------
#ifndef COMMA_OPERATOR
#define COMMA_OPERATOR , // The comma operator is used by preprocessor macros to delimit arguments, so we have to represent it via a macro to prevent parsing incorrectly.
#ifndef MD_COMMA_OPERATOR
#define MD_COMMA_OPERATOR , // The comma operator is used by preprocessor macros to delimit arguments, so we have to represent it via a macro to prevent parsing incorrectly.
#endif
// Helper macros for argument selection
#ifndef select_arg_1
#define select_arg_1( _1, ... ) _1 // <-- Of all th args passed pick _1.
#define select_arg_2( _1, _2, ... ) _2 // <-- Of all the args passed pick _2.
#define select_arg_3( _1, _2, _3, ... ) _3 // etc..
#ifndef md_select_arg_1
#define md_select_arg_1( _1, ... ) _1 // <-- Of all th args passed pick _1.
#define md_select_arg_2( _1, _2, ... ) _2 // <-- Of all the args passed pick _2.
#define md_select_arg_3( _1, _2, _3, ... ) _3 // etc..
#define generic_sel_entry_type select_arg_1 // Use the arg expansion macro to select arg 1 which should have the type.
#define generic_sel_entry_function select_arg_2 // Use the arg expansion macro to select arg 2 which should have the function.
#define generic_sel_entry_comma_delimiter select_arg_3 // Use the arg expansion macro to select arg 3 which should have the comma delimiter ','.
#define md_generic_sel_entry_type md_select_arg_1 // Use the arg expansion macro to select arg 1 which should have the type.
#define md_generic_sel_entry_function md_select_arg_2 // Use the arg expansion macro to select arg 2 which should have the function.
#define md_generic_sel_entry_comma_delimiter md_select_arg_3 // Use the arg expansion macro to select arg 3 which should have the comma delimiter ','.
#endif
#ifndef generic_call
#define generic_call // Just used to indicate where the call "occurs"
#ifndef md_generic_call
#define md_generic_call // Just used to indicate where the call "occurs"
#endif
// ----------------------------------------------------------------------------------------------------------------------------------
#ifndef if_generic_selector_defined_include_slot
// if_generic_selector_defined_include_slot( macro ) includes a _Generic slot only if the specified macro is defined (as type, function_name).
#ifndef md_if_generic_selector_defined_include_slot
// md_if_generic_selector_defined_include_slot( macro ) includes a _Generic slot only if the specified macro is defined (as type, function_name).
// It takes advantage of the fact that if the macro is defined, then the expanded text will contain a comma.
// Expands to ',' if it can find (type): (function) <comma_operator: ',' >
// Where generic_sel_entry_comma_delimiter is specifically looking for that <comma> ,
#define if_generic_selector_defined_include_slot( slot_exp ) generic_sel_entry_comma_delimiter( slot_exp, generic_sel_entry_type( slot_exp, ): generic_sel_entry_function( slot_exp, ) COMMA_OPERATOR, , )
// Where md_generic_sel_entry_comma_delimiter is specifically looking for that <comma> ,
#define md_if_generic_selector_defined_include_slot( slot_exp ) md_generic_sel_entry_comma_delimiter( slot_exp, md_generic_sel_entry_type( slot_exp, ): md_generic_sel_entry_function( slot_exp, ) MD_COMMA_OPERATOR, , )
// ^ Selects the comma ^ is the type ^ is the function ^ Insert a comma
// The slot won't exist if that comma is not found.
#endif
// For the occastion where an expression didn't resolve to a selection option the "default: <value>" will be set to:
typedef struct UNRESOLVED_GENERIC_SELECTION UNRESOLVED_GENERIC_SELECTION;
struct UNRESOLVED_GENERIC_SELECTION {
typedef struct MD_UNRESOLVED_GENERIC_SELECTION MD_UNRESOLVED_GENERIC_SELECTION;
struct MD_UNRESOLVED_GENERIC_SELECTION {
void* _THE_VOID_SLOT_;
};
UNRESOLVED_GENERIC_SELECTION const assert_generic_sel_fail = {0};
MD_UNRESOLVED_GENERIC_SELECTION const md_assert_generic_sel_fail = {0};
// Which will provide the message: error: called object type 'struct NO_RESOLVED_GENERIC_SELECTION' is not a function or function pointer
// ----------------------------------------------------------------------------------------------------------------------------------
@@ -63,10 +61,10 @@ UNRESOLVED_GENERIC_SELECTION const assert_generic_sel_fail = {0};
#define function_generic_example( selector_arg ) _Generic( \
(selector_arg), /* Select Via Expression*/ \
/* Extendibility slots: */ \
if_generic_selector_defined_include_slot( GENERIC_SLOT_1__function_sig ) \
if_generic_selector_defined_include_slot( GENERIC_SLOT_2__function_sig ) \
default: assert_generic_sel_fail \
) generic_call( selector_arg )
md_if_generic_selector_defined_include_slot( MD_GENERIC_SLOT_1__function_sig ) \
md_if_generic_selector_defined_include_slot( GENERIC_SLOT_2__function_sig ) \
default: md_assert_generic_sel_fail \
) md_generic_call( selector_arg )
// ----------------------------------------------------------------------------------------------------------------------------------
// Then each definiton of a function has an associated define:
@@ -78,56 +76,56 @@ UNRESOLVED_GENERIC_SELECTION const assert_generic_sel_fail = {0};
// Concrete example:
// To add support for long:
#define GENERIC_SLOT_1__example_hash long, generic_example_hash__P_long
size_t generic_example_hash__P_long( long val ) { return val * 2654435761ull; }
#define MD_GENERIC_SLOT_1__example_hash long, md_generic_example_hash__P_long
size_t md_generic_example_hash__P_long( long val ) { return val * 2654435761ull; }
// To add support for long long:
#define GENERIC_SLOT_2__example_hash long long, generic_example_hash__P_long_long
size_t generic_example_hash__P_long_long( long long val ) { return val * 2654435761ull; }
#define GENERIC_SLOT_2__example_hash long long, md_generic_example_hash__P_long_long
size_t md_generic_example_hash__P_long_long( long long val ) { return val * 2654435761ull; }
// If using an Editor with support for syntax hightlighting macros:
// GENERIC_SLOT_1__example_hash and GENERIC_SLOT_2__example_hash should show color highlighting indicating the slot is enabled,
// MD_GENERIC_SLOT_1__example_hash and GENERIC_SLOT_2__example_hash should show color highlighting indicating the slot is enabled,
// or, "defined" for usage during the compilation pass that handles the _Generic instrinsic.
#define generic_example_hash( function_arguments ) _Generic( \
(function_arguments), /* Select Via Expression*/ \
/* Extendibility slots: */ \
if_generic_selector_defined_include_slot( GENERIC_SLOT_1__example_hash ) \
if_generic_selector_defined_include_slot( GENERIC_SLOT_2__example_hash ) \
if_generic_selector_defined_include_slot( GENERIC_SLOT_3__example_hash ) \
if_generic_selector_defined_include_slot( GENERIC_SLOT_4__example_hash ) \
if_generic_selector_defined_include_slot( GENERIC_SLOT_5__example_hash ) \
if_generic_selector_defined_include_slot( GENERIC_SLOT_6__example_hash ) \
if_generic_selector_defined_include_slot( GENERIC_SLOT_7__example_hash ) \
if_generic_selector_defined_include_slot( GENERIC_SLOT_8__example_hash ) \
default: assert_generic_sel_fail \
) generic_call( function_arguments )
md_if_generic_selector_defined_include_slot( MD_GENERIC_SLOT_1__example_hash ) \
md_if_generic_selector_defined_include_slot( GENERIC_SLOT_2__example_hash ) \
md_if_generic_selector_defined_include_slot( GENERIC_SLOT_3__example_hash ) \
md_if_generic_selector_defined_include_slot( GENERIC_SLOT_4__example_hash ) \
md_if_generic_selector_defined_include_slot( GENERIC_SLOT_5__example_hash ) \
md_if_generic_selector_defined_include_slot( GENERIC_SLOT_6__example_hash ) \
md_if_generic_selector_defined_include_slot( GENERIC_SLOT_7__example_hash ) \
md_if_generic_selector_defined_include_slot( GENERIC_SLOT_8__example_hash ) \
default: md_assert_generic_sel_fail \
) md_generic_call( function_arguments )
// Additional Variations:
// If the function takes more than one argument the following is used:
#define function_generic_example_varadic( selector_arg, ... ) _Generic( \
#define md_function_generic_example_varadic( selector_arg, ... ) _Generic( \
(selector_arg), \
if_generic_selector_defined_include_slot( GENERIC_SLOT_1__function_sig ) \
if_generic_selector_defined_include_slot( GENERIC_SLOT_2__function_sig ) \
md_if_generic_selector_defined_include_slot( MD_GENERIC_SLOT_1__function_sig ) \
md_if_generic_selector_defined_include_slot( GENERIC_SLOT_2__function_sig ) \
/* ... */ \
if_generic_selector_defined_include_slot(GENERIC_SLOT_N__function_sig ) \
default: assert_generic_sel_fail \
) generic_call( selector_arg, __VA_ARG__ )
md_if_generic_selector_defined_include_slot(GENERIC_SLOT_N__function_sig ) \
default: md_assert_generic_sel_fail \
) md_generic_call( selector_arg, __VA_ARG__ )
// If the function does not take the arugment as a parameter:
#define function_generic_example_direct_type( selector_arg ) _Generic( \
( type_to_expression(selector_arg) ), \
if_generic_selector_defined_include_slot( GENERIC_SLOT_1__function_sig ) \
if_generic_selector_defined_include_slot( GENERIC_SLOT_2__function_sig ) \
#define md_function_generic_example_direct_type( selector_arg ) _Generic( \
( md_type_to_expression(selector_arg) ), \
md_if_generic_selector_defined_include_slot( MD_GENERIC_SLOT_1__function_sig ) \
md_if_generic_selector_defined_include_slot( GENERIC_SLOT_2__function_sig ) \
/* ... */ \
if_generic_selector_defined_include_slot(GENERIC_SLOT_N__function_sig ) \
default: assert_generic_sel_fail \
) generic_call(selector_arg)
md_if_generic_selector_defined_include_slot(GENERIC_SLOT_N__function_sig ) \
default: md_assert_generic_sel_fail \
) md_generic_call(selector_arg)
#ifndef type_to_expression
#ifndef md_type_to_expression
// Used to keep the _Generic keyword happy as bare types are not considered "expressions"
#define type_to_expression(type) (* (type*)NULL)
#define md_type_to_expression(type) (* (type*)NULL)
// Instead of using this macro, it should be directly expanded by code generation.
#endif
@@ -136,14 +134,14 @@ size_t generic_example_hash__P_long_long( long long val ) { return val * 2654435
#define example_with__l2(expr) _Generic( \
(expr), \
S64 : example_with_s64, \
default: assert_generic_sel_fail \
MD_S64 : example_with_s64, \
default: md_assert_generic_sel_fail \
)
#define example_with(expr) \
_Generic((expr), \
SSIZE : example_with_SSIZEZ \
MD_SSIZE : example_with_SSIZEZ \
default : example_with_not_SSIZE(allocator, in) \
) generic_call(allocator, in)
) md_generic_call(allocator, in)
// This can be made more concise with he following "layer" indicating _Generic macros
@@ -152,21 +150,21 @@ _Generic((expr), \
#define example_with_generic_layers(expr) \
_Generic( (expr), \
S64 : example_with_s64, \
MD_S64 : example_with_s64, \
_Generic_L2((expr), \
SSIZE: example_with_SSIZZE \
default: assert_generic_sel_fail \
MD_SSIZE: example_with_SSIZZE \
default: md_assert_generic_sel_fail \
), \
) generic_call(expr)
) md_generic_call(expr)
// Removing example definitions
#undef example_with
#undef example_with__l2
#undef example_with_generic_layers
#undef function_generic_example
#undef GENERIC_SLOT_1__example_hash
#undef MD_GENERIC_SLOT_1__example_hash
#undef GENERIC_SLOT_2__example_hash
#undef generic_example_hash
#undef function_generic_example_varadic
#undef function_generic_example_direct_type
#undef md_function_generic_example_varadic
#undef md_function_generic_example_direct_type
#undef generic_example_do_something_with
+11 -11
View File
@@ -4,9 +4,9 @@
#endif
#ifndef MD_API
#if COMPILER_MSVC
# if BUILD_DYANMIC
# if BUILD_API_EXPORT
#if MD_COMPILER_MSVC
# if MD_BUILD_DYANMIC
# if MD_BUILD_API_EXPORT
# define MD_API __declspec(dllexport)
# else
# define MD_API __declspec(dllimport)
@@ -15,7 +15,7 @@
# define MD_API // Empty for static builds
# endif
#else
# ifdef BUILD_DYANMIC
# ifdef MD_BUILD_DYANMIC
# define MD_API __attribute__((visibility("default")))
# else
# define MD_API // Empty for static builds
@@ -24,7 +24,7 @@
#endif // GEN_API
#ifndef MD_API_C_BEGIN
# if LANG_C
# if MD_LANG_C
# define MD_API_C_BEGIN
# define MD_API_C_END
# define MD_API_C
@@ -35,15 +35,15 @@
# endif
#endif
#ifndef global // Global variables
# if BUILD_API_EXPORT || BUILD_STATIC
# define global
#ifndef md_global // Global variables
# if MD_BUILD_API_EXPORT || MD_BUILD_STATIC
# define md_global
# else
# define global static
# define md_global static
# endif
#endif
// Internal Linkage
#ifndef internal
#define internal static
#ifndef md_internal
#define md_internal static
#endif
+34 -34
View File
@@ -9,40 +9,40 @@
////////////////////////////////
//~ rjf: Globals/Thread-Locals
MD_API_C thread_static Log* log_active;
#if !BUILD_SUPPLEMENTARY_UNIT
MD_API_C thread_static Log* log_active = 0;
MD_API_C md_thread_static MD_Log* md_log_active;
#if !MD_BUILD_SUPPLEMENTARY_UNIT
MD_API_C md_thread_static MD_Log* md_log_active = 0;
#endif
////////////////////////////////
//~ rjf: Log Creation/Selection
//~ rjf: MD_Log Creation/Selection
void
log_select(Log* log) {
log_active = log;
md_log_select(MD_Log* log) {
md_log_active = log;
}
////////////////////////////////
//~ rjf: Log Building
//~ rjf: MD_Log Building
void
log_msg(LogMsgKind kind, String8 string) {
if(log_active != 0 && log_active->top_scope != 0) {
String8 string_copy = str8_copy(log_active->arena, string);
str8_list_push(log_active->arena, &log_active->top_scope->strings[kind], string_copy);
md_log_msg(MD_LogMsgKind kind, MD_String8 string) {
if(md_log_active != 0 && md_log_active->top_scope != 0) {
MD_String8 md_string_copy = md_str8_copy(md_log_active->arena, string);
md_str8_list_push(md_log_active->arena, &md_log_active->top_scope->strings[kind], md_string_copy);
}
}
void
log_msgf(LogMsgKind kind, char *fmt, ...) {
if(log_active != 0)
md_log_msgf(MD_LogMsgKind kind, char *fmt, ...) {
if(md_log_active != 0)
{
TempArena scratch = scratch_begin(0, 0);
MD_TempArena scratch = md_scratch_begin(0, 0);
va_list args;
va_start(args, fmt);
String8 string = str8fv(scratch.arena, fmt, args);
log_msg(kind, string);
MD_String8 string = md_str8fv(scratch.arena, fmt, args);
md_log_msg(kind, string);
va_end(args);
scratch_end(scratch);
@@ -50,39 +50,39 @@ log_msgf(LogMsgKind kind, char *fmt, ...) {
}
////////////////////////////////
//~ rjf: Log Scopes
//~ rjf: MD_Log Scopes
void
log_scope_begin(void) {
if (log_active != 0) {
U64 pos = arena_pos(log_active->arena);
LogScope* scope = push_array(log_active->arena, LogScope, 1);
md_log_scope_begin(void) {
if (md_log_active != 0) {
MD_U64 pos = md_arena_pos(md_log_active->arena);
MD_LogScope* scope = md_push_array_(md_log_active->arena, MD_LogScope, 1);
scope->pos = pos;
sll_stack_push(log_active->top_scope, scope);
md_sll_stack_push(md_log_active->top_scope, scope);
}
}
LogScopeResult
log_scope_end(Arena *arena)
MD_LogScopeResult
md_log_scope_end(MD_Arena *arena)
{
LogScopeResult result = {0};
if(log_active != 0)
MD_LogScopeResult result = {0};
if(md_log_active != 0)
{
LogScope* scope = log_active->top_scope;
MD_LogScope* scope = md_log_active->top_scope;
if(scope != 0)
{
sll_stack_pop(log_active->top_scope);
md_sll_stack_pop(md_log_active->top_scope);
if(arena != 0)
{
for (each_enum_val(LogMsgKind, kind)) {
TempArena scratch = scratch_begin(&arena, 1);
String8
result_unindented = str8_list_join(scratch.arena, &scope->strings[kind], 0);
result.strings[kind] = indented_from_string(arena, result_unindented);
for (md_each_enum_val(MD_LogMsgKind, kind)) {
MD_TempArena scratch = md_scratch_begin(&arena, 1);
MD_String8
result_unindented = md_str8_list_join(scratch.arena, &scope->strings[kind], 0);
result.strings[kind] = md_indented_from_string(arena, result_unindented);
scratch_end(scratch);
}
}
arena_pop_to(log_active->arena, scope->pos);
md_arena_pop_to(md_log_active->arena, scope->pos);
}
}
return result;
+43 -43
View File
@@ -10,77 +10,77 @@
// Licensed under the MIT license (https://opensource.org/license/mit/)
////////////////////////////////
//~ rjf: Log Types
//~ rjf: MD_Log Types
typedef enum LogMsgKind LogMsgKind;
enum LogMsgKind
typedef enum MD_LogMsgKind MD_LogMsgKind;
enum MD_LogMsgKind
{
LogMsgKind_Info,
LogMsgKind_UserError,
LogMsgKind_COUNT
MD_LogMsgKind_Info,
MD_LogMsgKind_UserError,
MD_LogMsgKind_COUNT
};
typedef struct LogScope LogScope;
struct LogScope
typedef struct MD_LogScope MD_LogScope;
struct MD_LogScope
{
LogScope* next;
U64 pos;
String8List strings[LogMsgKind_COUNT];
MD_LogScope* next;
MD_U64 pos;
MD_String8List strings[MD_LogMsgKind_COUNT];
};
typedef struct LogScopeResult LogScopeResult;
struct LogScopeResult
typedef struct MD_LogScopeResult MD_LogScopeResult;
struct MD_LogScopeResult
{
String8 strings[LogMsgKind_COUNT];
MD_String8 strings[MD_LogMsgKind_COUNT];
};
typedef struct Log Log;
struct Log
typedef struct MD_Log MD_Log;
struct MD_Log
{
Arena* arena;
LogScope* top_scope;
MD_Arena* arena;
MD_LogScope* top_scope;
};
#ifndef LOG_DEFAULT_ARENA_BLOCK_SIZE
#define LOG_DEFAULT_ARENA_BLOCK_SIZE VARENA_DEFAULT_RESERVE
#ifndef MD_LOG_DEFAULT_ARENA_BLOCK_SIZE
#define MD_LOG_DEFAULT_ARENA_BLOCK_SIZE MD_VARENA_DEFAULT_RESERVE
#endif
////////////////////////////////
//~ rjf: Log Creation/Selection
//~ rjf: MD_Log Creation/Selection
Log* log_alloc(AllocatorInfo ainfo, U64 arena_block_size);
void log_release(Log* log);
MD_API void log_select (Log* log);
MD_Log* md_log_alloc(MD_AllocatorInfo ainfo, MD_U64 md_arena_block_size);
void md_log_release(MD_Log* log);
MD_API void md_log_select (MD_Log* log);
inline Log*
log_alloc(AllocatorInfo ainfo, U64 arena_block_size) {
if (arena_block_size == 0) {
arena_block_size = LOG_DEFAULT_ARENA_BLOCK_SIZE;
inline MD_Log*
md_log_alloc(MD_AllocatorInfo ainfo, MD_U64 md_arena_block_size) {
if (md_arena_block_size == 0) {
md_arena_block_size = MD_LOG_DEFAULT_ARENA_BLOCK_SIZE;
}
Arena* arena = arena_alloc(.backing = ainfo, .block_size = arena_block_size);
Log* log = push_array(arena, Log, 1);
MD_Arena* arena = md_arena_alloc(.backing = ainfo, .block_size = md_arena_block_size);
MD_Log* log = md_push_array_(arena, MD_Log, 1);
log->arena = arena;
return log;
}
inline void log_release(Log* log) { arena_release(log->arena); }
inline void md_log_release(MD_Log* log) { md_arena_release(log->arena); }
////////////////////////////////
//~ rjf: Log Building
//~ rjf: MD_Log Building
MD_API void log_msg (LogMsgKind kind, String8 string);
MD_API void log_msgf(LogMsgKind kind, char* fmt, ...);
MD_API void md_log_msg (MD_LogMsgKind kind, MD_String8 string);
MD_API void md_log_msgf(MD_LogMsgKind kind, char* fmt, ...);
#define log_info(s) log_msg (LogMsgKind_Info, (s))
#define log_infof(fmt, ...) log_msgf(LogMsgKind_Info, (fmt), __VA_ARGS__)
#define log_user_error(s) log_msg (LogMsgKind_UserError, (s))
#define log_user_errorf(fmt, ...) log_msgf(LogMsgKind_UserError, (fmt), __VA_ARGS__)
#define md_log_info(s) md_log_msg (MD_LogMsgKind_Info, (s))
#define md_log_infof(fmt, ...) md_log_msgf(MD_LogMsgKind_Info, (fmt), __VA_ARGS__)
#define md_log_user_error(s) md_log_msg (MD_LogMsgKind_UserError, (s))
#define md_log_user_errorf(fmt, ...) md_log_msgf(MD_LogMsgKind_UserError, (fmt), __VA_ARGS__)
#define log_info_named_block(s) defer_loop(log_infof("%S:\n{\n", (s)), log_infof("}\n"))
#define log_info_named_blockf(fmt, ...) defer_loop((log_infof(fmt, __VA_ARGS__), log_infof(":\n{\n")), log_infof("}\n"))
#define md_log_info_named_block(s) md_defer_loop(md_log_infof("%S:\n{\n", (s)), md_log_infof("}\n"))
#define md_log_info_named_blockf(fmt, ...) md_defer_loop((md_log_infof(fmt, __VA_ARGS__), md_log_infof(":\n{\n")), md_log_infof("}\n"))
////////////////////////////////
//~ rjf: Log Scopes
//~ rjf: MD_Log Scopes
void log_scope_begin(void);
MD_API LogScopeResult log_scope_end(Arena* arena);
void md_log_scope_begin(void);
MD_API MD_LogScopeResult md_log_scope_end(MD_Arena* arena);
+79 -79
View File
@@ -7,71 +7,71 @@
////////////////////////////////
//~ rjf: Branch Predictor Hints
#if COMPILER_CLANG
# define expect(expr, val) __builtin_expect((expr), (val))
#if MD_COMPILER_CLANG
# define md_expect(expr, val) __builtin_expect((expr), (val))
#else
# define expect(expr, val) (expr)
# define md_expect(expr, val) (expr)
#endif
#define likely(expr) expect(expr, 1)
#define unlikely(expr) expect(expr, 0)
#define md_likely(expr) md_expect(expr, 1)
#define md_unlikely(expr) md_expect(expr, 0)
////////////////////////////////
//~ erg: type casting
#if LANG_CPP
# ifndef ccast
# define ccast( type, value ) ( const_cast< type >( (value) ) )
#if MD_LANG_CPP
# ifndef md_ccast
# define md_ccast( type, value ) ( const_cast< type >( (value) ) )
# endif
# ifndef pcast
# define pcast( type, value ) ( * reinterpret_cast< type* >( & ( value ) ) )
# ifndef md_pcast
# define md_pcast( type, value ) ( * reinterpret_cast< type* >( & ( value ) ) )
# endif
# ifndef rcast
# define rcast( type, value ) reinterpret_cast< type >( value )
# ifndef md_rcast
# define md_rcast( type, value ) reinterpret_cast< type >( value )
# endif
# ifndef scast
# define scast( type, value ) static_cast< type >( value )
# ifndef md_scast
# define md_scast( type, value ) static_cast< type >( value )
# endif
#else
# ifndef ccast
# define ccast( type, value ) ( (type)(value) )
# ifndef md_ccast
# define md_ccast( type, value ) ( (type)(value) )
# endif
# ifndef pcast
# define pcast( type, value ) ( * (type*)(& value) )
# ifndef md_pcast
# define md_pcast( type, value ) ( * (type*)(& value) )
# endif
# ifndef rcast
# define rcast( type, value ) ( (type)(value) )
# ifndef md_rcast
# define md_rcast( type, value ) ( (type)(value) )
# endif
# ifndef scast
# define scast( type, value ) ( (type)(value) )
# ifndef md_scast
# define md_scast( type, value ) ( (type)(value) )
# endif
#endif
#if ! defined(typeof) && ( ! LANG_C || __STDC_VERSION__ < 202311L)
# if ! LANG_C
#if ! defined(typeof) && ( ! MD_LANG_C || __STDC_VERSION__ < 202311L)
# if ! MD_LANG_C
# define typeof decltype
# elif defined(_MSC_VER)
# define typeof __typeof__
# elif defined(__GNUC__) || defined(__clang__)
# define typeof __typeof__
# else
# error "Compiler not supported"
# error "MD_Compiler not supported"
# endif
#endif
#if LANG_C
#if MD_LANG_C
# if __STDC_VERSION__ >= 202311L
# define enum_underlying(type) : type
# define md_enum_underlying(type) : type
# else
# define enum_underlying(type)
# define md_enum_underlying(type)
# endif
#else
# define enum_underlying(type) : type
# define md_enum_underlying(type) : type
#endif
#if LANG_C
# ifndef nullptr
# define nullptr NULL
#if MD_LANG_C
# ifndef md_nullptr
# define md_nullptr NULL
# endif
# ifndef MD_REMOVE_PTR
@@ -79,13 +79,13 @@
# endif
#endif
#if ! defined(PARAM_DEFAULT) && LANG_CPP
# define PARAM_DEFAULT = {}
#if ! defined(MD_PARAM_DEFAULT) && MD_LANG_CPP
# define MD_PARAM_DEFAULT = {}
#else
# define PARAM_DEFAULT
# define MD_PARAM_DEFAULT
#endif
#if LANG_C
#if MD_LANG_C
# ifndef static_assert
# undef static_assert
# if __STDC_VERSION__ >= 201112L
@@ -96,86 +96,86 @@
# endif
#endif
#ifndef force_inline
# if COMPILER_MSVC
# define force_inline __forceinline
# elif COMPILER_GCC
# define force_inline inline __attribute__((__always_inline__))
# elif COMPILER_CLANG
#ifndef md_force_inline
# if MD_COMPILER_MSVC
# define md_force_inline __forceinline
# elif MD_COMPILER_GCC
# define md_force_inline inline __attribute__((__always_inline__))
# elif MD_COMPILER_CLANG
# if __has_attribute(__always_inline__)
# define force_inline inline __attribute__((__always_inline__))
# define md_force_inline inline __attribute__((__always_inline__))
# else
# define force_inline
# define md_force_inline
# endif
# else
# define force_inline
# define md_force_inline
# endif
#endif
#ifndef never_inline
# if COMPILER_MSVC
# define never_inline __declspec( noinline )
# elif COMPILER_GCC
# define never_inline __attribute__( ( __noinline__ ) )
# elif COMPILER_CLANG
#ifndef md_never_inline
# if MD_COMPILER_MSVC
# define md_never_inline __declspec( noinline )
# elif MD_COMPILER_GCC
# define md_never_inline __attribute__( ( __noinline__ ) )
# elif MD_COMPILER_CLANG
# if __has_attribute(__always_inline__)
# define never_inline __attribute__( ( __noinline__ ) )
# define md_never_inline __attribute__( ( __noinline__ ) )
# else
# define never_inline
# define md_never_inline
# endif
# else
# define never_inline
# define md_never_inline
# endif
#endif
////////////////////////////////
//~ rjf: For-Loop Construct Macros
#ifndef defer_loop
#define defer_loop(begin, end) for (int _i_ = ((begin), 0); ! _i_; _i_ += 1, (end))
#ifndef md_defer_loop
#define md_defer_loop(begin, end) for (int _i_ = ((begin), 0); ! _i_; _i_ += 1, (end))
#endif
#ifndef defer_loop_checked
#define defer_loop_checked(begin, end) for (int _i_ = 2 * ! (begin); (_i_ == 2 ? ((end), 0) : !_i_); _i_ += 1, (end))
#ifndef md_defer_loop_checked
#define md_defer_loop_checked(begin, end) for (int _i_ = 2 * ! (begin); (_i_ == 2 ? ((end), 0) : !_i_); _i_ += 1, (end))
#endif
#ifndef each_enum_val
#define each_enum_val(type, it) type it = (type) 0; it < type ## _COUNT; it = (type)( it + 1 )
#ifndef md_each_enum_val
#define md_each_enum_val(type, it) type it = (type) 0; it < type ## _COUNT; it = (type)( it + 1 )
#endif
#ifndef each_non_zero_enum_val
#define each_non_zero_enum_val(type, it) type it = (type) 1; it < type ## _COUNT; it = (type)( it + 1 )
#ifndef md_each_non_zero_enum_val
#define md_each_non_zero_enum_val(type, it) type it = (type) 1; it < type ## _COUNT; it = (type)( it + 1 )
#endif
#ifndef stringify
#define stringify_(S) #S
#define stringify(S) stringify_(S)
#ifndef md_stringify
#define md_stringify_(S) #S
#define md_stringify(S) md_stringify_(S)
#endif
#ifndef glue
#define glue_(A, B) A ## B
#define glue(A, B) glue_(A,B)
#ifndef md_glue
#define md_glue_(A, B) A ## B
#define md_glue(A, B) md_glue_(A,B)
#endif
#define src_line_str stringify(__LINE__)
#define md_src_line_str md_stringify(__LINE__)
#ifndef do_once
#define do_once() \
local_persist int __do_once_counter_##src_line_str = 0; \
for(; __do_once_counter_##src_line_str != 1; __do_once_counter_##src_line_str = 1 ) \
#ifndef md_do_once
#define md_do_once() \
md_local_persist int __do_once_counter_##md_src_line_str = 0; \
for(; __do_once_counter_##md_src_line_str != 1; __do_once_counter_##md_src_line_str = 1 ) \
#define do_once_defer( expression ) \
local_persist int __do_once_counter_##src_line_str = 0; \
for(;__do_once_counter_##src_line_str != 1; __do_once_counter_##src_line_str = 1, (expression)) \
#define md_do_once_defer( expression ) \
md_local_persist int __do_once_counter_##md_src_line_str = 0; \
for(;__do_once_counter_##md_src_line_str != 1; __do_once_counter_##md_src_line_str = 1, (expression)) \
#define do_once_start \
#define md_do_once_start \
do \
{ \
local_persist \
md_local_persist \
bool done = false; \
if ( done ) \
break; \
done = true;
#define do_once_end \
#define md_do_once_end \
} \
while(0);
#endif
+3 -3
View File
@@ -4,7 +4,7 @@
#endif
inline void
set_thread_name(String8 string) {
prof_thread_name("%.*s", str8_varg(string));
os_set_thread_name(string);
md_set_thread_name(MD_String8 string) {
md_prof_thread_name("%.*s", md_str8_varg(string));
md_os_set_thread_name(string);
}
+7 -7
View File
@@ -8,21 +8,21 @@
// Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
MD_API void set_thread_name(String8 string);
MD_API void md_set_thread_name(MD_String8 string);
inline void
set_thread_namef(char *fmt, ...)
md_set_thread_namef(char *fmt, ...)
{
TempArena scratch = scratch_begin(0, 0);
MD_TempArena scratch = md_scratch_begin(0, 0);
va_list args;
va_start(args, fmt);
String8 string = str8fv(scratch.arena, fmt, args);
set_thread_name(string);
MD_String8 string = md_str8fv(scratch.arena, fmt, args);
md_set_thread_name(string);
va_end(args);
scratch_end(scratch);
}
#define thread_namef(...) (set_thread_namef(__VA_ARGS__))
#define thread_name(str) (set_thread_name(str))
#define md_thread_namef(...) (md_set_thread_namef(__VA_ARGS__))
#define md_thread_name(str) (md_set_thread_name(str))
+574 -574
View File
File diff suppressed because it is too large Load Diff
+357 -357
View File
File diff suppressed because it is too large Load Diff
+163 -163
View File
@@ -5,15 +5,15 @@
#endif
void*
default_resize_align( AllocatorInfo a, void* old_memory, SSIZE old_size, SSIZE new_size, SSIZE alignment )
md_default_resize_align( MD_AllocatorInfo a, void* old_memory, MD_SSIZE old_size, MD_SSIZE new_size, MD_SSIZE alignment )
{
if ( ! old_memory )
return alloc_align( a, new_size, alignment );
return md_alloc_align( a, new_size, alignment );
if ( new_size == 0 )
{
alloc_free( a, old_memory );
return nullptr;
md_alloc_free( a, old_memory );
return md_nullptr;
}
if ( new_size < old_size )
@@ -25,12 +25,12 @@ default_resize_align( AllocatorInfo a, void* old_memory, SSIZE old_size, SSIZE n
}
else
{
void* new_memory = alloc_align( a, new_size, alignment );
void* new_memory = md_alloc_align( a, new_size, alignment );
if ( ! new_memory )
return nullptr;
return md_nullptr;
mem_move( new_memory, old_memory, md_min( new_size, old_size ) );
alloc_free( a, old_memory );
md_mem_move( new_memory, old_memory, md_min( new_size, old_size ) );
md_alloc_free( a, old_memory );
return new_memory;
}
}
@@ -41,73 +41,73 @@ default_resize_align( AllocatorInfo a, void* old_memory, SSIZE old_size, SSIZE n
typedef struct _heap_stats _heap_stats;
struct _heap_stats
{
U32 magic;
SSIZE used_memory;
SSIZE alloc_count;
MD_U32 magic;
MD_SSIZE used_memory;
MD_SSIZE md_alloc_count;
};
global _heap_stats _heap_stats_info;
md_global _heap_stats _heap_stats_info;
void
heap_stats_init( void )
md_heap_stats_init( void )
{
memory_zero_struct( &_heap_stats_info );
md_memory_zero_struct( &_heap_stats_info );
_heap_stats_info.magic = GEN_HEAP_STATS_MAGIC;
}
SSIZE
MD_SSIZE
heap_stats_used_memory( void )
{
assert_msg( _heap_stats_info.magic == GEN_HEAP_STATS_MAGIC, "heap_stats is not initialised yet, call heap_stats_init first!" );
md_assert_msg( _heap_stats_info.magic == GEN_HEAP_STATS_MAGIC, "heap_stats is not initialised yet, call md_heap_stats_init first!" );
return _heap_stats_info.used_memory;
}
SSIZE
heap_stats_alloc_count( void )
MD_SSIZE
md_heap_stats_alloc_count( void )
{
assert_msg( _heap_stats_info.magic == GEN_HEAP_STATS_MAGIC, "heap_stats is not initialised yet, call heap_stats_init first!" );
return _heap_stats_info.alloc_count;
md_assert_msg( _heap_stats_info.magic == GEN_HEAP_STATS_MAGIC, "heap_stats is not initialised yet, call md_heap_stats_init first!" );
return _heap_stats_info.md_alloc_count;
}
void
heap_stats_check( void )
md_heap_stats_check( void )
{
assert_msg( _heap_stats_info.magic == GEN_HEAP_STATS_MAGIC, "heap_stats is not initialised yet, call heap_stats_init first!" );
assert( _heap_stats_info.used_memory == 0 );
assert( _heap_stats_info.alloc_count == 0 );
md_assert_msg( _heap_stats_info.magic == GEN_HEAP_STATS_MAGIC, "heap_stats is not initialised yet, call md_heap_stats_init first!" );
md_assert( _heap_stats_info.used_memory == 0 );
md_assert( _heap_stats_info.md_alloc_count == 0 );
}
typedef struct _heap_alloc_info _heap_alloc_info;
struct _heap_alloc_info
{
SSIZE size;
MD_SSIZE size;
void* physical_start;
};
#endif
void*
heap_allocator_proc( void* allocator_data, AllocatorMode mode, SSIZE size, SSIZE alignment, void* old_memory, SSIZE old_size, U64 flags )
md_heap_allocator_proc( void* allocator_data, MD_AllocatorMode mode, MD_SSIZE size, MD_SSIZE alignment, void* old_memory, MD_SSIZE old_size, MD_U64 flags )
{
void* ptr = nullptr;
void* ptr = md_nullptr;
// unused( allocator_data );
// unused( old_size );
if ( ! alignment )
alignment = MD_DEFAULT_MEMORY_ALIGNMENT;
#ifdef MD_HEAP_ANALYSIS
ssize alloc_info_size = size_of( _heap_alloc_info );
ssize alloc_info_remainder = ( alloc_info_size % alignment );
ssize track_size = max( alloc_info_size, alignment ) + alloc_info_remainder;
ssize md_alloc_info_size = size_of( _heap_alloc_info );
ssize md_alloc_info_remainder = ( md_alloc_info_size % alignment );
ssize track_size = md_max( md_alloc_info_size, alignment ) + md_alloc_info_remainder;
switch ( type )
{
case EAllocatorMode_FREE :
{
if ( ! old_memory )
break;
_heap_alloc_info* alloc_info = rcast( _heap_alloc_info*, old_memory) - 1;
_heap_stats_info.used_memory -= alloc_info->size;
_heap_stats_info.alloc_count--;
old_memory = alloc_info->physical_start;
_heap_alloc_info* md_alloc_info = md_rcast( _heap_alloc_info*, old_memory) - 1;
_heap_stats_info.used_memory -= md_alloc_info->size;
_heap_stats_info.md_alloc_count--;
old_memory = md_alloc_info->physical_start;
}
break;
case EAllocatorMode_ALLOC :
@@ -122,27 +122,27 @@ heap_allocator_proc( void* allocator_data, AllocatorMode mode, SSIZE size, SSIZE
switch ( mode )
{
#if defined( COMPILER_MSVC ) || ( defined( COMPILER_GCC ) && defined( OS_WINDOWS ) ) || ( defined( COMPILER_TINYC ) && defined( OS_WINDOWS ) )
case AllocatorMode_Alloc:
#if defined( MD_COMPILER_MSVC ) || ( defined( MD_COMPILER_GCC ) && defined( MD_OS_WINDOWS ) ) || ( defined( MD_COMPILER_TINYC ) && defined( MD_OS_WINDOWS ) )
case MD_AllocatorMode_Alloc:
{
ptr = _aligned_malloc( size, alignment );
if ( flags & ALLOCATOR_FLAG_CLEAR_TO_ZERO )
memory_zero( ptr, size );
if ( flags & MD_ALLOCATOR_FLAG_CLEAR_TO_ZERO )
md_memory_zero( ptr, size );
}
break;
case AllocatorMode_Free:
case MD_AllocatorMode_Free:
_aligned_free( old_memory );
break;
case AllocatorMode_Resize:
case MD_AllocatorMode_Resize:
{
AllocatorInfo a = heap();
ptr = default_resize_align( a, old_memory, old_size, size, alignment );
MD_AllocatorInfo a = md_heap();
ptr = md_default_resize_align( a, old_memory, old_size, size, alignment );
}
break;
#elif defined( OS_LINUX ) && ! defined( CPU_ARM ) && ! defined( COMPILER_TINYC )
#elif defined( MD_OS_LINUX ) && ! defined( CPU_ARM ) && ! defined( MD_COMPILER_TINYC )
case EAllocation_ALLOC :
{
ptr = aligned_alloc( alignment, ( size + alignment - 1 ) & ~( alignment - 1 ) );
@@ -162,8 +162,8 @@ heap_allocator_proc( void* allocator_data, AllocatorMode mode, SSIZE size, SSIZE
case EAllocation_RESIZE :
{
AllocatorInfo a = heap();
ptr = default_resize_align( a, old_memory, old_size, size, alignment );
MD_AllocatorInfo a = md_heap();
ptr = md_default_resize_align( a, old_memory, old_size, size, alignment );
}
break;
#else
@@ -171,7 +171,7 @@ heap_allocator_proc( void* allocator_data, AllocatorMode mode, SSIZE size, SSIZE
{
posix_memalign( &ptr, alignment, size );
if ( flags & ALLOCATOR_FLAG_CLEAR_TO_ZERO )
if ( flags & MD_ALLOCATOR_FLAG_CLEAR_TO_ZERO )
{
zero_size( ptr, size );
}
@@ -186,89 +186,89 @@ heap_allocator_proc( void* allocator_data, AllocatorMode mode, SSIZE size, SSIZE
case EAllocType_RESIZE :
{
AllocatorInfo a = heap();
ptr = default_resize_align( a, old_memory, old_size, size, alignment );
MD_AllocatorInfo a = md_heap();
ptr = md_default_resize_align( a, old_memory, old_size, size, alignment );
}
break;
#endif
case AllocatorMode_FreeAll:
case MD_AllocatorMode_FreeAll:
break;
case AllocatorMode_QueryType:
return (void*) AllocatorType_Heap;
case MD_AllocatorMode_QueryType:
return (void*) MD_AllocatorType_Heap;
case AllocatorMode_QuerySupport:
case MD_AllocatorMode_QuerySupport:
return (void*) (
AllocatorQuery_Alloc | AllocatorQuery_Free | AllocatorQuery_Resize | AllocatorQuery_ResizeGrow | AllocatorQuery_ResizeShrink
MD_AllocatorQuery_Alloc | MD_AllocatorQuery_Free | MD_AllocatorQuery_Resize | MD_AllocatorQuery_ResizeGrow | MD_AllocatorQuery_ResizeShrink
);
}
#ifdef GEN_HEAP_ANALYSIS
if ( type == AllocatorMode_Alloc )
if ( type == MD_AllocatorMode_Alloc )
{
_heap_alloc_info* alloc_info = rcast( _heap_alloc_info*, rcast( char*, ptr) + alloc_info_remainder );
zero_item( alloc_info );
alloc_info->size = size - track_size;
alloc_info->physical_start = ptr;
ptr = rcast( void*, alloc_info + 1 );
_heap_stats_info.used_memory += alloc_info->size;
_heap_stats_info.alloc_count++;
_heap_alloc_info* md_alloc_info = md_rcast( _heap_alloc_info*, md_rcast( char*, ptr) + md_alloc_info_remainder );
zero_item( md_alloc_info );
md_alloc_info->size = size - track_size;
md_alloc_info->physical_start = ptr;
ptr = md_rcast( void*, md_alloc_info + 1 );
_heap_stats_info.used_memory += md_alloc_info->size;
_heap_stats_info.md_alloc_count++;
}
#endif
return ptr;
}
VArena*
varena__alloc(VArenaParams params)
MD_VArena*
md_varena__alloc(MD_VArenaParams params)
{
if (params.reserve_size == 0) {
params.reserve_size = VARENA_DEFAULT_RESERVE;
params.reserve_size = MD_VARENA_DEFAULT_RESERVE;
}
if (params.commit_size == 0) {
params.commit_size = VARENA_DEFAULT_COMMIT;
params.commit_size = MD_VARENA_DEFAULT_COMMIT;
}
// rjf: round up reserve/commit sizes
U64 reserve_size = params.reserve_size;
U64 commit_size = params.commit_size;
MD_U64 reserve_size = params.reserve_size;
MD_U64 commit_size = params.commit_size;
void* base = nullptr;
if (params.flags & VArenaFlag_LargePages)
void* base = md_nullptr;
if (params.flags & MD_VArenaFlag_LargePages)
{
reserve_size = align_pow2(reserve_size, os_get_system_info()->large_page_size);
commit_size = align_pow2(commit_size, os_get_system_info()->large_page_size);
reserve_size = md_align_pow2(reserve_size, md_os_get_system_info()->large_page_size);
commit_size = md_align_pow2(commit_size, md_os_get_system_info()->large_page_size);
base = os_reserve_large(reserve_size);
os_commit_large(base, commit_size);
asan_poison_memory_region(base, params.commit_size);
base = md_os_reserve_large(reserve_size);
md_os_commit_large(base, commit_size);
md_asan_poison_memory_region(base, params.commit_size);
}
else
{
reserve_size = align_pow2(reserve_size, os_get_system_info()->page_size);
commit_size = align_pow2(commit_size, os_get_system_info()->page_size);
reserve_size = md_align_pow2(reserve_size, md_os_get_system_info()->page_size);
commit_size = md_align_pow2(commit_size, md_os_get_system_info()->page_size);
base = os_reserve(reserve_size);
B32 commit_result = os_commit(base, commit_size);
assert(commit_result == 1);
asan_poison_memory_region(base, params.commit_size);
base = md_os_reserve(reserve_size);
MD_B32 commit_result = md_os_commit(base, commit_size);
md_assert(commit_result == 1);
md_asan_poison_memory_region(base, params.commit_size);
}
// NOTE(Ed): Panic on varena creation failure
#if OS_FEATURE_GRAPHICAL
if(unlikely(base == 0))
#if MD_OS_FEATURE_GRAPHICAL
if(md_unlikely(base == 0))
{
os_graphical_message(1, str8_lit("Fatal Allocation Failure"), str8_lit("Unexpected memory allocation failure."));
os_abort(1);
md_os_graphical_message(1, md_str8_lit("Fatal Allocation Failure"), md_str8_lit("Unexpected memory allocation failure."));
md_os_abort(1);
}
#endif
SPTR header_size = align_pow2(size_of(VArena), MD_DEFAULT_MEMORY_ALIGNMENT);
asan_unpoison_memory_region(base, header_size);
MD_SPTR header_size = md_align_pow2(size_of(MD_VArena), MD_DEFAULT_MEMORY_ALIGNMENT);
md_asan_unpoison_memory_region(base, header_size);
VArena* vm = rcast(VArena*, base);
vm->reserve_start = rcast(SPTR, base) + header_size;
MD_VArena* vm = md_rcast(MD_VArena*, base);
vm->reserve_start = md_rcast(MD_SPTR, base) + header_size;
vm->reserve = reserve_size;
vm->commit_size = params.commit_size;
vm->committed = commit_size;
@@ -278,50 +278,50 @@ varena__alloc(VArenaParams params)
}
void
varena_release(VArena* arena)
md_varena_release(MD_VArena* arena)
{
os_release(arena, arena->reserve);
arena = nullptr;
md_os_release(arena, arena->reserve);
arena = md_nullptr;
}
void*
varena_allocator_proc(void* allocator_data, AllocatorMode mode, SSIZE requested_size, SSIZE alignment, void* old_memory, SSIZE old_size, U64 flags)
md_varena_allocator_proc(void* allocator_data, MD_AllocatorMode mode, MD_SSIZE requested_size, MD_SSIZE alignment, void* old_memory, MD_SSIZE old_size, MD_U64 flags)
{
OS_SystemInfo const* info = os_get_system_info();
MD_OS_SystemInfo const* info = md_os_get_system_info();
VArena* vm = rcast(VArena*, allocator_data);
MD_VArena* vm = md_rcast(MD_VArena*, allocator_data);
void* allocated_mem = nullptr;
void* allocated_mem = md_nullptr;
switch (mode)
{
case AllocatorMode_Alloc:
case MD_AllocatorMode_Alloc:
{
assert_msg(requested_size != 0, "requested_size is 0");
md_assert_msg(requested_size != 0, "requested_size is 0");
requested_size = align_pow2(requested_size, alignment);
requested_size = md_align_pow2(requested_size, alignment);
UPTR current_offset = vm->reserve_start + vm->commit_used;
UPTR size_to_allocate = requested_size;
UPTR to_be_used = vm->commit_used + size_to_allocate;
SPTR reserve_left = vm->reserve - vm->committed;
assert(to_be_used < reserve_left);
MD_UPTR current_offset = vm->reserve_start + vm->commit_used;
MD_UPTR size_to_allocate = requested_size;
MD_UPTR to_be_used = vm->commit_used + size_to_allocate;
MD_SPTR reserve_left = vm->reserve - vm->committed;
md_assert(to_be_used < reserve_left);
UPTR header_offset = vm->reserve_start - scast(UPTR, vm);
MD_UPTR header_offset = vm->reserve_start - md_scast(MD_UPTR, vm);
UPTR commit_left = vm->committed - vm->commit_used - header_offset;
B32 needs_more_commited = commit_left < size_to_allocate;
MD_UPTR commit_left = vm->committed - vm->commit_used - header_offset;
MD_B32 needs_more_commited = commit_left < size_to_allocate;
if (needs_more_commited)
{
UPTR next_commit_size;
if (vm->flags & VArenaFlag_LargePages) {
next_commit_size = reserve_left > 0 ? md_max(vm->commit_size, size_to_allocate) : scast(UPTR, align_pow2( abs(reserve_left), os_get_system_info()->large_page_size));
MD_UPTR next_commit_size;
if (vm->flags & MD_VArenaFlag_LargePages) {
next_commit_size = reserve_left > 0 ? md_max(vm->commit_size, size_to_allocate) : md_scast(MD_UPTR, md_align_pow2( abs(reserve_left), md_os_get_system_info()->large_page_size));
}
else {
next_commit_size = reserve_left > 0 ? md_max(vm->commit_size, size_to_allocate) : scast(UPTR, align_pow2(abs(reserve_left), os_get_system_info()->page_size));
next_commit_size = reserve_left > 0 ? md_max(vm->commit_size, size_to_allocate) : md_scast(MD_UPTR, md_align_pow2(abs(reserve_left), md_os_get_system_info()->page_size));
}
if (next_commit_size) {
void* next_commit_start = rcast(void*, rcast(UPTR, vm) + vm->committed);
B32 commit_result = os_commit(next_commit_start, next_commit_size);
void* next_commit_start = md_rcast(void*, md_rcast(MD_UPTR, vm) + vm->committed);
MD_B32 commit_result = md_os_commit(next_commit_start, next_commit_size);
if (commit_result == false) {
break;
}
@@ -329,60 +329,60 @@ varena_allocator_proc(void* allocator_data, AllocatorMode mode, SSIZE requested_
}
}
allocated_mem = rcast(void*, current_offset);
allocated_mem = md_rcast(void*, current_offset);
vm->commit_used += size_to_allocate;
}
break;
case AllocatorMode_Free:
case MD_AllocatorMode_Free:
{
}
break;
case AllocatorMode_FreeAll:
case MD_AllocatorMode_FreeAll:
{
vm->commit_used = 0;
}
break;
case AllocatorMode_Resize:
case MD_AllocatorMode_Resize:
{
assert(old_memory != nullptr);
assert(old_size > 0);
assert_msg(old_size == requested_size, "Requested resize when none needed");
md_assert(old_memory != md_nullptr);
md_assert(old_size > 0);
md_assert_msg(old_size == requested_size, "Requested md_resize when none needed");
requested_size = align_pow2(requested_size, alignment);
old_size = align_pow2(old_size, alignment);
requested_size = md_align_pow2(requested_size, alignment);
old_size = md_align_pow2(old_size, alignment);
UPTR old_memory_offset = scast(UPTR, old_memory) + scast(UPTR, old_size);
UPTR current_offset = scast(UPTR, vm->reserve_start) + scast(UPTR, vm->commit_used);
MD_UPTR old_memory_offset = md_scast(MD_UPTR, old_memory) + md_scast(MD_UPTR, old_size);
MD_UPTR current_offset = md_scast(MD_UPTR, vm->reserve_start) + md_scast(MD_UPTR, vm->commit_used);
assert_msg(old_memory_offset == current_offset, "Cannot resize existing allocation in VArena unless it was the last allocated");
md_assert_msg(old_memory_offset == current_offset, "Cannot md_resize existing allocation in MD_VArena unless it was the last allocated");
B32 requested_shrink = requested_size >= old_size;
MD_B32 requested_shrink = requested_size >= old_size;
if (requested_shrink) {
vm->commit_used -= rcast(UPTR, align_pow2(requested_size, alignment));
vm->commit_used -= md_rcast(MD_UPTR, md_align_pow2(requested_size, alignment));
allocated_mem = old_memory;
break;
}
UPTR size_to_allocate = requested_size - old_size, alignment;
MD_UPTR size_to_allocate = requested_size - old_size, alignment;
UPTR header_offset = vm->reserve_start - scast(UPTR, vm);
UPTR commit_left = vm->committed - vm->commit_used - header_offset;
B32 needs_more_commited = commit_left < size_to_allocate;
MD_UPTR header_offset = vm->reserve_start - md_scast(MD_UPTR, vm);
MD_UPTR commit_left = vm->committed - vm->commit_used - header_offset;
MD_B32 needs_more_commited = commit_left < size_to_allocate;
if (needs_more_commited)
{
SPTR reserve_left = vm->reserve - vm->committed;
UPTR next_commit_size;
if (vm->flags & VArenaFlag_LargePages) {
next_commit_size = reserve_left > 0 ? vm->commit_size : scast(UPTR, align_pow2( -reserve_left, os_get_system_info()->large_page_size));
MD_SPTR reserve_left = vm->reserve - vm->committed;
MD_UPTR next_commit_size;
if (vm->flags & MD_VArenaFlag_LargePages) {
next_commit_size = reserve_left > 0 ? vm->commit_size : md_scast(MD_UPTR, md_align_pow2( -reserve_left, md_os_get_system_info()->large_page_size));
}
else {
next_commit_size = reserve_left > 0 ? vm->commit_size : scast(UPTR, align_pow2(abs(reserve_left), os_get_system_info()->page_size));
next_commit_size = reserve_left > 0 ? vm->commit_size : md_scast(MD_UPTR, md_align_pow2(abs(reserve_left), md_os_get_system_info()->page_size));
}
if (next_commit_size) {
B32 commit_result = os_commit(vm, next_commit_size);
MD_B32 commit_result = md_os_commit(vm, next_commit_size);
if (commit_result == false) {
break;
}
@@ -394,16 +394,16 @@ varena_allocator_proc(void* allocator_data, AllocatorMode mode, SSIZE requested_
}
break;
case AllocatorMode_QueryType:
case MD_AllocatorMode_QueryType:
{
return (void*) AllocatorType_VArena;
return (void*) MD_AllocatorType_VArena;
}
break;
case AllocatorMode_QuerySupport:
case MD_AllocatorMode_QuerySupport:
{
return (void*) (
AllocatorQuery_Alloc | AllocatorQuery_FreeAll | AllocatorQuery_Resize | AllocatorQuery_ResizeGrow | AllocatorQuery_ResizeShrink
MD_AllocatorQuery_Alloc | MD_AllocatorQuery_FreeAll | MD_AllocatorQuery_Resize | MD_AllocatorQuery_ResizeGrow | MD_AllocatorQuery_ResizeShrink
);
}
break;
@@ -412,54 +412,54 @@ varena_allocator_proc(void* allocator_data, AllocatorMode mode, SSIZE requested_
}
void*
farena_allocator_proc(void* allocator_data, AllocatorMode mode, SSIZE size, SSIZE alignment, void* old_memory, SSIZE old_size, U64 flags)
farena_allocator_proc(void* allocator_data, MD_AllocatorMode mode, MD_SSIZE size, MD_SSIZE alignment, void* old_memory, MD_SSIZE old_size, MD_U64 flags)
{
FArena* arena = rcast(FArena*, allocator_data);
MD_FArena* arena = md_rcast(MD_FArena*, allocator_data);
void* allocated_mem = nullptr;
void* allocated_mem = md_nullptr;
switch (mode)
{
case AllocatorMode_Alloc:
case MD_AllocatorMode_Alloc:
{
SPTR end = scast(SPTR, arena->slice.data) + arena->used;
SSIZE total_size = align_pow2(size, alignment);
MD_SPTR end = md_scast(MD_SPTR, arena->slice.data) + arena->used;
MD_SSIZE total_size = md_align_pow2(size, alignment);
if (arena->used + total_size > arena->slice.len ) {
// Out of memory
return allocated_mem;
}
allocated_mem = scast(void*, end);
allocated_mem = md_scast(void*, end);
arena->used += total_size;
}
break;
case AllocatorMode_Free:
case MD_AllocatorMode_Free:
{
}
break;
case AllocatorMode_FreeAll:
case MD_AllocatorMode_FreeAll:
{
arena->used = 0;
}
break;
case AllocatorMode_Resize:
case MD_AllocatorMode_Resize:
{
assert(old_memory != nullptr);
assert(old_size > 0);
assert_msg(old_size == size, "Requested resize when none needed");
md_assert(old_memory != md_nullptr);
md_assert(old_size > 0);
md_assert_msg(old_size == size, "Requested md_resize when none needed");
size = align_pow2(size, alignment);
old_size = align_pow2(size, alignment);
size = md_align_pow2(size, alignment);
old_size = md_align_pow2(size, alignment);
SPTR old_memory_offset = scast(SPTR, old_memory) + old_size;
SPTR current_offset = scast(SPTR, arena->slice.data) + arena->used;
MD_SPTR old_memory_offset = md_scast(MD_SPTR, old_memory) + old_size;
MD_SPTR current_offset = md_scast(MD_SPTR, arena->slice.data) + arena->used;
assert_msg(old_memory_offset == current_offset, "Cannot resize existing allocation in VArena unless it was the last allocated");
md_assert_msg(old_memory_offset == current_offset, "Cannot md_resize existing allocation in MD_VArena unless it was the last allocated");
B32 requested_shrink = size >= old_size;
MD_B32 requested_shrink = size >= old_size;
if (requested_shrink) {
arena->used -= size;
@@ -472,13 +472,13 @@ farena_allocator_proc(void* allocator_data, AllocatorMode mode, SSIZE size, SSIZ
}
break;
case AllocatorMode_QueryType:
return (void*) AllocatorType_FArena;
case MD_AllocatorMode_QueryType:
return (void*) MD_AllocatorType_FArena;
break;
case AllocatorMode_QuerySupport:
case MD_AllocatorMode_QuerySupport:
return (void*) (
AllocatorQuery_Alloc | AllocatorQuery_FreeAll | AllocatorQuery_Resize | AllocatorQuery_ResizeGrow | AllocatorQuery_ResizeShrink
MD_AllocatorQuery_Alloc | MD_AllocatorQuery_FreeAll | MD_AllocatorQuery_Resize | MD_AllocatorQuery_ResizeGrow | MD_AllocatorQuery_ResizeShrink
);
break;
}
+136 -136
View File
@@ -14,57 +14,57 @@
// Users can override the underlying memory allocator used, even for the HMH arena memory strategy.
#ifndef MD__ONES
#define MD__ONES ( scast( GEN_NS usize, - 1) / MD_U8_MAX )
#define MD__ONES ( md_scast( GEN_NS usize, - 1) / MD_U8_MAX )
#define MD__HIGHS ( MD__ONES * ( MD_U8_MAX / 2 + 1 ) )
#define MD__HAS_ZERO( x ) ( ( ( x ) - MD__ONES ) & ~( x ) & MD__HIGHS )
#endif
// Return value of allocator_type
typedef U64 AllocatorType;
// Return value of md_allocator_type
typedef MD_U64 MD_AllocatorType;
enum
{
AllocatorType_Heap = 0, // Genreal heap allocator
AllocatorType_VArena = 1, // Arena allocator backed by virtual address space
AllocatorType_FArena = 2, // Fixed arena backed back by a fixed size block of memory (usually a byte slice)
AllocatorType_Arena = 3, // Composite arena used originally by RAD Debugger & Metadesk
MD_AllocatorType_Heap = 0, // Genreal md_heap allocator
MD_AllocatorType_VArena = 1, // MD_Arena allocator backed by virtual address space
MD_AllocatorType_FArena = 2, // Fixed arena backed back by a fixed size block of memory (usually a byte slice)
MD_AllocatorType_Arena = 3, // Composite arena used originally by RAD Debugger & Metadesk
};
typedef U32 AllocatorMode;
enum AllocatorMode
typedef MD_U32 MD_AllocatorMode;
enum MD_AllocatorMode
{
AllocatorMode_Alloc,
AllocatorMode_Free,
AllocatorMode_FreeAll,
AllocatorMode_Resize,
AllocatorMode_QueryType,
AllocatorMode_QuerySupport,
MD_AllocatorMode_Alloc,
MD_AllocatorMode_Free,
MD_AllocatorMode_FreeAll,
MD_AllocatorMode_Resize,
MD_AllocatorMode_QueryType,
MD_AllocatorMode_QuerySupport,
};
typedef U64 AllocatorQueryFlags;
typedef MD_U64 MD_AllocatorQueryFlags;
enum
{
AllocatorQuery_Alloc = (1 << 0),
AllocatorQuery_Free = (1 << 1),
AllocatorQuery_FreeAll = (1 << 2),
AllocatorQuery_Resize = (1 << 3), // Supports both grow and shrink
AllocatorQuery_ResizeShrink = (1 << 4),
AllocatorQuery_ResizeGrow = (1 << 5),
MD_AllocatorQuery_Alloc = (1 << 0),
MD_AllocatorQuery_Free = (1 << 1),
MD_AllocatorQuery_FreeAll = (1 << 2),
MD_AllocatorQuery_Resize = (1 << 3), // Supports both grow and shrink
MD_AllocatorQuery_ResizeShrink = (1 << 4),
MD_AllocatorQuery_ResizeGrow = (1 << 5),
};
typedef void*(AllocatorProc)( void* allocator_data, AllocatorMode type, SSIZE size, SSIZE alignment, void* old_memory, SSIZE old_size, U64 flags );
typedef void*(MD_AllocatorProc)( void* allocator_data, MD_AllocatorMode type, MD_SSIZE size, MD_SSIZE alignment, void* old_memory, MD_SSIZE old_size, MD_U64 flags );
typedef struct AllocatorInfo AllocatorInfo;
struct AllocatorInfo
typedef struct MD_AllocatorInfo MD_AllocatorInfo;
struct MD_AllocatorInfo
{
AllocatorProc* proc;
MD_AllocatorProc* proc;
void* data;
};
// Overridable by the user by defining MD_OVERRIDE_DEFAULT_ALLOCATOR
AllocatorInfo default_allocator();
MD_AllocatorInfo md_default_allocator();
enum AllocFlag
{
ALLOCATOR_FLAG_CLEAR_TO_ZERO = (1 << 0),
MD_ALLOCATOR_FLAG_CLEAR_TO_ZERO = (1 << 0),
};
#ifndef MD_DEFAULT_MEMORY_ALIGNMENT
@@ -72,222 +72,222 @@ enum AllocFlag
#endif
#ifndef MD_DEFAULT_ALLOCATOR_FLAGS
# define MD_DEFAULT_ALLOCATOR_FLAGS ( ALLOCATOR_FLAG_CLEAR_TO_ZERO )
# define MD_DEFAULT_ALLOCATOR_FLAGS ( MD_ALLOCATOR_FLAG_CLEAR_TO_ZERO )
#endif
// Retrieve which type of allocator
AllocatorType allocator_type(AllocatorInfo a);
MD_AllocatorType md_allocator_type(MD_AllocatorInfo a);
// Retreive which modes the allocator supports
AllocatorQueryFlags allocator_query_support(AllocatorInfo a);
MD_AllocatorQueryFlags md_allocator_query_support(MD_AllocatorInfo a);
// Allocate memory with default alignment.
void* alloc( AllocatorInfo a, SSIZE size );
void* md_alloc( MD_AllocatorInfo a, MD_SSIZE size );
// Allocate memory with specified alignment.
void* alloc_align( AllocatorInfo a, SSIZE size, SSIZE alignment );
void* md_alloc_align( MD_AllocatorInfo a, MD_SSIZE size, MD_SSIZE alignment );
// Free allocated memory.
void alloc_free( AllocatorInfo a, void* ptr );
void md_alloc_free( MD_AllocatorInfo a, void* ptr );
// Free all memory allocated by an allocator.
void free_all( AllocatorInfo a );
void md_free_all( MD_AllocatorInfo a );
// Resize an allocated memory.
void* resize( AllocatorInfo a, void* ptr, SSIZE old_size, SSIZE new_size );
void* md_resize( MD_AllocatorInfo a, void* ptr, MD_SSIZE old_size, MD_SSIZE new_size );
// Resize an allocated memory with specified alignment.
void* resize_align( AllocatorInfo a, void* ptr, SSIZE old_size, SSIZE new_size, SSIZE alignment );
void* md_resize_align( MD_AllocatorInfo a, void* ptr, MD_SSIZE old_size, MD_SSIZE new_size, MD_SSIZE alignment );
#ifndef alloc_item
#ifndef md_alloc_item
// Allocate memory for an item.
#define alloc_item(allocator, Type) (Type*)memory_zero(alloc(allocator, size_of(Type)), size_of(Type))
#define md_alloc_item(allocator, Type) (Type*)md_memory_zero(md_alloc(allocator, size_of(Type)), size_of(Type))
// Allocate memory for an item.
#define alloc_item_no_zero( allocator, Type ) (Type*) alloc(allocator, size_of(Type))
#define md_alloc_item_no_zero( allocator, Type ) (Type*) md_alloc(allocator, size_of(Type))
#endif
#ifndef alloc_array
#ifndef md_alloc_array
// Allocate memory for an array of items.
#define alloc_array( allocator_, Type, count ) (Type*)memory_zero(alloc( allocator_, size_of(Type) * (count) ), size_of(Type) * (count))
#define md_alloc_array( allocator_, Type, count ) (Type*)md_memory_zero(md_alloc( allocator_, size_of(Type) * (count) ), size_of(Type) * (count))
// Allocate memory for an array of items. (Don't zero initialize)
#define alloc_array_no_zero( allocator_, Type, count ) (Type*) alloc( allocator_, size_of(Type) * (count) )
#define md_alloc_array_no_zero( allocator_, Type, count ) (Type*) md_alloc( allocator_, size_of(Type) * (count) )
#endif
// Allocate/Resize memory using default options.
// Use this if you don't need a "fancy" resize allocation
void* default_resize_align( AllocatorInfo a, void* ptr, SSIZE old_size, SSIZE new_size, SSIZE alignment );
// Use this if you don't need a "fancy" md_resize allocation
void* md_default_resize_align( MD_AllocatorInfo a, void* ptr, MD_SSIZE old_size, MD_SSIZE new_size, MD_SSIZE alignment );
#ifdef MD_HEAP_ANALYSIS
/* heap memory analysis tools */
/* md_heap memory analysis tools */
/* define GEN_HEAP_ANALYSIS to enable this feature */
/* call zpl_heap_stats_init at the beginning of the entry point */
/* you can call zpl_heap_stats_check near the end of the execution to validate any possible leaks */
MD_API void heap_stats_init( void );
MD_API SSIZE heap_stats_used_memory( void );
MD_API SSIZE heap_stats_alloc_count( void );
MD_API void heap_stats_check( void );
MD_API void md_heap_stats_init( void );
MD_API MD_SSIZE heap_stats_used_memory( void );
MD_API MD_SSIZE md_heap_stats_alloc_count( void );
MD_API void md_heap_stats_check( void );
#endif
MD_API void* heap_allocator_proc( void* allocator_data, AllocatorMode mode, SSIZE size, SSIZE alignment, void* old_memory, SSIZE old_size, U64 flags );
MD_API void* md_heap_allocator_proc( void* allocator_data, MD_AllocatorMode mode, MD_SSIZE size, MD_SSIZE alignment, void* old_memory, MD_SSIZE old_size, MD_U64 flags );
#ifndef heap
// The heap allocator backed by the platform vendor's malloc & free.
#define heap() (AllocatorInfo){ heap_allocator_proc, nullptr }
#ifndef md_heap
// The md_heap allocator backed by the platform vendor's md_malloc & free.
#define md_heap() (MD_AllocatorInfo){ md_heap_allocator_proc, md_nullptr }
#endif
#ifndef md_malloc
// Helper to allocate memory using heap allocator.
#define md_malloc( sz ) alloc( heap(), sz )
// Helper to allocate memory using md_heap allocator.
#define md_malloc( sz ) md_alloc( md_heap(), sz )
#endif
#ifndef md_free
// Helper to free memory allocated by heap allocator.
#define md_free( ptr ) alloc_free( heap(), ptr )
// Helper to free memory allocated by md_heap allocator.
#define md_free( ptr ) md_alloc_free( md_heap(), ptr )
#endif
/* Virtual Memory Arena
/* Virtual Memory MD_Arena
This is separate from the composite arena used by HMH/Casey Muratori/RJF
This arena stricly manages one reservation of the process's virtual address space.
Segregating this from composite Arena style causes more moremoy to be used for "allocator headers", however it allows
Segregating this from composite MD_Arena style causes more moremoy to be used for "allocator headers", however it allows
users of a library to have greater control over the allocation strategy used from their side instead of the library itself.
Like with the composite Arena, the VArena has its struct as the header of the reserve of memory.
Like with the composite MD_Arena, the MD_VArena has its struct as the header of the reserve of memory.
*/
#ifndef VARENA_DEFUALT_RESERVE
#define VARENA_DEFAULT_RESERVE MB(64)
#ifndef MD_VARENA_DEFUALT_RESERVE
#define MD_VARENA_DEFAULT_RESERVE MD_MB(64)
#endif
#ifndef VARENA_DEFUALT_COMMIT
#define VARENA_DEFAULT_COMMIT KB(64)
#ifndef MD_VARENA_DEFUALT_COMMIT
#define MD_VARENA_DEFAULT_COMMIT MD_KB(64)
#endif
typedef U32 VArenaFlags;
typedef MD_U32 MD_VArenaFlags;
enum
{
VArenaFlag_LargePages = (1 << 0),
MD_VArenaFlag_LargePages = (1 << 0),
};
typedef struct VArenaParams VArenaParams;
struct VArenaParams
typedef struct MD_VArenaParams MD_VArenaParams;
struct MD_VArenaParams
{
U64 base_addr;
VArenaFlags flags;
U64 reserve_size;
U64 commit_size;
MD_U64 base_addr;
MD_VArenaFlags flags;
MD_U64 reserve_size;
MD_U64 commit_size;
};
typedef struct VArena VArena;
struct VArena
typedef struct MD_VArena MD_VArena;
struct MD_VArena
{
SSIZE reserve_start;
SSIZE reserve;
SSIZE commit_size;
SSIZE committed;
SSIZE commit_used;
VArenaFlags flags;
MD_SSIZE reserve_start;
MD_SSIZE reserve;
MD_SSIZE commit_size;
MD_SSIZE committed;
MD_SSIZE commit_used;
MD_VArenaFlags flags;
};
MD_API VArena* varena__alloc(VArenaParams params PARAM_DEFAULT);
#define varena_alloc(...) varena__alloc( (VArenaParams){__VA_ARGS__} )
MD_API MD_VArena* md_varena__alloc(MD_VArenaParams params MD_PARAM_DEFAULT);
#define md_varena_alloc(...) md_varena__alloc( (MD_VArenaParams){__VA_ARGS__} )
MD_API void varena_commit (VArena* vm, SSIZE commit_size);
MD_API void varena_release(VArena* vm);
MD_API void md_varena_commit (MD_VArena* vm, MD_SSIZE commit_size);
MD_API void md_varena_release(MD_VArena* vm);
force_inline void varena_rewind(VArena* vm, SSIZE pos) { vm->commit_used = pos; }
md_force_inline void varena_rewind(MD_VArena* vm, MD_SSIZE pos) { vm->commit_used = pos; }
MD_API void* varena_allocator_proc(void* allocator_data, AllocatorMode mode, SSIZE size, SSIZE alignment, void* old_memory, SSIZE old_size, U64 flags);
MD_API void* md_varena_allocator_proc(void* allocator_data, MD_AllocatorMode mode, MD_SSIZE size, MD_SSIZE alignment, void* old_memory, MD_SSIZE old_size, MD_U64 flags);
#define varena_allocator(vm) (AllocatorInfo) { varena_allocator_proc, vm }
#define md_varena_allocator(vm) (MD_AllocatorInfo) { md_varena_allocator_proc, vm }
typedef struct ByteSlice ByteSlice;
struct ByteSlice
typedef struct MD_ByteSlice MD_ByteSlice;
struct MD_ByteSlice
{
U8* data;
SSIZE len;
MD_U8* data;
MD_SSIZE len;
};
#define mem_to_byteslice(data, len) (ByteSlice){ (U8*)(data), (SSIZE)(len) }
#define md_mem_to_byteslice(data, len) (MD_ByteSlice){ (MD_U8*)(data), (MD_SSIZE)(len) }
// Fixed size arena
typedef struct FArena FArena;
struct FArena
typedef struct MD_FArena MD_FArena;
struct MD_FArena
{
ByteSlice slice;
SSIZE used;
MD_ByteSlice slice;
MD_SSIZE used;
};
#define farena_from_byteslice(slice) (FArena) { slice, 0 }
#define farena_from_memory(data, len) (FArena) { mem_to_byteslice(data, len), 0 }
#define md_farena_from_byteslice(slice) (MD_FArena) { slice, 0 }
#define md_farena_from_memory(data, len) (MD_FArena) { md_mem_to_byteslice(data, len), 0 }
MD_API void* farena_allocator_proc(void* allocator_data, AllocatorMode mode, SSIZE size, SSIZE alignment, void* old_memory, SSIZE old_size, U64 flags);
MD_API void* farena_allocator_proc(void* allocator_data, MD_AllocatorMode mode, MD_SSIZE size, MD_SSIZE alignment, void* old_memory, MD_SSIZE old_size, MD_U64 flags);
#define farena_allocator(arena) (AllocatorInfo){ farena_allocator_proc, & arena }
#define farena_allocator(arena) (MD_AllocatorInfo){ farena_allocator_proc, & arena }
// Inlines
inline AllocatorType
allocator_type(AllocatorInfo a) {
if (a.proc == nullptr) {
a = default_allocator();
inline MD_AllocatorType
md_allocator_type(MD_AllocatorInfo a) {
if (a.proc == md_nullptr) {
a = md_default_allocator();
}
return (AllocatorType) a.proc(a.data, AllocatorMode_QueryType, 0, 0, nullptr, 0, MD_DEFAULT_ALLOCATOR_FLAGS);
return (MD_AllocatorType) a.proc(a.data, MD_AllocatorMode_QueryType, 0, 0, md_nullptr, 0, MD_DEFAULT_ALLOCATOR_FLAGS);
}
inline AllocatorQueryFlags
allocator_query_support(AllocatorInfo a) {
if (a.proc == nullptr) {
a = default_allocator();
inline MD_AllocatorQueryFlags
md_allocator_query_support(MD_AllocatorInfo a) {
if (a.proc == md_nullptr) {
a = md_default_allocator();
}
return (AllocatorType) a.proc(a.data, AllocatorMode_QuerySupport, 0, 0, nullptr, 0, MD_DEFAULT_ALLOCATOR_FLAGS);
return (MD_AllocatorType) a.proc(a.data, MD_AllocatorMode_QuerySupport, 0, 0, md_nullptr, 0, MD_DEFAULT_ALLOCATOR_FLAGS);
}
inline void*
alloc_align( AllocatorInfo a, SSIZE size, SSIZE alignment ) {
if (a.proc == nullptr) {
a = default_allocator();
md_alloc_align( MD_AllocatorInfo a, MD_SSIZE size, MD_SSIZE alignment ) {
if (a.proc == md_nullptr) {
a = md_default_allocator();
}
return a.proc( a.data, AllocatorMode_Alloc, size, alignment, nullptr, 0, MD_DEFAULT_ALLOCATOR_FLAGS );
return a.proc( a.data, MD_AllocatorMode_Alloc, size, alignment, md_nullptr, 0, MD_DEFAULT_ALLOCATOR_FLAGS );
}
inline void*
alloc( AllocatorInfo a, SSIZE size ) {
if (a.proc == nullptr) {
a = default_allocator();
md_alloc( MD_AllocatorInfo a, MD_SSIZE size ) {
if (a.proc == md_nullptr) {
a = md_default_allocator();
}
return alloc_align( a, size, MD_DEFAULT_MEMORY_ALIGNMENT );
return md_alloc_align( a, size, MD_DEFAULT_MEMORY_ALIGNMENT );
}
inline void
alloc_free( AllocatorInfo a, void* ptr ) {
if (a.proc == nullptr) {
a = default_allocator();
md_alloc_free( MD_AllocatorInfo a, void* ptr ) {
if (a.proc == md_nullptr) {
a = md_default_allocator();
}
if ( ptr != nullptr ) {
a.proc( a.data, AllocatorMode_Free, 0, 0, ptr, 0, MD_DEFAULT_ALLOCATOR_FLAGS );
if ( ptr != md_nullptr ) {
a.proc( a.data, MD_AllocatorMode_Free, 0, 0, ptr, 0, MD_DEFAULT_ALLOCATOR_FLAGS );
}
}
inline void
free_all( AllocatorInfo a ) {
if (a.proc == nullptr) {
a = default_allocator();
md_free_all( MD_AllocatorInfo a ) {
if (a.proc == md_nullptr) {
a = md_default_allocator();
}
a.proc( a.data, AllocatorMode_FreeAll, 0, 0, nullptr, 0, MD_DEFAULT_ALLOCATOR_FLAGS );
a.proc( a.data, MD_AllocatorMode_FreeAll, 0, 0, md_nullptr, 0, MD_DEFAULT_ALLOCATOR_FLAGS );
}
inline void*
resize( AllocatorInfo a, void* ptr, SSIZE old_size, SSIZE new_size ) {
if (a.proc == nullptr) {
a = default_allocator();
md_resize( MD_AllocatorInfo a, void* ptr, MD_SSIZE old_size, MD_SSIZE new_size ) {
if (a.proc == md_nullptr) {
a = md_default_allocator();
}
return resize_align( a, ptr, old_size, new_size, MD_DEFAULT_ALLOCATOR_FLAGS );
return md_resize_align( a, ptr, old_size, new_size, MD_DEFAULT_ALLOCATOR_FLAGS );
}
inline void*
resize_align( AllocatorInfo a, void* ptr, SSIZE old_size, SSIZE new_size, SSIZE alignment ) {
if (a.proc == nullptr) {
a = default_allocator();
md_resize_align( MD_AllocatorInfo a, void* ptr, MD_SSIZE old_size, MD_SSIZE new_size, MD_SSIZE alignment ) {
if (a.proc == md_nullptr) {
a = md_default_allocator();
}
return a.proc( a.data, AllocatorMode_Resize, new_size, alignment, ptr, old_size, MD_DEFAULT_ALLOCATOR_FLAGS );
return a.proc( a.data, MD_AllocatorMode_Resize, new_size, alignment, ptr, old_size, MD_DEFAULT_ALLOCATOR_FLAGS );
}
+2 -2
View File
@@ -6,13 +6,13 @@
#include <stdarg.h>
#include <stddef.h>
#if defined( OS_WINDOWS )
#if defined( MD_OS_WINDOWS )
# include <intrin.h>
# include <tmmintrin.h>
# include <wmmintrin.h>
#endif
#if LANG_C
#if MD_LANG_C
# include <assert.h>
# include <stdbool.h>
#endif
+38 -38
View File
@@ -9,20 +9,20 @@
////////////////////////////////
//~ rjf: Zero Settings
#if !defined(PROFILE_TELEMETRY)
# define PROFILE_TELEMETRY 0
#if !defined(MD_PROFILE_TELEMETRY)
# define MD_PROFILE_TELEMETRY 0
#endif
#if !defined(MARKUP_LAYER_COLOR)
# define MARKUP_LAYER_COLOR 1.00f, 0.00f, 1.00f
#if !defined(MD_MARKUP_LAYER_COLOR)
# define MD_MARKUP_LAYER_COLOR 1.00f, 0.00f, 1.00f
#endif
////////////////////////////////
//~ rjf: Third Party Includes
#if PROFILE_TELEMETRY
#if MD_PROFILE_TELEMETRY
# include "rad_tm.h"
# if OS_WINDOWS
# if MD_OS_WINDOWS
# pragma comment(lib, "rad_tm_win64.lib")
# endif
#endif
@@ -30,21 +30,21 @@
////////////////////////////////
//~ rjf: Telemetry Profile Defines
#if PROFILE_TELEMETRY
# define prof_begin(...) tmEnter(0, 0, __VA_ARGS__)
# define prof_begin_dynamic(...) (TM_API_PTR ? TM_API_PTR->_tmEnterZoneV_Core(0, 0, __FILE__, &g_telemetry_filename_id, __LINE__, __VA_ARGS__) : (void)0)
# define prof_end(...) (TM_API_PTR ? TM_API_PTR->_tmLeaveZone(0) : (void)0)
# define prof_tick(...) tmTick(0)
# define prof_is_capturing(...) tmRunning()
# define prof_begin_capture(...) tmOpen(0, __VA_ARGS__, __DATE__, "localhost", TMCT_TCP, TELEMETRY_DEFAULT_PORT, TMOF_INIT_NETWORKING|TMOF_CAPTURE_CONTEXT_SWITCHES, 100)
# define prof_end_capture(...) tmClose(0)
# define prof_thread_name(...) (TM_API_PTR ? TM_API_PTR->_tmThreadName(0, 0, __VA_ARGS__) : (void)0)
# define prof_msg(...) (TM_API_PTR ? TM_API_PTR->_tmMessageV_Core(0, TMMF_ICON_NOTE, __FILE__, &g_telemetry_filename_id, __LINE__, __VA_ARGS__) : (void)0)
# define prof_begin_lock_wait(...) tmStartWaitForLock(0, 0, __VA_ARGS__)
# define prof_end_lock_wait(...) tmEndWaitForLock(0)
# define prof_lock_take(...) tmAcquiredLock(0, 0, __VA_ARGS__)
# define prof_lock_drop(...) tmReleasedLock(0, __VA_ARGS__)
# define prof_color(color) tmZoneColorSticky(color)
#if MD_PROFILE_TELEMETRY
# define md_prof_begin(...) tmEnter(0, 0, __VA_ARGS__)
# define md_prof_begin_dynamic(...) (TM_API_PTR ? TM_API_PTR->_tmEnterZoneV_Core(0, 0, __FILE__, &g_telemetry_filename_id, __LINE__, __VA_ARGS__) : (void)0)
# define md_prof_end(...) (TM_API_PTR ? TM_API_PTR->_tmLeaveZone(0) : (void)0)
# define md_prof_tick(...) tmTick(0)
# define md_prof_is_capturing(...) tmRunning()
# define md_prof_begin_capture(...) tmOpen(0, __VA_ARGS__, __DATE__, "localhost", TMCT_TCP, TELEMETRY_DEFAULT_PORT, TMOF_INIT_NETWORKING|TMOF_CAPTURE_CONTEXT_SWITCHES, 100)
# define md_prof_end_capture(...) tmClose(0)
# define md_prof_thread_name(...) (TM_API_PTR ? TM_API_PTR->_tmThreadName(0, 0, __VA_ARGS__) : (void)0)
# define md_prof_msg(...) (TM_API_PTR ? TM_API_PTR->_tmMessageV_Core(0, TMMF_ICON_NOTE, __FILE__, &g_telemetry_filename_id, __LINE__, __VA_ARGS__) : (void)0)
# define md_prof_begin_lock_wait(...) tmStartWaitForLock(0, 0, __VA_ARGS__)
# define md_prof_end_lock_wait(...) tmEndWaitForLock(0)
# define md_prof_lock_take(...) tmAcquiredLock(0, 0, __VA_ARGS__)
# define md_prof_lock_drop(...) tmReleasedLock(0, __VA_ARGS__)
# define md_prof_color(color) tmZoneColorSticky(color)
#endif
// TODO(Ed): Support spall?
@@ -53,25 +53,25 @@
////////////////////////////////
//~ rjf: Zeroify Undefined Defines
#if !defined(prof_begin)
# define prof_begin(...) (0)
# define prof_begin_dynamic(...) (0)
# define prof_end(...) (0)
# define prof_tick(...) (0)
# define prof_is_capturing(...) (0)
# define prof_begin_capture(...) (0)
# define prof_end_capture(...) (0)
# define prof_thread_name(...) (0)
# define prof_msg(...) (0)
# define prof_end_lock_wait(...) (0)
# define prof_end_lock_wait(...) (0)
# define prof_lock_take(...) (0)
# define prof_lock_drop(...) (0)
# define prof_color(...) (0)
#if !defined(md_prof_begin)
# define md_prof_begin(...) (0)
# define md_prof_begin_dynamic(...) (0)
# define md_prof_end(...) (0)
# define md_prof_tick(...) (0)
# define md_prof_is_capturing(...) (0)
# define md_prof_begin_capture(...) (0)
# define md_prof_end_capture(...) (0)
# define md_prof_thread_name(...) (0)
# define md_prof_msg(...) (0)
# define md_prof_end_lock_wait(...) (0)
# define md_prof_end_lock_wait(...) (0)
# define md_prof_lock_take(...) (0)
# define md_prof_lock_drop(...) (0)
# define md_prof_color(...) (0)
#endif
////////////////////////////////
//~ rjf: Helper Wrappers
#define prof_begin_function(...) prof_begin(this_function_name)
#define prof_scope(...) defer_loop(prof_begin_dynamic(__VA_ARGS__), ProfEnd())
#define md_prof_begin_function(...) md_prof_begin(md_this_function_name)
#define md_prof_scope(...) md_defer_loop(md_prof_begin_dynamic(__VA_ARGS__), ProfEnd())
+23 -23
View File
@@ -6,41 +6,41 @@
////////////////////////////////
//~ rjf: Non-Fancy Ring Buffer Reads/Writes
U64 ring_write(U8* ring_base, U64 ring_size, U64 ring_pos, void* src_data, U64 src_data_size);
U64 ring_read (U8* ring_base, U64 ring_size, U64 ring_pos, void* dst_data, U64 read_size);
MD_U64 md_ring_write(MD_U8* md_ring_base, MD_U64 md_ring_size, MD_U64 md_ring_pos, void* src_data, MD_U64 src_data_size);
MD_U64 md_ring_read (MD_U8* md_ring_base, MD_U64 md_ring_size, MD_U64 md_ring_pos, void* dst_data, MD_U64 read_size);
#define ring_write_struct(ring_base, ring_size, ring_pos, ptr) ring_write((ring_base), (ring_size), (ring_pos), (ptr), sizeof(*(ptr)))
#define ring_read_struct(ring_base, ring_size, ring_pos, ptr) ring_read ((ring_base), (ring_size), (ring_pos), (ptr), sizeof(*(ptr)))
#define md_ring_write_struct(md_ring_base, md_ring_size, md_ring_pos, ptr) md_ring_write((md_ring_base), (md_ring_size), (md_ring_pos), (ptr), sizeof(*(ptr)))
#define md_ring_read_struct(md_ring_base, md_ring_size, md_ring_pos, ptr) md_ring_read ((md_ring_base), (md_ring_size), (md_ring_pos), (ptr), sizeof(*(ptr)))
////////////////////////////////
//~ rjf: Non-Fancy Ring Buffer Reads/Writes
inline U64
ring_write(U8* ring_base, U64 ring_size, U64 ring_pos, void* src_data, U64 src_data_size) {
assert(src_data_size <= ring_size);
inline MD_U64
md_ring_write(MD_U8* md_ring_base, MD_U64 md_ring_size, MD_U64 md_ring_pos, void* src_data, MD_U64 src_data_size) {
md_assert(src_data_size <= md_ring_size);
{
U64 ring_off = ring_pos % ring_size;
U64 bytes_before_split = ring_size - ring_off;
U64 pre_split_bytes = min(bytes_before_split, src_data_size);
U64 pst_split_bytes = src_data_size - pre_split_bytes;
MD_U64 md_ring_off = md_ring_pos % md_ring_size;
MD_U64 bytes_before_split = md_ring_size - md_ring_off;
MD_U64 pre_split_bytes = md_min(bytes_before_split, src_data_size);
MD_U64 pst_split_bytes = src_data_size - pre_split_bytes;
void* pre_split_data = src_data;
void* pst_split_data = ((U8*)src_data + pre_split_bytes);
memory_copy(ring_base + ring_off, pre_split_data, pre_split_bytes);
memory_copy(ring_base + 0, pst_split_data, pst_split_bytes);
void* pst_split_data = ((MD_U8*)src_data + pre_split_bytes);
md_memory_copy(md_ring_base + md_ring_off, pre_split_data, pre_split_bytes);
md_memory_copy(md_ring_base + 0, pst_split_data, pst_split_bytes);
}
return src_data_size;
}
inline U64
ring_read(U8* ring_base, U64 ring_size, U64 ring_pos, void* dst_data, U64 read_size) {
assert(read_size <= ring_size);
inline MD_U64
md_ring_read(MD_U8* md_ring_base, MD_U64 md_ring_size, MD_U64 md_ring_pos, void* dst_data, MD_U64 read_size) {
md_assert(read_size <= md_ring_size);
{
U64 ring_off = ring_pos % ring_size;
U64 bytes_before_split = ring_size-ring_off;
U64 pre_split_bytes = min(bytes_before_split, read_size);
U64 pst_split_bytes = read_size - pre_split_bytes;
memory_copy(dst_data, ring_base+ring_off, pre_split_bytes);
memory_copy((U8*)dst_data + pre_split_bytes, ring_base + 0, pst_split_bytes);
MD_U64 md_ring_off = md_ring_pos % md_ring_size;
MD_U64 bytes_before_split = md_ring_size-md_ring_off;
MD_U64 pre_split_bytes = md_min(bytes_before_split, read_size);
MD_U64 pst_split_bytes = read_size - pre_split_bytes;
md_memory_copy(dst_data, md_ring_base+md_ring_off, pre_split_bytes);
md_memory_copy((MD_U8*)dst_data + pre_split_bytes, md_ring_base + 0, pst_split_bytes);
}
return read_size;
}
+2 -2
View File
@@ -5,6 +5,6 @@
////////////////////////////////
//~ rjf: Sorts
#ifndef quick_sort
#define quick_sort(ptr, count, element_size, cmp_function) qsort((ptr), (count), (element_size), (int (*)(const void *, const void *))(cmp_function))
#ifndef md_quick_sort
#define md_quick_sort(ptr, count, element_size, cmp_function) qsort((ptr), (count), (element_size), (int (*)(const void *, const void *))(cmp_function))
#endif
+40 -40
View File
@@ -6,62 +6,62 @@
////////////////////////////////
//~ rjf: Basic Types & Spaces
typedef enum Dimension Dimension;
enum Dimension
typedef enum MD_Dimension MD_Dimension;
enum MD_Dimension
{
Dimension_X,
Dimension_Y,
Dimension_Z,
Dimension_W,
MD_Dimension_X,
MD_Dimension_Y,
MD_Dimension_Z,
MD_Dimension_W,
};
typedef enum Side Side;
enum Side
typedef enum MD_Side MD_Side;
enum MD_Side
{
Side_Invalid = -1,
Side_Min,
Side_Max,
Side_COUNT,
MD_Side_Invalid = -1,
MD_Side_Min,
MD_Side_Max,
MD_Side_COUNT,
};
#define side_flip(s) ((Side)(!(s)))
#define side_flip(s) ((MD_Side)(!(s)))
typedef enum Axis2 Axis2;
enum Axis2
typedef enum MD_Axis2 MD_Axis2;
enum MD_Axis2
{
Axis2_Invalid = -1,
Axis2_X,
Axis2_Y,
Axis2_COUNT,
MD_Axis2_Invalid = -1,
MD_Axis2_X,
MD_Axis2_Y,
MD_Axis2_COUNT,
};
#define axis2_flip(a) ((Axis2)(!(a)))
#define axis2_flip(a) ((MD_Axis2)(!(a)))
typedef enum Corner Corner;
enum Corner
typedef enum MD_corner MD_corner;
enum MD_corner
{
Corner_Invalid = -1,
Corner_00,
Corner_01,
Corner_10,
Corner_11,
Corner_COUNT
MD_Corner_Invalid = -1,
MD_Corner_00,
MD_Corner_01,
MD_Corner_10,
MD_Corner_11,
MD_Corner_COUNT
};
typedef enum Dir2 Dir2;
enum Dir2
typedef enum MD_Dir2 MD_Dir2;
enum MD_Dir2
{
Dir2_Invalid = -1,
Dir2_Left,
Dir2_Up,
Dir2_Right,
Dir2_Down,
Dir2_COUNT
MD_Dir2_Invalid = -1,
MD_Dir2_Left,
MD_Dir2_Up,
MD_Dir2_Right,
MD_Dir2_Down,
MD_Dir2_COUNT
};
#define axis2_from_dir2(d) (((d) & 1) ? Axis2_Y : Axis2_X)
#define side_from_dir2(d) (((d) < Dir2_Right) ? Side_Min : Side_Max)
#define md_axis2_from_dir2(d) (((d) & 1) ? MD_Axis2_Y : MD_Axis2_X)
#define md_side_from_dir2(d) (((d) < MD_Dir2_Right) ? MD_Side_Min : MD_Side_Max)
////////////////////////////////
//~ rjf: Enum -> Sign
inline S32 sign_from_side_S32(Side side) { return((side == Side_Min) ? -1 : 1 ); }
inline F32 sign_from_side_F32(Side side) { return((side == Side_Min) ? -1.f : 1.f); }
inline MD_S32 md_sign_from_side_S32(MD_Side side) { return((side == MD_Side_Min) ? -1 : 1 ); }
inline MD_F32 md_sign_from_side_F32(MD_Side side) { return((side == MD_Side_Min) ? -1.f : 1.f); }
+629 -629
View File
File diff suppressed because it is too large Load Diff
+687 -687
View File
File diff suppressed because it is too large Load Diff
+19 -19
View File
@@ -5,23 +5,23 @@
////////////////////////////////
//~ rjf: Text Path Helpers
String8TxtPtPair
str8_txt_pt_pair_from_string(String8 string)
MD_String8TxtPtPair
md_str8_txt_pt_pair_from_string(MD_String8 string)
{
String8TxtPtPair pair = {0};
MD_String8TxtPtPair pair = {0};
{
String8 file_part = {0};
String8 line_part = {0};
String8 col_part = {0};
MD_String8 file_part = {0};
MD_String8 line_part = {0};
MD_String8 col_part = {0};
// rjf: grab file part
for(U64 idx = 0; idx <= string.size; idx += 1)
for(MD_U64 idx = 0; idx <= string.size; idx += 1)
{
U8 byte = (idx < string.size) ? (string.str[idx ]) : 0;
U8 next_byte = ((idx + 1 < string.size) ? (string.str[idx + 1]) : 0);
MD_U8 byte = (idx < string.size) ? (string.str[idx ]) : 0;
MD_U8 next_byte = ((idx + 1 < string.size) ? (string.str[idx + 1]) : 0);
if(byte == ':' && next_byte != '/' && next_byte != '\\') {
file_part = str8_prefix(string, idx);
line_part = str8_skip(string, idx+1);
file_part = md_str8_prefix(string, idx);
line_part = md_str8_skip(string, idx+1);
break;
}
else if(byte == 0) {
@@ -31,22 +31,22 @@ str8_txt_pt_pair_from_string(String8 string)
}
// rjf: grab line/column
{
U64 colon_pos = str8_find_needle(line_part, 0, str8_lit(":"), 0);
MD_U64 colon_pos = md_str8_find_needle(line_part, 0, md_str8_lit(":"), 0);
if(colon_pos < line_part.size) {
col_part = str8_skip (line_part, colon_pos + 1);
line_part = str8_prefix(line_part, colon_pos);
col_part = md_str8_skip (line_part, colon_pos + 1);
line_part = md_str8_prefix(line_part, colon_pos);
}
}
// rjf: convert line/column strings to numerics
U64 line = 0;
U64 column = 0;
try_u64_from_str8_c_rules(line_part, &line);
try_u64_from_str8_c_rules(col_part, &column);
MD_U64 line = 0;
MD_U64 column = 0;
md_try_u64_from_str8_c_rules(line_part, &line);
md_try_u64_from_str8_c_rules(col_part, &column);
// rjf: fill
pair.string = file_part;
pair.pt = txt_pt((S64)line, (S64)column);
pair.pt = md_txt_pt((MD_S64)line, (MD_S64)column);
if(pair.pt.line == 0) { pair.pt.line = 1; }
if(pair.pt.column == 0) { pair.pt.column = 1; }
}
+47 -47
View File
@@ -6,54 +6,54 @@
////////////////////////////////
//~ rjf: Text 2D Coordinates & Ranges
typedef struct TxtPt TxtPt;
struct TxtPt
typedef struct MD_TxtPt MD_TxtPt;
struct MD_TxtPt
{
S64 line;
S64 column;
MD_S64 line;
MD_S64 column;
};
typedef struct TxtRng TxtRng;
struct TxtRng
typedef struct MD_TxtRng MD_TxtRng;
struct MD_TxtRng
{
TxtPt min;
TxtPt max;
MD_TxtPt md_min;
MD_TxtPt md_max;
};
////////////////////////////////
//~ rjf: String Pair Types
typedef struct String8TxtPtPair String8TxtPtPair;
struct String8TxtPtPair
typedef struct MD_String8TxtPtPair MD_String8TxtPtPair;
struct MD_String8TxtPtPair
{
String8 string;
TxtPt pt;
MD_String8 string;
MD_TxtPt pt;
};
////////////////////////////////
//~ rjf: Text Path Helpers
MD_API String8TxtPtPair str8_txt_pt_pair_from_string(String8 string);
MD_API MD_String8TxtPtPair md_str8_txt_pt_pair_from_string(MD_String8 string);
////////////////////////////////
//~ rjf: Text 2D Coordinate/Range Functions
inline TxtPt txt_pt(S64 line, S64 column) { TxtPt p = { line, column }; return p; }
inline MD_TxtPt md_txt_pt(MD_S64 line, MD_S64 column) { MD_TxtPt p = { line, column }; return p; }
inline B32 txt_pt_match(TxtPt a, TxtPt b) { return a.line == b.line && a.column == b.column; }
inline TxtPt txt_pt_min (TxtPt a, TxtPt b) { TxtPt result = b; if (txt_pt_less_than(a, b)) { result = a; } return result; }
inline TxtPt txt_pt_max (TxtPt a, TxtPt b) { TxtPt result = a; if (txt_pt_less_than(a, b)) { result = b; } return result; }
inline MD_B32 md_txt_pt_match(MD_TxtPt a, MD_TxtPt b) { return a.line == b.line && a.column == b.column; }
inline MD_TxtPt md_txt_pt_min (MD_TxtPt a, MD_TxtPt b) { MD_TxtPt result = b; if (md_txt_pt_less_than(a, b)) { result = a; } return result; }
inline MD_TxtPt md_txt_pt_max (MD_TxtPt a, MD_TxtPt b) { MD_TxtPt result = a; if (md_txt_pt_less_than(a, b)) { result = b; } return result; }
B32 txt_pt_less_than (TxtPt a, TxtPt b);
TxtRng txt_rng (TxtPt min, TxtPt max);
TxtRng txt_rng_intersect(TxtRng a, TxtRng b);
TxtRng txt_rng_union (TxtRng a, TxtRng b);
B32 txt_rng_contains (TxtRng r, TxtPt pt);
MD_B32 md_txt_pt_less_than (MD_TxtPt a, MD_TxtPt b);
MD_TxtRng md_txt_rng (MD_TxtPt md_min, MD_TxtPt md_max);
MD_TxtRng md_txt_rng_intersect(MD_TxtRng a, MD_TxtRng b);
MD_TxtRng md_txt_rng_union (MD_TxtRng a, MD_TxtRng b);
MD_B32 md_txt_rng_contains (MD_TxtRng r, MD_TxtPt pt);
inline B32
txt_pt_less_than(TxtPt a, TxtPt b)
inline MD_B32
md_txt_pt_less_than(MD_TxtPt a, MD_TxtPt b)
{
B32 result = 0;
MD_B32 result = 0;
if (a.line < b.line) {
result = 1;
}
@@ -63,44 +63,44 @@ txt_pt_less_than(TxtPt a, TxtPt b)
return result;
}
inline TxtRng
txt_rng(TxtPt min, TxtPt max)
inline MD_TxtRng
md_txt_rng(MD_TxtPt md_min, MD_TxtPt md_max)
{
TxtRng range = {0};
if(txt_pt_less_than(min, max)) {
range.min = min;
range.max = max;
MD_TxtRng range = {0};
if(md_txt_pt_less_than(md_min, md_max)) {
range.md_min = md_min;
range.md_max = md_max;
}
else {
range.min = max;
range.max = min;
range.md_min = md_max;
range.md_max = md_min;
}
return range;
}
inline TxtRng
txt_rng_intersect(TxtRng a, TxtRng b)
inline MD_TxtRng
md_txt_rng_intersect(MD_TxtRng a, MD_TxtRng b)
{
TxtRng result = {0};
result.min = txt_pt_max(a.min, b.min);
result.max = txt_pt_min(a.max, b.max);
if (txt_pt_less_than(result.max, result.min)) {
MD_TxtRng result = {0};
result.md_min = md_txt_pt_max(a.md_min, b.md_min);
result.md_max = md_txt_pt_min(a.md_max, b.md_max);
if (md_txt_pt_less_than(result.md_max, result.md_min)) {
MemoryZeroStruct(&result);
}
return result;
}
inline TxtRng
txt_rng_union(TxtRng a, TxtRng b)
inline MD_TxtRng
md_txt_rng_union(MD_TxtRng a, MD_TxtRng b)
{
TxtRng result = {0};
result.min = txt_pt_min(a.min, b.min);
result.max = txt_pt_max(a.max, b.max);
MD_TxtRng result = {0};
result.md_min = md_txt_pt_min(a.md_min, b.md_min);
result.md_max = md_txt_pt_max(a.md_max, b.md_max);
return result;
}
inline B32
txt_rng_contains(TxtRng r, TxtPt pt) {
B32 result = ((txt_pt_less_than(r.min, pt) || txt_pt_match(r.min, pt)) && txt_pt_less_than(pt, r.max));
inline MD_B32
md_txt_rng_contains(MD_TxtRng r, MD_TxtPt pt) {
MD_B32 result = ((md_txt_pt_less_than(r.md_min, pt) || md_txt_pt_match(r.md_min, pt)) && md_txt_pt_less_than(pt, r.md_max));
return result;
}
+35 -35
View File
@@ -7,79 +7,79 @@
// Licensed under the MIT license (https://opensource.org/license/mit/)
////////////////////////////////
// NOTE(allen): Thread Context Functions
// NOTE(allen): Thread MD_Context Functions
MD_API_C thread_static TCTX* tctx_thread_local;
MD_API_C md_thread_static MD_TCTX* md_tctx_thread_local;
#if ! MD_BUILD_SUPPLEMENTARY_UNIT
MD_API_C thread_static TCTX* tctx_thread_local = 0;
MD_API_C md_thread_static MD_TCTX* md_tctx_thread_local = 0;
#endif
void
tctx_init_and_equip(TCTX* tctx)
md_tctx_init_and_equip(MD_TCTX* md_tctx)
{
// memory_zero_struct(tctx);
// md_memory_zero_struct(md_tctx);
Arena** arena_ptr = tctx->arenas;
for (U64 i = 0; i < array_count(tctx->arenas); i += 1, arena_ptr += 1)
MD_Arena** md_arena_ptr = md_tctx->arenas;
for (MD_U64 i = 0; i < md_array_count(md_tctx->arenas); i += 1, md_arena_ptr += 1)
{
if (*arena_ptr == nullptr)
if (*md_arena_ptr == md_nullptr)
{
VArena* vm = varena_alloc(.reserve_size = VARENA_DEFAULT_RESERVE, .commit_size = VARENA_DEFAULT_COMMIT);
*arena_ptr = arena_alloc(.backing = varena_allocator(vm));
MD_VArena* vm = md_varena_alloc(.reserve_size = MD_VARENA_DEFAULT_RESERVE, .commit_size = MD_VARENA_DEFAULT_COMMIT);
*md_arena_ptr = md_arena_alloc(.backing = md_varena_allocator(vm));
}
}
tctx_thread_local = tctx;
md_tctx_thread_local = md_tctx;
}
void
tctx_init_and_equip_alloc(TCTX* tctx, AllocatorInfo ainfo)
md_tctx_init_and_equip_alloc(MD_TCTX* md_tctx, MD_AllocatorInfo ainfo)
{
memory_zero_struct(tctx);
md_memory_zero_struct(md_tctx);
Arena** arena_ptr = tctx->arenas;
for (U64 i = 0; i < array_count(tctx->arenas); i += 1, arena_ptr += 1)
MD_Arena** md_arena_ptr = md_tctx->arenas;
for (MD_U64 i = 0; i < md_array_count(md_tctx->arenas); i += 1, md_arena_ptr += 1)
{
if (*arena_ptr == nullptr)
if (*md_arena_ptr == md_nullptr)
{
*arena_ptr = arena_alloc(.backing = ainfo);
*md_arena_ptr = md_arena_alloc(.backing = ainfo);
}
}
tctx_thread_local = tctx;
md_tctx_thread_local = md_tctx;
}
void
tctx_release(void) {
for (U64 i = 0; i < array_count(tctx_thread_local->arenas); i += 1) {
arena_release(tctx_thread_local->arenas[i]);
md_tctx_release(void) {
for (MD_U64 i = 0; i < md_array_count(md_tctx_thread_local->arenas); i += 1) {
md_arena_release(md_tctx_thread_local->arenas[i]);
}
}
TCTX*
tctx_get_equipped(void){
return(tctx_thread_local);
MD_TCTX*
md_tctx_get_equipped(void){
return(md_tctx_thread_local);
}
Arena*
tctx_get_scratch(Arena** conflicts, U64 count)
MD_Arena*
md_tctx_get_scratch(MD_Arena** conflicts, MD_U64 count)
{
TCTX* tctx = tctx_get_equipped();
MD_TCTX* md_tctx = md_tctx_get_equipped();
Arena* result = 0;
Arena** arena_ptr = tctx->arenas;
for (U64 i = 0; i < array_count(tctx->arenas); i += 1, arena_ptr += 1)
MD_Arena* result = 0;
MD_Arena** md_arena_ptr = md_tctx->arenas;
for (MD_U64 i = 0; i < md_array_count(md_tctx->arenas); i += 1, md_arena_ptr += 1)
{
Arena** conflict_ptr = conflicts;
B32 has_conflict = 0;
for (U64 j = 0; j < count; j += 1, conflict_ptr += 1)
MD_Arena** conflict_ptr = conflicts;
MD_B32 has_conflict = 0;
for (MD_U64 j = 0; j < count; j += 1, conflict_ptr += 1)
{
if (*arena_ptr == *conflict_ptr) {
if (*md_arena_ptr == *conflict_ptr) {
has_conflict = 1;
break;
}
}
if ( ! has_conflict){
result = *arena_ptr;
result = *md_arena_ptr;
break;
}
}
+48 -48
View File
@@ -8,83 +8,83 @@
// Licensed under the MIT license (https://opensource.org/license/mit/)
////////////////////////////////
// NOTE(allen): Thread Context
// NOTE(allen): Thread MD_Context
typedef struct TCTX TCTX;
struct TCTX
typedef struct MD_TCTX MD_TCTX;
struct MD_TCTX
{
Arena* arenas[2];
MD_Arena* arenas[2];
U8 thread_name[32];
U64 thread_name_size;
MD_U8 md_thread_name[32];
MD_U64 thread_name_size;
char* file_name;
U64 line_number;
MD_U64 line_number;
};
////////////////////////////////
// NOTE(allen): Thread Context Functions
// NOTE(allen): Thread MD_Context Functions
MD_API void tctx_init_and_equip (TCTX* tctx);
MD_API void tctx_init_and_equip_alloc(TCTX* tctx, AllocatorInfo ainfo);
MD_API void tctx_release (void);
MD_API TCTX* tctx_get_equipped (void);
MD_API void md_tctx_init_and_equip (MD_TCTX* md_tctx);
MD_API void md_tctx_init_and_equip_alloc(MD_TCTX* md_tctx, MD_AllocatorInfo ainfo);
MD_API void md_tctx_release (void);
MD_API MD_TCTX* md_tctx_get_equipped (void);
MD_API Arena* tctx_get_scratch(Arena** conflicts, U64 count);
MD_API MD_Arena* md_tctx_get_scratch(MD_Arena** conflicts, MD_U64 count);
void tctx_set_thread_name(String8 name);
String8 tctx_get_thread_name(void);
void md_tctx_set_thread_name(MD_String8 name);
MD_String8 md_tctx_get_thread_name(void);
void tctx_write_srcloc(char* file_name, U64 line_number);
void tctx_read_srcloc (char** file_name, U64* line_number);
#define tctx_write_this_srcloc() tctx_write_srcloc(__FILE__, __LINE__)
void md_tctx_write_srcloc(char* file_name, MD_U64 line_number);
void md_tctx_read_srcloc (char** file_name, MD_U64* line_number);
#define md_tctx_write_this_srcloc() md_tctx_write_srcloc(__FILE__, __LINE__)
typedef struct { U64 count; } Opt_ScratchBegin;
typedef struct { MD_U64 count; } Opt_ScratchBegin;
inline TempArena
scratch_begin__ainfo(AllocatorInfo ainfo, Opt_ScratchBegin opt) {
Arena* arena = extract_arena(ainfo);
TempArena scratch = temp_begin(tctx_get_scratch(&arena, arena != nullptr));
inline MD_TempArena
md_scratch_begin__ainfo(MD_AllocatorInfo ainfo, Opt_ScratchBegin opt) {
MD_Arena* arena = md_extract_arena(ainfo);
MD_TempArena scratch = md_temp_begin(md_tctx_get_scratch(&arena, arena != md_nullptr));
return scratch;
}
force_inline TempArena scratch_begin__arena(Arena** arena, Opt_ScratchBegin opt) { TempArena scratch = temp_begin(tctx_get_scratch(arena, opt.count)); return scratch; }
md_force_inline MD_TempArena md_scratch_begin__arena(MD_Arena** arena, Opt_ScratchBegin opt) { MD_TempArena scratch = md_temp_begin(md_tctx_get_scratch(arena, opt.count)); return scratch; }
#define scratch_begin(conflicts, ...) \
#define md_scratch_begin(conflicts, ...) \
_Generic(conflicts, \
int : scratch_begin__arena, \
Arena** : scratch_begin__arena, \
AllocatorInfo: scratch_begin__ainfo, \
default : assert_generic_sel_fail \
) generic_call(conflicts, (Opt_ScratchBegin){__VA_ARGS__})
int : md_scratch_begin__arena, \
MD_Arena** : md_scratch_begin__arena, \
MD_AllocatorInfo: md_scratch_begin__ainfo, \
default : md_assert_generic_sel_fail \
) md_generic_call(conflicts, (Opt_ScratchBegin){__VA_ARGS__})
#define scratch_end(scratch) temp_end(scratch)
#define scratch_end(scratch) md_temp_end(scratch)
inline void
tctx_set_thread_name(String8 string){
TCTX* tctx = tctx_get_equipped();
U64 size = clamp_top(string.size, sizeof(tctx->thread_name));
memory_copy(tctx->thread_name, string.str, size);
tctx->thread_name_size = size;
md_tctx_set_thread_name(MD_String8 string){
MD_TCTX* md_tctx = md_tctx_get_equipped();
MD_U64 size = md_clamp_top(string.size, sizeof(md_tctx->md_thread_name));
md_memory_copy(md_tctx->md_thread_name, string.str, size);
md_tctx->thread_name_size = size;
}
inline String8
tctx_get_thread_name(void) {
TCTX* tctx = tctx_get_equipped();
String8 result = str8(tctx->thread_name, tctx->thread_name_size);
inline MD_String8
md_tctx_get_thread_name(void) {
MD_TCTX* md_tctx = md_tctx_get_equipped();
MD_String8 result = md_str8(md_tctx->md_thread_name, md_tctx->thread_name_size);
return(result);
}
inline void
tctx_write_srcloc(char* file_name, U64 line_number){
TCTX *tctx = tctx_get_equipped();
tctx->file_name = file_name;
tctx->line_number = line_number;
md_tctx_write_srcloc(char* file_name, MD_U64 line_number){
MD_TCTX *md_tctx = md_tctx_get_equipped();
md_tctx->file_name = file_name;
md_tctx->line_number = line_number;
}
inline void
tctx_read_srcloc(char** file_name, U64* line_number){
TCTX* tctx = tctx_get_equipped();
*file_name = tctx->file_name;
*line_number = tctx->line_number;
md_tctx_read_srcloc(char** file_name, MD_U64* line_number){
MD_TCTX* md_tctx = md_tctx_get_equipped();
*file_name = md_tctx->file_name;
*line_number = md_tctx->line_number;
}
+20 -20
View File
@@ -3,25 +3,25 @@
# include "time.h"
#endif
DateTime
date_time_from_unix_time(U64 unix_time)
MD_DateTime
md_date_time_from_unix_time(MD_U64 unix_time)
{
DateTime date = {0};
MD_DateTime date = {0};
date.year = 1970;
date.day = 1 + (unix_time / 86400);
date.sec = (U32) unix_time % 60;
date.min = (U32)(unix_time / 60) % 60;
date.hour = (U32)(unix_time / 3600) % 24;
date.sec = (MD_U32) unix_time % 60;
date.md_min = (MD_U32)(unix_time / 60) % 60;
date.hour = (MD_U32)(unix_time / 3600) % 24;
for(;;)
{
for(date.month = 0; date.month < 12; ++date.month)
{
U64 c = 0;
MD_U64 c = 0;
switch(date.month)
{
case Month_Jan: c = 31; break;
case Month_Feb:
case MD_Month_Jan: c = 31; break;
case MD_Month_Feb:
{
if((date.year % 4 == 0) && ((date.year % 100) != 0 || (date.year % 400) == 0))
{
@@ -32,17 +32,17 @@ date_time_from_unix_time(U64 unix_time)
c = 28;
}
} break;
case Month_Mar: c = 31; break;
case Month_Apr: c = 30; break;
case Month_May: c = 31; break;
case Month_Jun: c = 30; break;
case Month_Jul: c = 31; break;
case Month_Aug: c = 31; break;
case Month_Sep: c = 30; break;
case Month_Oct: c = 31; break;
case Month_Nov: c = 30; break;
case Month_Dec: c = 31; break;
default: invalid_path;
case MD_Month_Mar: c = 31; break;
case MD_Month_Apr: c = 30; break;
case MD_Month_May: c = 31; break;
case MD_Month_Jun: c = 30; break;
case MD_Month_Jul: c = 31; break;
case MD_Month_Aug: c = 31; break;
case MD_Month_Sep: c = 30; break;
case MD_Month_Oct: c = 31; break;
case MD_Month_Nov: c = 30; break;
case MD_Month_Dec: c = 31; break;
default: md_invalid_path;
}
if(date.day <= c)
{
+59 -59
View File
@@ -6,110 +6,110 @@
////////////////////////////////
//~ allen: Time
typedef enum WeekDay WeekDay;
enum WeekDay
typedef enum MD_WeekDay MD_WeekDay;
enum MD_WeekDay
{
WeekDay_Sun,
WeekDay_Mon,
WeekDay_Tue,
WeekDay_Wed,
WeekDay_Thu,
WeekDay_Fri,
WeekDay_Sat,
WeekDay_COUNT,
MD_WeekDay_Sun,
MD_WeekDay_Mon,
MD_WeekDay_Tue,
MD_WeekDay_Wed,
MD_WeekDay_Thu,
MD_WeekDay_Fri,
MD_WeekDay_Sat,
MD_WeekDay_COUNT,
};
typedef enum Month Month;
enum Month
typedef enum MD_Month MD_Month;
enum MD_Month
{
Month_Jan,
Month_Feb,
Month_Mar,
Month_Apr,
Month_May,
Month_Jun,
Month_Jul,
Month_Aug,
Month_Sep,
Month_Oct,
Month_Nov,
Month_Dec,
Month_COUNT,
MD_Month_Jan,
MD_Month_Feb,
MD_Month_Mar,
MD_Month_Apr,
MD_Month_May,
MD_Month_Jun,
MD_Month_Jul,
MD_Month_Aug,
MD_Month_Sep,
MD_Month_Oct,
MD_Month_Nov,
MD_Month_Dec,
MD_Month_COUNT,
};
typedef struct DateTime DateTime;
struct DateTime
typedef struct MD_DateTime MD_DateTime;
struct MD_DateTime
{
U16 micro_sec; // [0,999]
U16 msec; // [0,999]
U16 sec; // [0,60]
U16 min; // [0,59]
U16 hour; // [0,24]
U16 day; // [0,30]
MD_U16 micro_sec; // [0,999]
MD_U16 msec; // [0,999]
MD_U16 sec; // [0,60]
MD_U16 md_min; // [0,59]
MD_U16 hour; // [0,24]
MD_U16 day; // [0,30]
union
{
WeekDay week_day;
U32 wday;
MD_WeekDay week_day;
MD_U32 wday;
};
union
{
Month month;
U32 mon;
MD_Month month;
MD_U32 mon;
};
U32 year; // 1 = 1 CE, 0 = 1 BC
MD_U32 year; // 1 = 1 CE, 0 = 1 BC
};
typedef U64 DenseTime;
typedef MD_U64 MD_DenseTime;
////////////////////////////////
//~ rjf: Time Functions
DenseTime dense_time_from_date_time (DateTime date_time);
DateTime date_time_from_dense_time (DenseTime time);
DateTime date_time_from_micro_seconds(U64 time);
DateTime date_time_from_unix_time (U64 unix_time);
MD_DenseTime md_dense_time_from_date_time (MD_DateTime date_time);
MD_DateTime md_date_time_from_dense_time (MD_DenseTime time);
MD_DateTime md_date_time_from_micro_seconds(MD_U64 time);
MD_DateTime md_date_time_from_unix_time (MD_U64 unix_time);
////////////////////////////////
//~ rjf: Time Functions
inline DenseTime
dense_time_from_date_time(DateTime date_time) {
DenseTime result = 0;
inline MD_DenseTime
md_dense_time_from_date_time(MD_DateTime date_time) {
MD_DenseTime result = 0;
result += date_time.year; result *= 12;
result += date_time.mon; result *= 31;
result += date_time.day; result *= 24;
result += date_time.hour; result *= 60;
result += date_time.min; result *= 61;
result += date_time.md_min; result *= 61;
result += date_time.sec; result *= 1000;
result += date_time.msec;
return(result);
}
inline DateTime
date_time_from_dense_time(DenseTime time) {
DateTime result = {0};
inline MD_DateTime
md_date_time_from_dense_time(MD_DenseTime time) {
MD_DateTime result = {0};
result.msec = time % 1000; time /= 1000;
result.sec = time % 61; time /= 61;
result.min = time % 60; time /= 60;
result.md_min = time % 60; time /= 60;
result.hour = time % 24; time /= 24;
result.day = time % 31; time /= 31;
result.mon = time % 12; time /= 12;
assert(time <= MAX_U32);
result.year = (U32)time;
md_assert(time <= MD_MAX_U32);
result.year = (MD_U32)time;
return(result);
}
inline DateTime
date_time_from_micro_seconds(U64 time){
DateTime result = {0};
inline MD_DateTime
md_date_time_from_micro_seconds(MD_U64 time){
MD_DateTime result = {0};
result.micro_sec = time % 1000; time /= 1000;
result.msec = time % 1000; time /= 1000;
result.sec = time % 60; time /= 60;
result.min = time % 60; time /= 60;
result.md_min = time % 60; time /= 60;
result.hour = time % 24; time /= 24;
result.day = time % 31; time /= 31;
result.mon = time % 12; time /= 12;
assert(time <= MAX_U32);
result.year = (U32)time;
md_assert(time <= MD_MAX_U32);
result.year = (MD_U32)time;
return(result);
}
+67 -67
View File
@@ -6,110 +6,110 @@
////////////////////////////////
//~ rjf: Toolchain/Environment Enums
typedef enum OperatingSystem OperatingSystem;
enum OperatingSystem
typedef enum MD_OperatingSystem MD_OperatingSystem;
enum MD_OperatingSystem
{
OperatingSystem_Null,
OperatingSystem_Windows,
OperatingSystem_Linux,
OperatingSystem_Mac,
OperatingSystem_COUNT,
MD_OperatingSystem_Null,
MD_OperatingSystem_Windows,
MD_OperatingSystem_Linux,
MD_OperatingSystem_Mac,
MD_OperatingSystem_COUNT,
};
typedef enum ImageType ImageType;
enum ImageType
typedef enum MD_ImageType MD_ImageType;
enum MD_ImageType
{
Image_Null,
Image_CoffPe,
Image_Elf32,
Image_Elf64,
Image_Macho
MD_Image_Null,
MD_Image_CoffPe,
MD_Image_Elf32,
MD_Image_Elf64,
MD_Image_Macho
};
typedef enum Arch Arch;
enum Arch
typedef enum MD_Arch MD_Arch;
enum MD_Arch
{
Arch_Null,
Arch_x64,
Arch_x86,
Arch_arm64,
Arch_arm32,
Arch_COUNT,
MD_Arch_Null,
MD_Arch_x64,
MD_Arch_x86,
MD_Arch_arm64,
MD_Arch_arm32,
MD_Arch_COUNT,
};
typedef enum Compiler Compiler;
enum Compiler
typedef enum MD_Compiler MD_Compiler;
enum MD_Compiler
{
Compiler_Null,
Compiler_msvc,
Compiler_gcc,
Compiler_clang,
Compiler_COUNT,
MD_Compiler_Null,
MD_Compiler_msvc,
MD_Compiler_gcc,
MD_Compiler_clang,
MD_Compiler_COUNT,
};
////////////////////////////////
//~ rjf: Toolchain/Environment Enum Functions
inline U64
bit_size_from_arch(Arch arch)
inline MD_U64
md_bit_size_from_arch(MD_Arch arch)
{
// TODO(rjf): metacode
U64 arch_bitsize = 0;
MD_U64 arch_bitsize = 0;
switch(arch)
{
case Arch_x64: arch_bitsize = 64; break;
case Arch_x86: arch_bitsize = 32; break;
case Arch_arm64: arch_bitsize = 64; break;
case Arch_arm32: arch_bitsize = 32; break;
case MD_Arch_x64: arch_bitsize = 64; break;
case MD_Arch_x86: arch_bitsize = 32; break;
case MD_Arch_arm64: arch_bitsize = 64; break;
case MD_Arch_arm32: arch_bitsize = 32; break;
default: break;
}
return arch_bitsize;
}
inline U64
max_instruction_size_from_arch(Arch arch)
inline MD_U64
md_max_instruction_size_from_arch(MD_Arch arch)
{
// TODO(rjf): make this real
return 64;
}
inline OperatingSystem
operating_system_from_context(void) {
OperatingSystem os = OperatingSystem_Null;
#if OS_WINDOWS
os = OperatingSystem_Windows;
#elif OS_LINUX
os = OperatingSystem_Linux;
#elif OS_MAC
os = OperatingSystem_Mac;
inline MD_OperatingSystem
md_operating_system_from_context(void) {
MD_OperatingSystem os = MD_OperatingSystem_Null;
#if MD_OS_WINDOWS
os = MD_OperatingSystem_Windows;
#elif MD_OS_LINUX
os = MD_OperatingSystem_Linux;
#elif MD_OS_MAC
os = MD_OperatingSystem_Mac;
#endif
return os;
}
inline Arch
arch_from_context(void) {
Arch arch = Arch_Null;
#if ARCH_X64
arch = Arch_x64;
#elif ARCH_X86
arch = Arch_x86;
#elif ARCH_ARM64
arch = Arch_arm64;
#elif ARCH_ARM32
arch = Arch_arm32;
inline MD_Arch
md_arch_from_contexto(void) {
MD_Arch arch = MD_Arch_Null;
#if MD_ARCH_X64
arch = MD_Arch_x64;
#elif MD_ARCH_X86
arch = MD_Arch_x86;
#elif MD_ARCH_ARM64
arch = MD_Arch_arm64;
#elif MD_ARCH_ARM32
arch = MD_Arch_arm32;
#endif
return arch;
}
inline Compiler
compiler_from_context(void) {
Compiler compiler = Compiler_Null;
#if COMPILER_MSVC
compiler = Compiler_msvc;
#elif COMPILER_GCC
compiler = Compiler_gcc;
#elif COMPILER_CLANG
compiler = Compiler_clang;
inline MD_Compiler
md_compiler_from_context(void) {
MD_Compiler compiler = MD_Compiler_Null;
#if MD_COMPILER_MSVC
compiler = MD_Compiler_msvc;
#elif MD_COMPILER_GCC
compiler = MD_Compiler_gcc;
#elif MD_COMPILER_CLANG
compiler = MD_Compiler_clang;
#endif
return compiler;
}