mirror of
https://github.com/Ed94/metadesk.git
synced 2026-08-07 16:18:49 +00:00
beginning to lift vmem ops out of the arena
This commit is contained in:
Vendored
+6
-1
@@ -16,6 +16,11 @@
|
|||||||
"xmemory": "cpp",
|
"xmemory": "cpp",
|
||||||
"memory.h": "c",
|
"memory.h": "c",
|
||||||
"charconv": "c",
|
"charconv": "c",
|
||||||
"xstring": "c"
|
"xstring": "c",
|
||||||
|
"memory_substrate.h": "c",
|
||||||
|
"os.h": "c",
|
||||||
|
"os_core.h": "c",
|
||||||
|
"file.h": "c",
|
||||||
|
"xiosbase": "c"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+68
-6
@@ -11,7 +11,8 @@
|
|||||||
|
|
||||||
//- rjf: arena creation/destruction
|
//- rjf: arena creation/destruction
|
||||||
|
|
||||||
internal Arena *
|
#if 0
|
||||||
|
internal Arena*
|
||||||
arena_alloc_(ArenaParams *params)
|
arena_alloc_(ArenaParams *params)
|
||||||
{
|
{
|
||||||
// rjf: round up reserve/commit sizes
|
// rjf: round up reserve/commit sizes
|
||||||
@@ -67,17 +68,78 @@ arena_alloc_(ArenaParams *params)
|
|||||||
AsanUnpoisonMemoryRegion(base, ARENA_HEADER_SIZE);
|
AsanUnpoisonMemoryRegion(base, ARENA_HEADER_SIZE);
|
||||||
return arena;
|
return arena;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
internal void
|
Arena*
|
||||||
arena_release(Arena *arena)
|
arena_alloc_(ArenaParams* params)
|
||||||
{
|
{
|
||||||
for(Arena *n = arena->current, *prev = 0; n != 0; n = prev)
|
// rjf: round up reserve/commit sizes
|
||||||
|
U64 reserve_size = params->reserve_size;
|
||||||
|
U64 commit_size = params->commit_size;
|
||||||
|
|
||||||
|
|
||||||
|
if(params->flags & ArenaFlag_LargePages)
|
||||||
{
|
{
|
||||||
prev = n->prev;
|
reserve_size = align_pow2(reserve_size, os_get_system_info()->large_page_size);
|
||||||
os_release(n, n->res);
|
commit_size = align_pow2(commit_size, os_get_system_info()->large_page_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);
|
||||||
|
}
|
||||||
|
|
||||||
|
// rjf: reserve/commit initial block
|
||||||
|
void *base = params->optional_backing_buffer;
|
||||||
|
if(base == 0)
|
||||||
|
{
|
||||||
|
if(params->flags & ArenaFlag_LargePages)
|
||||||
|
{
|
||||||
|
base = os_reserve_large(reserve_size);
|
||||||
|
os_commit_large(base, commit_size);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
base = os_reserve(reserve_size);
|
||||||
|
os_commit(base, commit_size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// rjf: panic on arena creation failure
|
||||||
|
#if OS_FEATURE_GRAPHICAL
|
||||||
|
if(Unlikely(base == 0))
|
||||||
|
{
|
||||||
|
os_graphical_message(1, str8_lit("Fatal Allocation Failure"), str8_lit("Unexpected memory allocation failure."));
|
||||||
|
os_abort(1);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// rjf: extract arena header & fill
|
||||||
|
Arena *arena = (Arena *)base;
|
||||||
|
arena->current = arena;
|
||||||
|
arena->flags = params->flags;
|
||||||
|
arena->cmt_size = (U32)params->commit_size;
|
||||||
|
arena->res_size = params->reserve_size;
|
||||||
|
arena->base_pos = 0;
|
||||||
|
arena->pos = ARENA_HEADER_SIZE;
|
||||||
|
arena->cmt = commit_size;
|
||||||
|
arena->res = reserve_size;
|
||||||
|
AsanPoisonMemoryRegion(base, commit_size);
|
||||||
|
AsanUnpoisonMemoryRegion(base, ARENA_HEADER_SIZE);
|
||||||
|
return arena;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Note(Ed): INLINED
|
||||||
|
// internal void
|
||||||
|
// arena_release(Arena *arena)
|
||||||
|
// {
|
||||||
|
// for(Arena *n = arena->current, *prev = 0; n != 0; n = prev)
|
||||||
|
// {
|
||||||
|
// prev = n->prev;
|
||||||
|
// os_release(n, n->res);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
//- rjf: arena push/pop core functions
|
//- rjf: arena push/pop core functions
|
||||||
|
|
||||||
internal void *
|
internal void *
|
||||||
|
|||||||
+30
-4
@@ -2,6 +2,7 @@
|
|||||||
# pragma once
|
# pragma once
|
||||||
# include "macros.h"
|
# include "macros.h"
|
||||||
# include "base_types.h"
|
# include "base_types.h"
|
||||||
|
# include "memory_substrate.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Copyright (c) 2024 Epic Games Tools
|
// Copyright (c) 2024 Epic Games Tools
|
||||||
@@ -10,7 +11,7 @@
|
|||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
//~ rjf: Constants
|
//~ rjf: Constants
|
||||||
|
|
||||||
#define MD_ARENA_HEADER_SIZE 64
|
#define ARENA_HEADER_SIZE 64
|
||||||
|
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
//~ rjf: Types
|
//~ rjf: Types
|
||||||
@@ -43,6 +44,7 @@ struct ArenaParams
|
|||||||
typedef struct Arena Arena;
|
typedef struct Arena Arena;
|
||||||
struct Arena
|
struct Arena
|
||||||
{
|
{
|
||||||
|
AllocatorInfo backing;
|
||||||
Arena* prev; // previous arena in chain
|
Arena* prev; // previous arena in chain
|
||||||
Arena* current; // current arena in chain
|
Arena* current; // current arena in chain
|
||||||
ArenaFlags flags;
|
ArenaFlags flags;
|
||||||
@@ -53,7 +55,7 @@ struct Arena
|
|||||||
U64 cmt;
|
U64 cmt;
|
||||||
U64 res;
|
U64 res;
|
||||||
};
|
};
|
||||||
static_assert(sizeof(Arena) <= MD_ARENA_HEADER_SIZE, "sizeof(Arena) <= MD_ARENA_HEADER_SIZE");
|
static_assert(sizeof(Arena) <= ARENA_HEADER_SIZE, "sizeof(Arena) <= MD_ARENA_HEADER_SIZE");
|
||||||
|
|
||||||
typedef struct TempArena TempArena;
|
typedef struct TempArena TempArena;
|
||||||
struct TempArena
|
struct TempArena
|
||||||
@@ -65,27 +67,51 @@ struct TempArena
|
|||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
//~ rjf: Arena Functions
|
//~ rjf: Arena Functions
|
||||||
|
|
||||||
|
MD_API void* arena_allocator_proc(void* allocator_data, AllocType type, SSIZE size, SSIZE alignment, void* old_memory, SSIZE old_size, U64 flags);
|
||||||
|
|
||||||
//- rjf: arena creation/destruction
|
//- rjf: arena creation/destruction
|
||||||
internal Arena* arena_alloc_(ArenaParams *params);
|
|
||||||
|
MD_API Arena* arena_alloc_(ArenaParams *params);
|
||||||
#define arena_alloc(...) arena_alloc_( & ( ArenaParams) { .reserve_size = MB(64), .commit_size = KB(64), __VA_ARGS__ } )
|
#define arena_alloc(...) arena_alloc_( & ( ArenaParams) { .reserve_size = MB(64), .commit_size = KB(64), __VA_ARGS__ } )
|
||||||
|
|
||||||
internal void arena_release(Arena *arena);
|
void arena_release(Arena *arena);
|
||||||
|
|
||||||
//- rjf: arena push/pop/pos core functions
|
//- rjf: arena push/pop/pos core functions
|
||||||
|
|
||||||
internal void *arena_push (Arena *arena, U64 size, U64 align);
|
internal void *arena_push (Arena *arena, U64 size, U64 align);
|
||||||
internal U64 arena_pos (Arena *arena);
|
internal U64 arena_pos (Arena *arena);
|
||||||
internal void arena_pop_to(Arena *arena, U64 pos);
|
internal void arena_pop_to(Arena *arena, U64 pos);
|
||||||
|
|
||||||
//- rjf: arena push/pop helpers
|
//- rjf: arena push/pop helpers
|
||||||
|
|
||||||
internal void arena_clear(Arena *arena);
|
internal void arena_clear(Arena *arena);
|
||||||
internal void arena_pop (Arena *arena, U64 amt);
|
internal void arena_pop (Arena *arena, U64 amt);
|
||||||
|
|
||||||
//- rjf: temporary arena scopes
|
//- rjf: temporary arena scopes
|
||||||
|
|
||||||
internal TempArena temp_arena_begin(Arena *arena);
|
internal TempArena temp_arena_begin(Arena *arena);
|
||||||
internal void temp_arena_end(TempArena temp);
|
internal void temp_arena_end(TempArena temp);
|
||||||
|
|
||||||
//- rjf: push helper macros
|
//- 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_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_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_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)))
|
#define push_array(a, T, c) push_array_aligned (a, T, c, max(8, align_of(T)))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Inlines
|
||||||
|
|
||||||
|
inline void
|
||||||
|
arena_release(Arena* arena)
|
||||||
|
{
|
||||||
|
for (Arena* n = arena->current, *prev = 0; n != 0; n = prev)
|
||||||
|
{
|
||||||
|
prev = n->prev;
|
||||||
|
// os_release(n, n->res);
|
||||||
|
alloc_free(arena->backing, n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -57,6 +57,10 @@ typedef ptrdiff_t SSIZE;
|
|||||||
|
|
||||||
static_assert( sizeof( USIZE ) == sizeof( SSIZE ), "sizeof(USIZE) != sizeof(SSIZE)" );
|
static_assert( sizeof( USIZE ) == sizeof( SSIZE ), "sizeof(USIZE) != sizeof(SSIZE)" );
|
||||||
|
|
||||||
|
#ifndef size_of
|
||||||
|
#define size_of( x ) ( 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.
|
// NOTE: (u)zpl_intptr is only here for semantic reasons really as this library will only support 32/64 bit OSes.
|
||||||
#if defined( _WIN64 )
|
#if defined( _WIN64 )
|
||||||
typedef signed __int64 SPTR;
|
typedef signed __int64 SPTR;
|
||||||
@@ -88,3 +92,5 @@ static_assert( sizeof( F64 ) == 8, "sizeof(F64) != 8" );
|
|||||||
typedef S8 B8;
|
typedef S8 B8;
|
||||||
typedef S16 B16;
|
typedef S16 B16;
|
||||||
typedef S32 B32;
|
typedef S32 B32;
|
||||||
|
|
||||||
|
typedef void VoidProc(void);
|
||||||
|
|||||||
@@ -0,0 +1,43 @@
|
|||||||
|
#ifdef INTELLISENSE_DIRECTIVES
|
||||||
|
# pragma once
|
||||||
|
# include "context_cracking.h"
|
||||||
|
# include "macros.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
////////////////////////////////
|
||||||
|
//~ rjf: Asserts
|
||||||
|
|
||||||
|
#ifndef trap
|
||||||
|
# if COMPILER_MSVC
|
||||||
|
# define trap() __debugbreak()
|
||||||
|
# elif COMPILER_CLANG || COMPILER_GCC
|
||||||
|
# define trap() __builtin_trap()
|
||||||
|
# else
|
||||||
|
# error Unknown trap intrinsic for this compiler.
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef assert_always
|
||||||
|
#define assert_always(x) do { if ( !(x) ) { trap(); } } while(0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef assert
|
||||||
|
# if BUILD_DEBUG
|
||||||
|
# define assert(x) assert_always(x)
|
||||||
|
# else
|
||||||
|
# define assert(x) (void)(x)
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef invalid_path
|
||||||
|
#define invalid_path assert( ! "Invalid Path!")
|
||||||
|
#endif
|
||||||
|
#ifndef not_implemented
|
||||||
|
#define not_implemented assert( ! "Not Implemented!")
|
||||||
|
#endif
|
||||||
|
#ifndef no_op
|
||||||
|
#define no_op ((void)0)
|
||||||
|
#endif
|
||||||
|
#ifndef md_static_assert
|
||||||
|
#define md_static_assert(C, ID) global U8 glue(ID, __LINE__)[ (C) ? 1 : -1 ]
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
#ifdef INTELLISENSE_DIRECTIVES
|
||||||
|
# pragma once
|
||||||
|
# include "base_types.h"
|
||||||
|
# include "time.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
////////////////////////////////
|
||||||
|
//~ allen: Files
|
||||||
|
|
||||||
|
typedef U32 FilePropertyFlags;
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
FilePropertyFlag_IsFolder = (1 << 0),
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct FileProperties FileProperties;
|
||||||
|
struct FileProperties
|
||||||
|
{
|
||||||
|
U64 size;
|
||||||
|
DenseTime modified;
|
||||||
|
DenseTime created;
|
||||||
|
FilePropertyFlags flags;
|
||||||
|
};
|
||||||
+311
-55
@@ -68,85 +68,260 @@
|
|||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
//~ rjf: Type -> Alignment
|
//~ rjf: Type -> Alignment
|
||||||
|
|
||||||
#if COMPILER_MSVC
|
#ifndef align_of
|
||||||
|
# if COMPILER_MSVC
|
||||||
# define align_of(T) __alignof(T)
|
# define align_of(T) __alignof(T)
|
||||||
#elif COMPILER_CLANG
|
# elif COMPILER_CLANG
|
||||||
# define align_of(T) __alignof(T)
|
# define align_of(T) __alignof(T)
|
||||||
#elif COMPILER_GCC
|
# elif COMPILER_GCC
|
||||||
# define align_of(T) __alignof__(T)
|
# define align_of(T) __alignof__(T)
|
||||||
#else
|
# else
|
||||||
# error AlignOf not defined for this compiler.
|
# error AlignOf not defined for this compiler.
|
||||||
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
//~ rjf: Member Offsets
|
//~ rjf: Member Offsets
|
||||||
|
|
||||||
|
#ifndef membeMD_DYN_LINKr
|
||||||
#define member(T, m) ( ((T*) 0)->m )
|
#define member(T, m) ( ((T*) 0)->m )
|
||||||
|
#endif
|
||||||
|
#ifndef offset_of
|
||||||
#define offset_of(T, m) int_from_ptr(& member(T, m))
|
#define offset_of(T, m) int_from_ptr(& member(T, m))
|
||||||
|
#endif
|
||||||
|
#ifndef member_from_offset
|
||||||
#define member_from_offset(T, ptr, off) (T) ((((U8 *) ptr) + (off)))
|
#define member_from_offset(T, ptr, off) (T) ((((U8 *) ptr) + (off)))
|
||||||
|
#endif
|
||||||
|
#ifndef cast_from_member
|
||||||
#define cast_from_member(T, m, ptr) (T*) (((U8*)ptr) - offset_of(T, m))
|
#define cast_from_member(T, m, ptr) (T*) (((U8*)ptr) - offset_of(T, m))
|
||||||
|
#endif
|
||||||
|
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
//~ rjf: For-Loop Construct Macros
|
//~ rjf: For-Loop Construct Macros
|
||||||
|
|
||||||
|
#ifndef defer_loop
|
||||||
#define defer_loop(begin, end) for (int _i_ = ((begin), 0); ! _i_; _i_ += 1, (end))
|
#define 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))
|
#define 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 )
|
#define 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 )
|
#define each_non_zero_enum_val(type, it) type it = (type) 1; it < type ## _COUNT; it = (type)( it + 1 )
|
||||||
|
#endif
|
||||||
|
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
//~ rjf: Memory Operation Macros
|
//~ rjf: Memory Operation Macros
|
||||||
|
|
||||||
#define memory_copy(dst, src, size) memmove((dst), (src), (size))
|
|
||||||
#define memory_set(dst, byte, size) memset((dst), (byte), (size))
|
// TODO(Ed): Review usage of memmove here...
|
||||||
|
#ifndef memory_copy
|
||||||
|
# if USE_VENDOR_MEMORY_OPS
|
||||||
|
# define memory_copy(dst, src, size) memmove((dst), (src), (size))
|
||||||
|
# else
|
||||||
|
# define memory_copy(dst, src, size) mem_move((dst), (src), (size))
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#ifndef memory_set
|
||||||
|
# if USE_VENDOR_MEMORY_OPS
|
||||||
|
# define memory_set(dst, byte, size) memset((dst), (byte), (size))
|
||||||
|
# else
|
||||||
|
# define memory_set(dst, byte, size) mem_set((dst), (byte), (size))
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
#ifndef memory_compare
|
||||||
#define memory_compare(a, b, size) memcmp((a), (b), (size))
|
#define memory_compare(a, b, size) memcmp((a), (b), (size))
|
||||||
|
#endif
|
||||||
|
#ifndef memory_str_len
|
||||||
#define memory_str_len(ptr) cstr_len(ptr)
|
#define memory_str_len(ptr) cstr_len(ptr)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef memory_copy_struct
|
||||||
#define memory_copy_struct(d,s) memory_copy((d), (s), sizeof( *(d)))
|
#define memory_copy_struct(d,s) memory_copy((d), (s), sizeof( *(d)))
|
||||||
|
#endif
|
||||||
|
#ifndef memory_copy_array
|
||||||
#define memory_copy_array(d,s) memory_copy((d), (s), sizeof( d))
|
#define memory_copy_array(d,s) memory_copy((d), (s), sizeof( d))
|
||||||
|
#endif
|
||||||
|
#ifndef memory_copy_type
|
||||||
#define memory_copy_type(d,s,c) memory_copy((d), (s), sizeof( *(d)) * (c))
|
#define memory_copy_type(d,s,c) memory_copy((d), (s), sizeof( *(d)) * (c))
|
||||||
|
#endif
|
||||||
|
|
||||||
#define memory_zero(s,z) mem_set((s), 0, (z))
|
#ifndef memory_zero
|
||||||
|
#define memory_zero(s,z) memory_set((s), 0, (z))
|
||||||
|
#endif
|
||||||
|
#ifndef memory_zero_struct
|
||||||
#define memory_zero_struct(s) memory_zero((s), sizeof( *(s)))
|
#define memory_zero_struct(s) memory_zero((s), sizeof( *(s)))
|
||||||
#define memory_zero_array(a) memroy_zero((a), sizeof(a))
|
#endif
|
||||||
#define memory_zero_type(m,c) memroy_zero((m), sizeof( *(m)) * (c))
|
#ifndef memory_zero_array
|
||||||
|
#define memory_zero_array(a) memory_zero((a), sizeof(a))
|
||||||
|
#endif
|
||||||
|
#ifndef memory_zero_type
|
||||||
|
#define memory_zero_type(m,c) memory_zero((m), sizeof( *(m)) * (c))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef memory_match
|
||||||
#define memory_match(a,b,z) (memory_compare((a), (b), (z)) == 0)
|
#define memory_match(a,b,z) (memory_compare((a), (b), (z)) == 0)
|
||||||
|
#endif
|
||||||
|
#ifndef memory_match_struct
|
||||||
#define memory_match_struct(a,b) memory_match((a), (b), sizeof(*(a)))
|
#define memory_match_struct(a,b) memory_match((a), (b), sizeof(*(a)))
|
||||||
|
#endif
|
||||||
|
#ifndef memory_match_array
|
||||||
#define memory_match_array(a,b) memory_match((a), (b), sizeof(a))
|
#define memory_match_array(a,b) memory_match((a), (b), sizeof(a))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef memory_read
|
||||||
#define memory_read(T,p,e) ( ((p) + sizeof(T) <= (e)) ? ( *(T*)(p)) : (0) )
|
#define memory_read(T,p,e) ( ((p) + sizeof(T) <= (e)) ? ( *(T*)(p)) : (0) )
|
||||||
|
#endif
|
||||||
|
#ifndef memory_consume
|
||||||
#define memory_consume(T,p,e) ( ((p) + sizeof(T) <= (e)) ? ((p) += sizeof(T), *(T*)((p) - sizeof(T))) : ((p) = (e),0) )
|
#define memory_consume(T,p,e) ( ((p) + sizeof(T) <= (e)) ? ((p) += sizeof(T), *(T*)((p) - sizeof(T))) : ((p) = (e),0) )
|
||||||
|
|
||||||
////////////////////////////////
|
|
||||||
//~ rjf: Asserts
|
|
||||||
|
|
||||||
#if COMPILER_MSVC
|
|
||||||
# define trap() __debugbreak()
|
|
||||||
#elif COMPILER_CLANG || COMPILER_GCC
|
|
||||||
# define trap() __builtin_trap()
|
|
||||||
#else
|
|
||||||
# error Unknown trap intrinsic for this compiler.
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define assert_always(x) do { if ( !(x) ) { trap(); } } while(0)
|
inline
|
||||||
|
void* mem_move( void* destination, void const* source, SSIZE byte_count )
|
||||||
|
{
|
||||||
|
if ( destination == NULL )
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
#if BUILD_DEBUG
|
U8* dest_ptr = rcast( U8*, destination);
|
||||||
# define assert(x) assert_always(x)
|
U8 const* src_ptr = rcast( U8 const*, source);
|
||||||
#else
|
|
||||||
# define assert(x) (void)(x)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define invalid_path assert( ! "Invalid Path!")
|
if ( dest_ptr == src_ptr )
|
||||||
#define not_implemented assert( ! "Not Implemented!")
|
return dest_ptr;
|
||||||
#define no_op ((void)0)
|
|
||||||
#define md_static_assert(C, ID) global U8 glue(ID, __LINE__)[ (C) ? 1 : -1 ]
|
if ( src_ptr + byte_count <= dest_ptr || dest_ptr + byte_count <= src_ptr ) // NOTE: Non-overlapping
|
||||||
|
return mem_copy( dest_ptr, src_ptr, byte_count );
|
||||||
|
|
||||||
|
if ( dest_ptr < src_ptr )
|
||||||
|
{
|
||||||
|
if ( to_uptr(src_ptr) % size_of( SSIZE ) == to_uptr(dest_ptr) % size_of( SSIZE ) )
|
||||||
|
{
|
||||||
|
while ( pcast( UPTR, dest_ptr) % size_of( ssize ) )
|
||||||
|
{
|
||||||
|
if ( ! byte_count-- )
|
||||||
|
return destination;
|
||||||
|
|
||||||
|
*dest_ptr++ = *src_ptr++;
|
||||||
|
}
|
||||||
|
while ( byte_count >= size_of( ssize ) )
|
||||||
|
{
|
||||||
|
* rcast(SSIZE*, dest_ptr) = * rcast(SSIZE const*, src_ptr);
|
||||||
|
byte_count -= size_of( ssize );
|
||||||
|
dest_ptr += size_of( ssize );
|
||||||
|
src_ptr += size_of( ssize );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for ( ; byte_count; byte_count-- )
|
||||||
|
*dest_ptr++ = *src_ptr++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ( ( to_uptr(src_ptr) % size_of( SSIZE ) ) == ( to_uptr(dest_ptr) % size_of( SSIZE ) ) )
|
||||||
|
{
|
||||||
|
while ( to_uptr( dest_ptr + byte_count ) % size_of( SSIZE ) )
|
||||||
|
{
|
||||||
|
if ( ! byte_count-- )
|
||||||
|
return destination;
|
||||||
|
|
||||||
|
dest_ptr[ byte_count ] = src_ptr[ byte_count ];
|
||||||
|
}
|
||||||
|
while ( byte_count >= size_of( SSIZE ) )
|
||||||
|
{
|
||||||
|
byte_count -= size_of( SSIZE );
|
||||||
|
* rcast(SSIZE*, dest_ptr + byte_count ) = * rcast( SSIZE const*, src_ptr + byte_count );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while ( byte_count )
|
||||||
|
byte_count--, dest_ptr[ byte_count ] = src_ptr[ byte_count ];
|
||||||
|
}
|
||||||
|
|
||||||
|
return destination;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
void* mem_set( void* destination, U8 fill_byte, SSIZE byte_count )
|
||||||
|
{
|
||||||
|
if ( destination == NULL )
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
SSIZE align_offset;
|
||||||
|
U8* dest_ptr = rcast( U8*, destination);
|
||||||
|
U32 fill_word = ( ( U32 )-1 ) / 255 * fill_byte;
|
||||||
|
|
||||||
|
if ( byte_count == 0 )
|
||||||
|
return destination;
|
||||||
|
|
||||||
|
dest_ptr[ 0 ] = dest_ptr[ byte_count - 1 ] = fill_byte;
|
||||||
|
if ( byte_count < 3 )
|
||||||
|
return destination;
|
||||||
|
|
||||||
|
dest_ptr[ 1 ] = dest_ptr[ byte_count - 2 ] = fill_byte;
|
||||||
|
dest_ptr[ 2 ] = dest_ptr[ byte_count - 3 ] = fill_byte;
|
||||||
|
if ( byte_count < 7 )
|
||||||
|
return destination;
|
||||||
|
|
||||||
|
dest_ptr[ 3 ] = dest_ptr[ byte_count - 4 ] = fill_byte;
|
||||||
|
if ( byte_count < 9 )
|
||||||
|
return destination;
|
||||||
|
|
||||||
|
align_offset = -to_sptr( dest_ptr ) & 3;
|
||||||
|
dest_ptr += align_offset;
|
||||||
|
byte_count -= align_offset;
|
||||||
|
byte_count &= -4;
|
||||||
|
|
||||||
|
* rcast( U32*, ( dest_ptr + 0 ) ) = fill_word;
|
||||||
|
* rcast( U32*, ( dest_ptr + byte_count - 4 ) ) = fill_word;
|
||||||
|
if ( byte_count < 9 )
|
||||||
|
return destination;
|
||||||
|
|
||||||
|
* rcast( U32*, dest_ptr + 4 ) = fill_word;
|
||||||
|
* rcast( U32*, dest_ptr + 8 ) = fill_word;
|
||||||
|
* rcast( U32*, dest_ptr + byte_count - 12 ) = fill_word;
|
||||||
|
* rcast( U32*, dest_ptr + byte_count - 8 ) = fill_word;
|
||||||
|
if ( byte_count < 25 )
|
||||||
|
return destination;
|
||||||
|
|
||||||
|
* rcast( U32*, dest_ptr + 12 ) = fill_word;
|
||||||
|
* rcast( U32*, dest_ptr + 16 ) = fill_word;
|
||||||
|
* rcast( U32*, dest_ptr + 20 ) = fill_word;
|
||||||
|
* rcast( U32*, dest_ptr + 24 ) = fill_word;
|
||||||
|
* rcast( U32*, dest_ptr + byte_count - 28 ) = fill_word;
|
||||||
|
* rcast( U32*, dest_ptr + byte_count - 24 ) = fill_word;
|
||||||
|
* rcast( U32*, dest_ptr + byte_count - 20 ) = fill_word;
|
||||||
|
* rcast( U32*, dest_ptr + byte_count - 16 ) = fill_word;
|
||||||
|
|
||||||
|
align_offset = 24 + to_uptr( dest_ptr ) & 4;
|
||||||
|
dest_ptr += align_offset;
|
||||||
|
byte_count -= align_offset;
|
||||||
|
|
||||||
|
{
|
||||||
|
u64 fill_doubleword = ( scast( U64, fill_word) << 32 ) | fill_word;
|
||||||
|
while ( byte_count > 31 )
|
||||||
|
{
|
||||||
|
* rcast( U64*, dest_ptr + 0 ) = fill_doubleword;
|
||||||
|
* rcast( U64*, dest_ptr + 8 ) = fill_doubleword;
|
||||||
|
* rcast( U64*, dest_ptr + 16 ) = fill_doubleword;
|
||||||
|
* rcast( U64*, dest_ptr + 24 ) = fill_doubleword;
|
||||||
|
|
||||||
|
byte_count -= 32;
|
||||||
|
dest_ptr += 32;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return destination;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
//~ rjf: Atomic Operations
|
//~ rjf: Atomic Operations
|
||||||
|
|
||||||
#if OS_WINDOWS
|
#ifndef ins_atomic_u64_eval
|
||||||
|
# if OS_WINDOWS
|
||||||
# if ARCH_X64
|
# if ARCH_X64
|
||||||
# define ins_atomic_u64_eval(x) InterlockedAdd64((volatile __int64 *)(x), 0)
|
# define ins_atomic_u64_eval(x) InterlockedAdd64((volatile __int64 *)(x), 0)
|
||||||
# define ins_atomic_u64_inc_eval(x) InterlockedIncrement64((volatile __int64 *)(x))
|
# define ins_atomic_u64_inc_eval(x) InterlockedIncrement64((volatile __int64 *)(x))
|
||||||
@@ -161,14 +336,15 @@
|
|||||||
# else
|
# else
|
||||||
# error Atomic intrinsics not defined for this operating system / architecture combination.
|
# error Atomic intrinsics not defined for this operating system / architecture combination.
|
||||||
# endif
|
# endif
|
||||||
#elif OS_LINUX
|
# elif OS_LINUX
|
||||||
# if ARCH_X64
|
# if ARCH_X64
|
||||||
# define ins_atomic_u64_inc_eval(x) __sync_fetch_and_add((volatile U64 *)(x), 1)
|
# define ins_atomic_u64_inc_eval(x) __sync_fetch_and_add((volatile U64 *)(x), 1)
|
||||||
# else
|
# else
|
||||||
# error Atomic intrinsics not defined for this operating system / architecture combination.
|
# error Atomic intrinsics not defined for this operating system / architecture combination.
|
||||||
# endif
|
# endif
|
||||||
#else
|
# else
|
||||||
# error Atomic intrinsics not defined for this operating system.
|
# error Atomic intrinsics not defined for this operating system.
|
||||||
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
@@ -176,11 +352,16 @@
|
|||||||
|
|
||||||
//- rjf: linked list macro helpers
|
//- rjf: linked list macro helpers
|
||||||
|
|
||||||
|
#ifndef check_nil
|
||||||
#define check_nil(nil,p) ((p) == 0 || (p) == nil)
|
#define check_nil(nil,p) ((p) == 0 || (p) == nil)
|
||||||
|
#endif
|
||||||
|
#ifndef set_nil
|
||||||
#define set_nil(nil,p) ((p) = nil)
|
#define set_nil(nil,p) ((p) = nil)
|
||||||
|
#endif
|
||||||
|
|
||||||
//- rjf: doubly-linked-lists
|
//- rjf: doubly-linked-lists
|
||||||
|
|
||||||
|
#ifndef dll_insert_npz
|
||||||
// insert next-previous with nil
|
// insert next-previous with nil
|
||||||
#define dll_insert_npz(nil, f, l, p, n, next, prev) ( \
|
#define dll_insert_npz(nil, f, l, p, n, next, prev) ( \
|
||||||
check_nil(nil, f) ? ( \
|
check_nil(nil, f) ? ( \
|
||||||
@@ -213,10 +394,16 @@
|
|||||||
) \
|
) \
|
||||||
) \
|
) \
|
||||||
)
|
)
|
||||||
|
#endif
|
||||||
|
#ifndef dll_push_back_npz
|
||||||
// push-back next-previous with nil
|
// push-back next-previous with nil
|
||||||
#define dll_push_back_npz(nil, f, l, n, next, prev) dll_insert_npz(nil, f, l, l, n, next, prev)
|
#define dll_push_back_npz(nil, f, l, n, next, prev) dll_insert_npz(nil, f, l, l, n, next, prev)
|
||||||
|
#endif
|
||||||
|
#ifndef dll_push_front_npz
|
||||||
// push-fornt next-previous with nil
|
// push-fornt next-previous with nil
|
||||||
#define dll_push_front_npz(nil, f, l, n, next, prev) dll_insert_npz(nil, l, f, f, n, prev, next)
|
#define dll_push_front_npz(nil, f, l, n, next, prev) dll_insert_npz(nil, l, f, f, n, prev, next)
|
||||||
|
#endif
|
||||||
|
#ifndef dll_remove_npz
|
||||||
// remove next-previous with nil
|
// remove next-previous with nil
|
||||||
#define dll_remove_npz(nil, f, l, n, next, prev) \
|
#define dll_remove_npz(nil, f, l, n, next, prev) \
|
||||||
( \
|
( \
|
||||||
@@ -241,9 +428,11 @@
|
|||||||
: ((n)->next->prev = (n)->prev) \
|
: ((n)->next->prev = (n)->prev) \
|
||||||
) \
|
) \
|
||||||
)
|
)
|
||||||
|
#endif
|
||||||
|
|
||||||
//- rjf: singly-linked, doubly-headed lists (queues)
|
//- rjf: singly-linked, doubly-headed lists (queues)
|
||||||
|
|
||||||
|
#ifndef sll_queue_push_nz
|
||||||
// queue-push next with nil
|
// queue-push next with nil
|
||||||
#define sll_queue_push_nz(nil, f, l, n, next) \
|
#define sll_queue_push_nz(nil, f, l, n, next) \
|
||||||
( \
|
( \
|
||||||
@@ -257,6 +446,8 @@
|
|||||||
set_nil(nil,(n)->next) \
|
set_nil(nil,(n)->next) \
|
||||||
) \
|
) \
|
||||||
)
|
)
|
||||||
|
#endif
|
||||||
|
#ifndef sll_queue_push_front_nz
|
||||||
// queue-push-front next with nil
|
// queue-push-front next with nil
|
||||||
#define sll_queue_push_front_nz(nil, f, l, n, next) \
|
#define sll_queue_push_front_nz(nil, f, l, n, next) \
|
||||||
( \
|
( \
|
||||||
@@ -269,6 +460,8 @@
|
|||||||
(f) = (n) \
|
(f) = (n) \
|
||||||
) \
|
) \
|
||||||
)
|
)
|
||||||
|
#endif
|
||||||
|
#ifndef sll_queue_pop_nz
|
||||||
// queue-pop next with nil
|
// queue-pop next with nil
|
||||||
#define sll_queue_pop_nz(nil, f, l, next) \
|
#define sll_queue_pop_nz(nil, f, l, next) \
|
||||||
( \
|
( \
|
||||||
@@ -280,68 +473,109 @@
|
|||||||
(f)=(f)->next \
|
(f)=(f)->next \
|
||||||
) \
|
) \
|
||||||
)
|
)
|
||||||
|
#endif
|
||||||
|
|
||||||
//- rjf: singly-linked, singly-headed lists (stacks)
|
//- rjf: singly-linked, singly-headed lists (stacks)
|
||||||
|
|
||||||
|
#ifndef sll_stack_push_n
|
||||||
#define sll_stack_push_n(f,n,next) ( (n)->next = (f), (f) = (n) )
|
#define sll_stack_push_n(f,n,next) ( (n)->next = (f), (f) = (n) )
|
||||||
|
#endif
|
||||||
|
#ifndef sll_stack_pop_n
|
||||||
#define sll_stack_pop_n(f,next) ( (f) = (f)->next )
|
#define sll_stack_pop_n(f,next) ( (f) = (f)->next )
|
||||||
|
#endif
|
||||||
|
|
||||||
//- rjf: doubly-linked-list helpers
|
//- rjf: doubly-linked-list helpers
|
||||||
|
|
||||||
|
#ifndef dll_insert_np
|
||||||
#define dll_insert_np(f, l, p, n, next, prev) dll_insert_npz (0, f, l, p, n, next, prev)
|
#define dll_insert_np(f, l, p, n, next, prev) dll_insert_npz (0, f, l, p, n, next, prev)
|
||||||
|
#endif
|
||||||
|
#ifndef dll_push_back_np
|
||||||
#define dll_push_back_np(f, l, n, next, prev) dll_push_back_npz (0, f, l, n, next, prev)
|
#define dll_push_back_np(f, l, n, next, prev) dll_push_back_npz (0, f, l, n, next, prev)
|
||||||
|
#endif
|
||||||
|
#ifndef dll_push_front_np
|
||||||
#define dll_push_front_np(f, l, n, next, prev) dll_push_front_npz(0, f, l, n, next, prev)
|
#define dll_push_front_np(f, l, n, next, prev) dll_push_front_npz(0, f, l, n, next, prev)
|
||||||
|
#endif
|
||||||
|
#ifndef dll_remove_np
|
||||||
#define dll_remove_np(f, l, n, next, prev) dll_remove_npz (0, f, l, n, next, prev)
|
#define dll_remove_np(f, l, n, next, prev) dll_remove_npz (0, f, l, n, next, prev)
|
||||||
|
#endif
|
||||||
|
#ifndef dll_insert
|
||||||
#define dll_insert(f, l, p, n) dll_insert_npz (0, f, l, p, n, next, prev)
|
#define dll_insert(f, l, p, n) dll_insert_npz (0, f, l, p, n, next, prev)
|
||||||
|
#endif
|
||||||
|
#ifndef dll_push_back
|
||||||
#define dll_push_back(f, l, n) dll_push_back_npz (0, f, l, n, next, prev)
|
#define dll_push_back(f, l, n) dll_push_back_npz (0, f, l, n, next, prev)
|
||||||
|
#endif
|
||||||
|
#ifndef dll_push_front
|
||||||
#define dll_push_front(f, l, n) dll_push_front_npz(0, f, l, n, next, prev)
|
#define dll_push_front(f, l, n) dll_push_front_npz(0, f, l, n, next, prev)
|
||||||
|
#endif
|
||||||
|
#ifndef dll_remove
|
||||||
#define dll_remove(f, l, n) dll_remove_npz (0, f, l, n, next, prev)
|
#define dll_remove(f, l, n) dll_remove_npz (0, f, l, n, next, prev)
|
||||||
|
#endif
|
||||||
|
|
||||||
//- rjf: singly-linked, doubly-headed list helpers
|
//- rjf: singly-linked, doubly-headed list helpers
|
||||||
|
|
||||||
|
#ifndef sll_queue_push_n
|
||||||
#define sll_queue_push_n(f, l, n, next) sll_queue_push_nz (0, f, l, n, next)
|
#define sll_queue_push_n(f, l, n, next) sll_queue_push_nz (0, f, l, n, next)
|
||||||
#define sll_queue_push_fornt_n(f, l, n, next) sll_queue_push_front_nz(0, f, l, n, next)
|
#endif
|
||||||
|
#ifndef sll_queue_push_front_n
|
||||||
|
#define sll_queue_push_front_n(f, l, n, next) sll_queue_push_front_nz(0, f, l, n, next)
|
||||||
|
#endif
|
||||||
|
#ifndef sll_queue_pop_n
|
||||||
#define sll_queue_pop_n(f, l, next) sll_queue_pop_nzs (0, f, l, next)
|
#define sll_queue_pop_n(f, l, next) sll_queue_pop_nzs (0, f, l, next)
|
||||||
|
#endif
|
||||||
|
#ifndef sll_queue_push
|
||||||
#define sll_queue_push(f, l, n) sll_queue_push_nz (0, f, l, n, next)
|
#define sll_queue_push(f, l, n) sll_queue_push_nz (0, f, l, n, next)
|
||||||
|
#endif
|
||||||
|
#ifndef sll_queue_push_front
|
||||||
#define sll_queue_push_front(f, l ,n) sll_queue_push_front_nz(0, f, l, n, next)
|
#define sll_queue_push_front(f, l ,n) sll_queue_push_front_nz(0, f, l, n, next)
|
||||||
|
#endif
|
||||||
|
#ifndef sll_queue_pop
|
||||||
#define sll_queue_pop(f, l) sll_queue_pop_nz (0, f, l, next)
|
#define sll_queue_pop(f, l) sll_queue_pop_nz (0, f, l, next)
|
||||||
|
#endif
|
||||||
|
|
||||||
//- rjf: singly-linked, singly-headed list helpers
|
//- rjf: singly-linked, singly-headed list helpers
|
||||||
|
|
||||||
|
#ifndef sll_stack_push
|
||||||
#define sll_stack_push(f, n) sll_stack_push_n(f, n, next)
|
#define sll_stack_push(f, n) sll_stack_push_n(f, n, next)
|
||||||
|
#endif
|
||||||
|
#ifndef sll_stack_pop
|
||||||
#define sll_stack_pop(f) sll_stack_pop_n (f, next)
|
#define sll_stack_pop(f) sll_stack_pop_n (f, next)
|
||||||
|
#endif
|
||||||
|
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
//~ rjf: Address Sanitizer Markup
|
//~ rjf: Address Sanitizer Markup
|
||||||
|
|
||||||
#if COMPILER_MSVC
|
#ifndef NO_ASAN
|
||||||
|
# if COMPILER_MSVC
|
||||||
# if defined(__SANITIZE_ADDRESS__)
|
# if defined(__SANITIZE_ADDRESS__)
|
||||||
# define ASAN_ENABLED 1
|
# define ASAN_ENABLED 1
|
||||||
# define NO_ASAN __declspec(no_sanitize_address)
|
# define NO_ASAN __declspec(no_sanitize_address)
|
||||||
# else
|
# else
|
||||||
# define NO_ASAN
|
# define NO_ASAN
|
||||||
# endif
|
# endif
|
||||||
#elif COMPILER_CLANG
|
# elif COMPILER_CLANG
|
||||||
# if defined(__has_feature)
|
# if defined(__has_feature)
|
||||||
# if __has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__)
|
# if __has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__)
|
||||||
# define ASAN_ENABLED 1
|
# define ASAN_ENABLED 1
|
||||||
# endif
|
# endif
|
||||||
# endif
|
# endif
|
||||||
# define NO_ASAN __attribute__((no_sanitize("address")))
|
# define NO_ASAN __attribute__((no_sanitize("address")))
|
||||||
#else
|
# else
|
||||||
# define NO_ASAN
|
# define NO_ASAN
|
||||||
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if MD_ASAN_ENABLED
|
#ifndef asan_poison_memory_region
|
||||||
|
# if MD_ASAN_ENABLED
|
||||||
# pragma comment(lib, "clang_rt.asan-x86_64.lib")
|
# pragma comment(lib, "clang_rt.asan-x86_64.lib")
|
||||||
MD_C_API void __asan_poison_memory_region(void const volatile *addr, size_t size);
|
MD_C_API void __asan_poison_memory_region(void const volatile *addr, size_t size);
|
||||||
MD_C_API void __asan_unpoison_memory_region(void const volatile *addr, size_t size);
|
MD_C_API void __asan_unpoison_memory_region(void const volatile *addr, size_t size);
|
||||||
|
|
||||||
# define asan_poison_memory_region(addr, size) __asan_poison_memory_region((addr), (size))
|
# define asan_poison_memory_region(addr, size) __asan_poison_memory_region((addr), (size))
|
||||||
# define asan_unpoison_memory_region(addr, size) __asan_unpoison_memory_region((addr), (size))
|
# define asan_unpoison_memory_region(addr, size) __asan_unpoison_memory_region((addr), (size))
|
||||||
#else
|
# else
|
||||||
# define asan_poison_memory_region(addr, size) ((void)(addr), (void)(size))
|
# define asan_poison_memory_region(addr, size) ((void)(addr), (void)(size))
|
||||||
# define asan_unpoison_memory_region(addr, size) ((void)(addr), (void)(size))
|
# define asan_unpoison_memory_region(addr, size) ((void)(addr), (void)(size))
|
||||||
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
@@ -379,39 +613,61 @@
|
|||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef ptr_from_int
|
||||||
#define ptr_from_int(i) (void*)((U8*)0 + (i))
|
#define ptr_from_int(i) (void*)((U8*)0 + (i))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef compose_64bit
|
||||||
#define compose_64bit(a,b) ((((U64)a) << 32) | ((U64)b));
|
#define compose_64bit(a,b) ((((U64)a) << 32) | ((U64)b));
|
||||||
#define align_pow_2(x,b) (((x) + (b) - 1)&( ~((b) - 1)))
|
#endif
|
||||||
#define align_down_pow_2(x,b) ((x) & (~((b) - 1)))
|
#ifndef align_pow2
|
||||||
#define align_pad_pow_2(x,b) ((0-(x)) & ((b) - 1))
|
#define align_pow2(x,b) (((x) + (b) - 1) & ( ~((b) - 1)))
|
||||||
#define is_pow_2(x) ((x) != 0 && ((x )& ((x) - 1)) == 0)
|
#endif
|
||||||
#define is_pow_2_or_zero(x) ((((x) - 1) & (x)) == 0)
|
#ifndef align_down_pow2
|
||||||
|
#define align_down_pow2(x,b) ((x) & (~((b) - 1)))
|
||||||
|
#endif
|
||||||
|
#ifndef align_pad_pow2
|
||||||
|
#define align_pad_pow2(x,b) ((0-(x)) & ((b) - 1))
|
||||||
|
#endif
|
||||||
|
#ifndef is_pow2
|
||||||
|
#define is_pow2(x) ((x) != 0 && ((x ) & ((x) - 1)) == 0)
|
||||||
|
#endif
|
||||||
|
#ifndef is_pow2_or_zero
|
||||||
|
#define is_pow2_or_zero(x) ((((x) - 1) & (x)) == 0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef extract_bit
|
||||||
#define extract_bit(word, idx) (((word) >> (idx)) & 1)
|
#define extract_bit(word, idx) (((word) >> (idx)) & 1)
|
||||||
|
#endif
|
||||||
|
|
||||||
#if LANG_CPP
|
#ifndef zero_struct
|
||||||
|
# if LANG_CPP
|
||||||
# define zero_struct {}
|
# define zero_struct {}
|
||||||
#else
|
# else
|
||||||
# define zero_struct {0}
|
# define zero_struct {0}
|
||||||
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if COMPILER_MSVC && COMPILER_MSVC_YEAR < 2015
|
#ifndef this_function_name
|
||||||
|
# if COMPILER_MSVC && COMPILER_MSVC_YEAR < 2015
|
||||||
# define this_function_name "unknown"
|
# define this_function_name "unknown"
|
||||||
#else
|
# else
|
||||||
# define this_function_name __func__
|
# define this_function_name __func__
|
||||||
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if COMPILER_MSVC || (COMPILER_CLANG && OS_WINDOWS)
|
#ifndef read_only
|
||||||
|
# if COMPILER_MSVC || (COMPILER_CLANG && OS_WINDOWS)
|
||||||
# pragma section(".rdata$", read)
|
# pragma section(".rdata$", read)
|
||||||
# define read_only __declspec(allocate(".rdata$"))
|
# define read_only __declspec(allocate(".rdata$"))
|
||||||
#elif (COMPILER_CLANG && OS_LINUX)
|
# elif (COMPILER_CLANG && OS_LINUX)
|
||||||
# define read_only __attribute__((section(".rodata")))
|
# define read_only __attribute__((section(".rodata")))
|
||||||
#else
|
# else
|
||||||
// NOTE(rjf): I don't know of a useful way to do this in GCC land.
|
// NOTE(rjf): I don't know of a useful way to do this in GCC land.
|
||||||
// __attribute__((section(".rodata"))) looked promising, but it introduces a
|
// __attribute__((section(".rodata"))) looked promising, but it introduces a
|
||||||
// strange warning about malformed section attributes, and it doesn't look
|
// strange warning about malformed section attributes, and it doesn't look
|
||||||
// like writing to that section reliably produces access violations, strangely
|
// like writing to that section reliably produces access violations, strangely
|
||||||
// enough. (It does on Clang)
|
// enough. (It does on Clang)
|
||||||
# define read_only
|
# define read_only
|
||||||
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -0,0 +1,177 @@
|
|||||||
|
#ifdef INTELLISENSE_DIRECTIVES
|
||||||
|
# include "memory.h"
|
||||||
|
# include "memory_substrate.h"
|
||||||
|
# include "../os/os.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define GEN_HEAP_STATS_MAGIC 0xDEADC0DE
|
||||||
|
|
||||||
|
typedef struct _heap_stats _heap_stats;
|
||||||
|
struct _heap_stats
|
||||||
|
{
|
||||||
|
U32 magic;
|
||||||
|
SSIZE used_memory;
|
||||||
|
SSIZE alloc_count;
|
||||||
|
};
|
||||||
|
|
||||||
|
global _heap_stats _heap_stats_info;
|
||||||
|
|
||||||
|
void heap_stats_init( void )
|
||||||
|
{
|
||||||
|
memory_zero_struct( &_heap_stats_info );
|
||||||
|
_heap_stats_info.magic = GEN_HEAP_STATS_MAGIC;
|
||||||
|
}
|
||||||
|
|
||||||
|
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!" );
|
||||||
|
return _heap_stats_info.used_memory;
|
||||||
|
}
|
||||||
|
|
||||||
|
SSIZE 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
void 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 );
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef struct _heap_alloc_info _heap_alloc_info;
|
||||||
|
struct _heap_alloc_info
|
||||||
|
{
|
||||||
|
SSIZE size;
|
||||||
|
void* physical_start;
|
||||||
|
};
|
||||||
|
|
||||||
|
void* heap_allocator_proc( void* allocator_data, AllocType type, SSIZE size, SSIZE alignment, void* old_memory, SSIZE old_size, U64 flags )
|
||||||
|
{
|
||||||
|
void* ptr = 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;
|
||||||
|
switch ( type )
|
||||||
|
{
|
||||||
|
case EAllocation_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;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case EAllocation_ALLOC :
|
||||||
|
{
|
||||||
|
size += track_size;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default :
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
switch ( type )
|
||||||
|
{
|
||||||
|
#if defined( COMPILER_MSVC ) || ( defined( COMPILER_GCC ) && defined( OS_WINDOWS ) ) || ( defined( COMPILER_TINYC ) && defined( OS_WINDOWS ) )
|
||||||
|
case EAllocType_ALLOC :
|
||||||
|
ptr = _aligned_malloc( size, alignment );
|
||||||
|
if ( flags & ALLOCATOR_FLAG_CLEAR_TO_ZERO )
|
||||||
|
zero_size( ptr, size );
|
||||||
|
break;
|
||||||
|
case EAllocType_FREE :
|
||||||
|
_aligned_free( old_memory );
|
||||||
|
break;
|
||||||
|
case EAllocType_RESIZE :
|
||||||
|
{
|
||||||
|
AllocatorInfo a = heap();
|
||||||
|
ptr = default_resize_align( a, old_memory, old_size, size, alignment );
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
#elif defined( OS_LINUX ) && ! defined( CPU_ARM ) && ! defined( COMPILER_TINYC )
|
||||||
|
case EAllocation_ALLOC :
|
||||||
|
{
|
||||||
|
ptr = aligned_alloc( alignment, ( size + alignment - 1 ) & ~( alignment - 1 ) );
|
||||||
|
|
||||||
|
if ( flags & GEN_ALLOCATOR_FLAG_CLEAR_TO_ZERO )
|
||||||
|
{
|
||||||
|
zero_size( ptr, size );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EAllocation_FREE :
|
||||||
|
{
|
||||||
|
free( old_memory );
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EAllocation_RESIZE :
|
||||||
|
{
|
||||||
|
AllocatorInfo a = heap();
|
||||||
|
ptr = default_resize_align( a, old_memory, old_size, size, alignment );
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#else
|
||||||
|
case EAllocType_ALLOC :
|
||||||
|
{
|
||||||
|
posix_memalign( &ptr, alignment, size );
|
||||||
|
|
||||||
|
if ( flags & ALLOCATOR_FLAG_CLEAR_TO_ZERO )
|
||||||
|
{
|
||||||
|
zero_size( ptr, size );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EAllocType_FREE :
|
||||||
|
{
|
||||||
|
free( old_memory );
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EAllocType_RESIZE :
|
||||||
|
{
|
||||||
|
AllocatorInfo a = heap();
|
||||||
|
ptr = default_resize_align( a, old_memory, old_size, size, alignment );
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
case EAllocType_FREE_ALL :
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef GEN_HEAP_ANALYSIS
|
||||||
|
if ( type == EAllocation_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++;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* vm_allocator_proc(void* allocator_data, AllocType type, SSIZE size, SSIZE alignment, void* old_memory, SSIZE old_size, U64 flags)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@@ -13,9 +13,11 @@
|
|||||||
// is related to the gb headers an thus the Odin-lang memory strategy
|
// is related to the gb headers an thus the Odin-lang memory strategy
|
||||||
// Users can override the underlying memory allocator used, even for the HMH arena memory strategy.
|
// Users can override the underlying memory allocator used, even for the HMH arena memory strategy.
|
||||||
|
|
||||||
|
#ifndef MD__ONES
|
||||||
#define MD__ONES ( scast( GEN_NS usize, - 1) / MD_U8_MAX )
|
#define MD__ONES ( scast( GEN_NS usize, - 1) / MD_U8_MAX )
|
||||||
#define MD__HIGHS ( MD__ONES * ( MD_U8_MAX / 2 + 1 ) )
|
#define MD__HIGHS ( MD__ONES * ( MD_U8_MAX / 2 + 1 ) )
|
||||||
#define MD__HAS_ZERO( x ) ( ( ( x ) - MD__ONES ) & ~( x ) & MD__HIGHS )
|
#define MD__HAS_ZERO( x ) ( ( ( x ) - MD__ONES ) & ~( x ) & MD__HIGHS )
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef U32 AllocType;
|
typedef U32 AllocType;
|
||||||
enum AllocType enum_underlying(U32)
|
enum AllocType enum_underlying(U32)
|
||||||
@@ -66,11 +68,20 @@ void* resize( AllocatorInfo a, void* ptr, SSIZE old_size, SSIZE new_size );
|
|||||||
//! Resize an allocated memory with specified alignment.
|
//! Resize an allocated memory with specified alignment.
|
||||||
void* resize_align( AllocatorInfo a, void* ptr, SSIZE old_size, SSIZE new_size, SSIZE alignment );
|
void* resize_align( AllocatorInfo a, void* ptr, SSIZE old_size, SSIZE new_size, SSIZE alignment );
|
||||||
|
|
||||||
|
#ifndef alloc_item
|
||||||
//! Allocate memory for an item.
|
//! Allocate memory for an item.
|
||||||
#define alloc_item( allocator_, Type ) ( Type* )alloc( allocator_, size_of( Type ) )
|
#define alloc_item( allocator_, Type ) ( Type* )alloc( allocator_, size_of( Type ) )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef alloc_array
|
||||||
//! Allocate memory for an array of items.
|
//! Allocate memory for an array of items.
|
||||||
#define alloc_array( allocator_, Type, count ) ( Type* )alloc( allocator_, size_of( Type ) * ( count ) )
|
#define alloc_array( allocator_, Type, count ) ( Type* )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 );
|
||||||
|
|
||||||
/* heap memory analysis tools */
|
/* heap memory analysis tools */
|
||||||
/* define GEN_HEAP_ANALYSIS to enable this feature */
|
/* define GEN_HEAP_ANALYSIS to enable this feature */
|
||||||
@@ -81,32 +92,116 @@ MD_API SSIZE heap_stats_used_memory( void );
|
|||||||
MD_API SSIZE heap_stats_alloc_count( void );
|
MD_API SSIZE heap_stats_alloc_count( void );
|
||||||
MD_API void heap_stats_check( void );
|
MD_API void heap_stats_check( void );
|
||||||
|
|
||||||
//! 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 );
|
|
||||||
|
|
||||||
MD_API void* heap_allocator_proc( void* allocator_data, AllocType type, SSIZE size, SSIZE alignment, void* old_memory, SSIZE old_size, U64 flags );
|
MD_API void* heap_allocator_proc( void* allocator_data, AllocType type, SSIZE size, SSIZE alignment, void* old_memory, SSIZE old_size, U64 flags );
|
||||||
|
|
||||||
|
#ifndef heap
|
||||||
//! The heap allocator backed by operating system's memory manager.
|
//! The heap allocator backed by operating system's memory manager.
|
||||||
#define heap() (AllocatorInfo){ AllocatorInfo allocator = { heap_allocator_proc, nullptr }; return allocator; }
|
#define heap() (AllocatorInfo){ AllocatorInfo allocator = { heap_allocator_proc, nullptr }; return allocator; }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef malloc
|
||||||
//! Helper to allocate memory using heap allocator.
|
//! Helper to allocate memory using heap allocator.
|
||||||
#define malloc( sz ) alloc( heap(), sz )
|
#define malloc( sz ) alloc( heap(), sz )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef mfree
|
||||||
//! Helper to free memory allocated by heap allocator.
|
//! Helper to free memory allocated by heap allocator.
|
||||||
#define mfree( ptr ) free( heap(), ptr )
|
#define mfree( ptr ) free( heap(), ptr )
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef struct VMem;
|
typedef U32 VMemoryFlags;
|
||||||
struct VMem {
|
enum
|
||||||
|
{
|
||||||
|
VMemoryFlag_NoChain = (1 << 0),
|
||||||
|
VMemoryFlag_LargePages = (1 << 1),
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct VMemory_Params;
|
||||||
|
struct VMemory_Params
|
||||||
|
{
|
||||||
|
VMemoryFlags flags;
|
||||||
|
U64 reserve_size;
|
||||||
|
U64 commit_size;
|
||||||
|
// void* optional_backing_buffer;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct VMemory;
|
||||||
|
struct VMemory
|
||||||
|
{
|
||||||
U32 cmt_size;
|
U32 cmt_size;
|
||||||
U32 res_size;
|
U32 res_size;
|
||||||
U64 base_pos;
|
U64 base_pos;
|
||||||
|
U64 cmt;
|
||||||
|
U64 res;
|
||||||
};
|
};
|
||||||
|
|
||||||
AllocatorInfo vm_allocator(VMem* vm) {
|
AllocatorInfo vm_allocator(VMemory* vm) {
|
||||||
AllocatorInfo info = { vm_allocator_proc, vm }
|
AllocatorInfo info = { vm_allocator_proc, vm }
|
||||||
return info
|
return info
|
||||||
}
|
}
|
||||||
|
|
||||||
MD_API void* vm_allocator_proc(void * allocator_data, AllocType type, SSIZE size, SSIZE alignment, void* old_memory, SSIZE old_size, U64 flags);
|
MD_API void* vm_allocator_proc(void* allocator_data, AllocType type, SSIZE size, SSIZE alignment, void* old_memory, SSIZE old_size, U64 flags);
|
||||||
|
|
||||||
|
// Inlines
|
||||||
|
|
||||||
|
inline
|
||||||
|
void* alloc_align( AllocatorInfo a, SSIZE size, SSIZE alignment ) {
|
||||||
|
return a.Proc( a.Data, EAllocType_ALLOC, size, alignment, nullptr, 0, MD_DEFAULT_ALLOCATOR_FLAGS );
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
void* alloc( AllocatorInfo a, SSIZE size ) {
|
||||||
|
return alloc_align( a, size, MD_DEFAULT_MEMORY_ALIGNMENT );
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
void allocator_free( AllocatorInfo a, void* ptr ) {
|
||||||
|
if ( ptr != nullptr )
|
||||||
|
a.Proc( a.Data, EAllocType_FREE, 0, 0, ptr, 0, MD_DEFAULT_ALLOCATOR_FLAGS );
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
void free_all( AllocatorInfo a ) {
|
||||||
|
a.Proc( a.Data, EAllocType_FREE_ALL, 0, 0, nullptr, 0, MD_DEFAULT_ALLOCATOR_FLAGS );
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
void* resize( AllocatorInfo a, void* ptr, SSIZE old_size, SSIZE new_size ) {
|
||||||
|
return 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 ) {
|
||||||
|
return a.Proc( a.Data, EAllocType_RESIZE, new_size, alignment, ptr, old_size, MD_DEFAULT_ALLOCATOR_FLAGS );
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
void* default_resize_align( AllocatorInfo a, void* old_memory, SSIZE old_size, SSIZE new_size, SSIZE alignment )
|
||||||
|
{
|
||||||
|
if ( ! old_memory )
|
||||||
|
return alloc_align( a, new_size, alignment );
|
||||||
|
|
||||||
|
if ( new_size == 0 )
|
||||||
|
{
|
||||||
|
allocator_free( a, old_memory );
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( new_size < old_size )
|
||||||
|
new_size = old_size;
|
||||||
|
|
||||||
|
if ( old_size == new_size )
|
||||||
|
{
|
||||||
|
return old_memory;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
void* new_memory = alloc_align( a, new_size, alignment );
|
||||||
|
if ( ! new_memory )
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
mem_move( new_memory, old_memory, min( new_size, old_size ) );
|
||||||
|
allocator_free( a, old_memory );
|
||||||
|
return new_memory;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,62 @@
|
|||||||
|
#ifdef INTELLISENSE_DIRECTIVES
|
||||||
|
# pragma once
|
||||||
|
# include "base_types.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
////////////////////////////////
|
||||||
|
//~ allen: Time
|
||||||
|
|
||||||
|
typedef enum WeekDay
|
||||||
|
{
|
||||||
|
WeekDay_Sun,
|
||||||
|
WeekDay_Mon,
|
||||||
|
WeekDay_Tue,
|
||||||
|
WeekDay_Wed,
|
||||||
|
WeekDay_Thu,
|
||||||
|
WeekDay_Fri,
|
||||||
|
WeekDay_Sat,
|
||||||
|
WeekDay_COUNT,
|
||||||
|
}
|
||||||
|
WeekDay;
|
||||||
|
|
||||||
|
typedef enum 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,
|
||||||
|
}
|
||||||
|
Month;
|
||||||
|
|
||||||
|
typedef struct DateTime DateTime;
|
||||||
|
struct 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]
|
||||||
|
union
|
||||||
|
{
|
||||||
|
WeekDay week_day;
|
||||||
|
U32 wday;
|
||||||
|
};
|
||||||
|
union
|
||||||
|
{
|
||||||
|
Month month;
|
||||||
|
U32 mon;
|
||||||
|
};
|
||||||
|
U32 year; // 1 = 1 CE, 0 = 1 BC
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef U64 DenseTime;
|
||||||
@@ -4,6 +4,10 @@
|
|||||||
|
|
||||||
// metadesk header: intended for "As-Is" library usage
|
// metadesk header: intended for "As-Is" library usage
|
||||||
|
|
||||||
|
// os
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// base
|
// base
|
||||||
|
|
||||||
#include "base/context_cracking.h"
|
#include "base/context_cracking.h"
|
||||||
@@ -15,6 +19,7 @@
|
|||||||
MD_NS_BEGIN
|
MD_NS_BEGIN
|
||||||
|
|
||||||
#include "base/base_types.h"
|
#include "base/base_types.h"
|
||||||
|
#include "base/debug.h"
|
||||||
#include "base/memory.h"
|
#include "base/memory.h"
|
||||||
#include "base/memory_substrate.h"
|
#include "base/memory_substrate.h"
|
||||||
#include "base/arena.h"
|
#include "base/arena.h"
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
#ifdef INTELLISENSE_DIRECTIVES
|
#ifdef INTELLISENSE_DIRECTIVES
|
||||||
# pragma once
|
# pragma once
|
||||||
# include "base/cracking_arch.h"
|
# include "base/context_cracking.h"
|
||||||
# include "base/cracking_compiler.h"
|
|
||||||
# include "base/cracking_os.h"
|
|
||||||
# include "base/linkage.h"
|
# include "base/linkage.h"
|
||||||
|
# include "base/macros.h"
|
||||||
# include "base/base_types.h"
|
# include "base/base_types.h"
|
||||||
|
# include "base/time.h"
|
||||||
|
# include "base/file.h"
|
||||||
# include "base/strings.h"
|
# include "base/strings.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -140,7 +141,7 @@ struct OS_Guid
|
|||||||
U16 data3;
|
U16 data3;
|
||||||
U8 data4[8];
|
U8 data4[8];
|
||||||
};
|
};
|
||||||
StaticAssert(sizeof(OS_Guid) == 16, os_guid_check);
|
md_static_assert(size_of(OS_Guid) == 16, os_guid_check);
|
||||||
|
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
//~ rjf: Thread Types
|
//~ rjf: Thread Types
|
||||||
|
|||||||
@@ -1,25 +0,0 @@
|
|||||||
// Copyright (c) 2024 Epic Games Tools
|
|
||||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
|
||||||
|
|
||||||
#ifndef OS_INC_H
|
|
||||||
#define OS_INC_H
|
|
||||||
|
|
||||||
#if !defined(OS_FEATURE_GRAPHICAL)
|
|
||||||
# define OS_FEATURE_GRAPHICAL 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined(OS_GFX_STUB)
|
|
||||||
# define OS_GFX_STUB 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "metagen/metagen_os/core/metagen_os_core.h"
|
|
||||||
|
|
||||||
#if OS_WINDOWS
|
|
||||||
# include "metagen/metagen_os/core/win32/metagen_os_core_win32.h"
|
|
||||||
#elif OS_LINUX
|
|
||||||
# include "metagen/metagen_os/core/linux/metagen_os_core_linux.h"
|
|
||||||
#else
|
|
||||||
# error OS core layer not implemented for this operating system.
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // OS_INC_H
|
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
#ifdef INTELLISENSE_DIRECTIVES
|
||||||
|
# pragma once
|
||||||
|
# include "context_cracking.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(OS_FEATURE_GRAPHICAL)
|
||||||
|
# define OS_FEATURE_GRAPHICAL 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(OS_GFX_STUB)
|
||||||
|
# define OS_GFX_STUB 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if OS_WINDOWS
|
||||||
|
# include "core/win32/os_core_win32.h"
|
||||||
|
#elif OS_LINUX
|
||||||
|
# include "core/linux/os_core_linux.h"
|
||||||
|
#else
|
||||||
|
# error OS core layer not implemented for this operating system.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "core/os_core.h"
|
||||||
|
|||||||
+90
-1
@@ -15,6 +15,8 @@
|
|||||||
|
|
||||||
// base module
|
// base module
|
||||||
|
|
||||||
|
// base/context_cracking.h
|
||||||
|
|
||||||
word HAS_ATTRIBUTE, MD_HAS_ATTRIBUTE
|
word HAS_ATTRIBUTE, MD_HAS_ATTRIBUTE
|
||||||
|
|
||||||
namespace ARCH_, MD_ARCH_
|
namespace ARCH_, MD_ARCH_
|
||||||
@@ -23,9 +25,13 @@ namespace GCC_, MD_GCC_
|
|||||||
namespace LANG_, MD_LANG_
|
namespace LANG_, MD_LANG_
|
||||||
namespace OS_, MD_OS_
|
namespace OS_, MD_OS_
|
||||||
|
|
||||||
|
// base/linkage.h
|
||||||
|
|
||||||
word global, md_global
|
word global, md_global
|
||||||
word internal, md_internal
|
word internal, md_internal
|
||||||
|
|
||||||
|
// base/macros.h
|
||||||
|
|
||||||
word local_persist, md_local_persist
|
word local_persist, md_local_persist
|
||||||
word thread_static, md_thread_static
|
word thread_static, md_thread_static
|
||||||
|
|
||||||
@@ -43,6 +49,8 @@ word typeof, word md_typeof
|
|||||||
word enum_underlying, md_enum_underlying
|
word enum_underlying, md_enum_underlying
|
||||||
word nullptr, md_nullptr
|
word nullptr, md_nullptr
|
||||||
|
|
||||||
|
// base/base_types.h
|
||||||
|
|
||||||
word U8, MD_U8
|
word U8, MD_U8
|
||||||
word U16, MD_U16
|
word U16, MD_U16
|
||||||
word U32, MD_U32
|
word U32, MD_U32
|
||||||
@@ -66,6 +74,18 @@ word B8, MD_B8
|
|||||||
word B16, MD_B16
|
word B16, MD_B16
|
||||||
word B32, MD_B32
|
word B32, MD_B32
|
||||||
|
|
||||||
|
// base/debug.h
|
||||||
|
|
||||||
|
word trap, md_trap
|
||||||
|
word assert_always, md_assert_always
|
||||||
|
word assert, md_asert
|
||||||
|
|
||||||
|
word invalid_path, md_invalid_path
|
||||||
|
word not_implemented, md_not_implemented
|
||||||
|
word no_op, md_no_op
|
||||||
|
|
||||||
|
// base/memory.h
|
||||||
|
|
||||||
word KILOBYTES, MD_KILOBYTES
|
word KILOBYTES, MD_KILOBYTES
|
||||||
word MEGABYTES, MD_MEGABYTES
|
word MEGABYTES, MD_MEGABYTES
|
||||||
word GIGABYTES, MD_GIGABYTES
|
word GIGABYTES, MD_GIGABYTES
|
||||||
@@ -112,11 +132,71 @@ word memory_zero_struct, md_memory_zero_struct
|
|||||||
word memroy_zero_array, md_memory_zero_array
|
word memroy_zero_array, md_memory_zero_array
|
||||||
word memory_zero_type, md_memory_zero_type
|
word memory_zero_type, md_memory_zero_type
|
||||||
|
|
||||||
|
word memory_match, md_memory_match
|
||||||
|
word memory_match_struct, md_memory_match_struct
|
||||||
|
word memory_match_array, md_memory_match_array
|
||||||
|
word memory_match_type, md_memory_match_type
|
||||||
|
|
||||||
|
word memory_read, md_memory_read
|
||||||
|
word memory_consume, md_memory_consume
|
||||||
|
|
||||||
|
word mem_move, md_mem_move
|
||||||
|
word mem_set, md_mem_set
|
||||||
|
|
||||||
|
namespace ins_atomic_, md_ins_atomic_
|
||||||
|
|
||||||
|
word check_nil, md_check_nil
|
||||||
|
word set_nil, md_set_nil
|
||||||
|
|
||||||
|
// word dll_insert_npz, md_dll_insert_npz,
|
||||||
|
// word dll_push_back_npz, md_dll_push_back_npz,
|
||||||
|
// word dll_push_front_npz, md_dll_push_front_npz,
|
||||||
|
// word dll_remove_npz, md_dll_remove_npz
|
||||||
|
|
||||||
|
// word sll_queue_push_nz, md_sll_queue_push_nz
|
||||||
|
// word sll_queue_push_front_nz, md_sll_queue_push_front_nz
|
||||||
|
// word sll_queue_pop_nz, md_sll_queue_pop_nz
|
||||||
|
|
||||||
|
// word sll_stack_push_n, md_sll_stack_push_n
|
||||||
|
// word sll_stack_pop_n, md_sll_stack_pop_n
|
||||||
|
|
||||||
|
namespace dll_, md_dll_
|
||||||
|
namespace sll_, md_sll_
|
||||||
|
|
||||||
|
word NO_ASAN, MD_NO_ASAN
|
||||||
|
|
||||||
|
namespace asan_, md_asan_
|
||||||
|
|
||||||
|
word stringify, md_stringify
|
||||||
|
word stringify_, md_stringify_
|
||||||
|
|
||||||
|
word glue, md_glue
|
||||||
|
word glue_, md_glue_
|
||||||
|
|
||||||
|
word array_count, md_array_count
|
||||||
|
|
||||||
|
word ceil_integer_div, md_ceil_integer_div
|
||||||
|
|
||||||
word swap, md_swap
|
word swap, md_swap
|
||||||
|
|
||||||
word readonly, md_readonly
|
word int_from_ptr, md_int_from_ptr
|
||||||
|
word ptr_from_int, md_ptr_from_int
|
||||||
|
|
||||||
|
word compose_64bit, md_compose_64bit
|
||||||
|
word align_pow2, md_align_pow2
|
||||||
|
word align_down_pow2, md_align_down_pow2
|
||||||
|
word align_pad_pow2, md_align_pad_pow2
|
||||||
|
word is_pow2, md_is_pow2
|
||||||
|
word is_pow2_or_zero, md_is_pow2_or_zero
|
||||||
|
|
||||||
|
word extract_bit, md_extract_bit
|
||||||
|
word zero_struct, md_zero_struct
|
||||||
|
|
||||||
|
word this_function_name, md_this_function_name
|
||||||
|
|
||||||
|
word read_only, md_read_only
|
||||||
|
|
||||||
|
// base/memory_substrate.h
|
||||||
|
|
||||||
word AllocType, MD_AllocType
|
word AllocType, MD_AllocType
|
||||||
word AllocatorProc, MD_AllocatorProc
|
word AllocatorProc, MD_AllocatorProc
|
||||||
@@ -145,8 +225,17 @@ word heap, md_heap
|
|||||||
word malloc, md_malloc
|
word malloc, md_malloc
|
||||||
word mfree, md_mfree
|
word mfree, md_mfree
|
||||||
|
|
||||||
|
word VMem, MD_VMem
|
||||||
|
namespace vm_, md_vm_
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// base/math.h
|
||||||
|
|
||||||
word Rng1U64, MD_Rng1U64
|
word Rng1U64, MD_Rng1U64
|
||||||
|
|
||||||
|
// base/strings.h
|
||||||
|
|
||||||
word String8, MD_String8
|
word String8, MD_String8
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user