From 268271e4a7330c7c2b4a353e40b7961d027bd7e3 Mon Sep 17 00:00:00 2001 From: Ed_ Date: Wed, 5 Feb 2025 13:42:36 -0500 Subject: [PATCH] beginning to lift vmem ops out of the arena --- .vscode/settings.json | 7 +- code/base/arena.c | 78 +++++- code/base/arena.h | 56 +++-- code/base/base_types.h | 6 + code/base/debug.h | 43 ++++ code/base/file.h | 23 ++ code/base/memory.h | 468 +++++++++++++++++++++++++++-------- code/base/memory_substrate.c | 177 +++++++++++++ code/base/memory_substrate.h | 113 ++++++++- code/base/time.h | 62 +++++ code/metadesk.h | 5 + code/os/core/os_core.h | 9 +- code/os/metagen_os_inc.h | 25 -- code/os/os.h | 22 ++ gen_c11/c11.refactor | 93 ++++++- 15 files changed, 1017 insertions(+), 170 deletions(-) create mode 100644 code/base/debug.h create mode 100644 code/base/file.h create mode 100644 code/base/memory_substrate.c create mode 100644 code/base/time.h delete mode 100644 code/os/metagen_os_inc.h diff --git a/.vscode/settings.json b/.vscode/settings.json index 8613d25..535e523 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -16,6 +16,11 @@ "xmemory": "cpp", "memory.h": "c", "charconv": "c", - "xstring": "c" + "xstring": "c", + "memory_substrate.h": "c", + "os.h": "c", + "os_core.h": "c", + "file.h": "c", + "xiosbase": "c" } } \ No newline at end of file diff --git a/code/base/arena.c b/code/base/arena.c index 6b651df..dcee4be 100644 --- a/code/base/arena.c +++ b/code/base/arena.c @@ -11,7 +11,8 @@ //- rjf: arena creation/destruction -internal Arena * +#if 0 +internal Arena* arena_alloc_(ArenaParams *params) { // rjf: round up reserve/commit sizes @@ -67,17 +68,78 @@ arena_alloc_(ArenaParams *params) AsanUnpoisonMemoryRegion(base, ARENA_HEADER_SIZE); return arena; } +#endif -internal void -arena_release(Arena *arena) +Arena* +arena_alloc_(ArenaParams* params) { - for(Arena *n = arena->current, *prev = 0; n != 0; n = prev) - { - prev = n->prev; - os_release(n, n->res); - } + // rjf: round up reserve/commit sizes + U64 reserve_size = params->reserve_size; + U64 commit_size = params->commit_size; + + + if(params->flags & ArenaFlag_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); + } + 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 internal void * diff --git a/code/base/arena.h b/code/base/arena.h index 28533f9..7d357c8 100644 --- a/code/base/arena.h +++ b/code/base/arena.h @@ -2,6 +2,7 @@ # pragma once # include "macros.h" # include "base_types.h" +# include "memory_substrate.h" #endif // Copyright (c) 2024 Epic Games Tools @@ -10,7 +11,7 @@ //////////////////////////////// //~ rjf: Constants -#define MD_ARENA_HEADER_SIZE 64 +#define ARENA_HEADER_SIZE 64 //////////////////////////////// //~ rjf: Types @@ -43,17 +44,18 @@ struct ArenaParams typedef struct Arena Arena; struct Arena { - Arena* prev; // previous arena in chain - Arena* current; // current arena in chain - ArenaFlags flags; - U32 cmt_size; - U64 res_size; - U64 base_pos; - U64 pos; - U64 cmt; - U64 res; + AllocatorInfo backing; + Arena* prev; // previous arena in chain + Arena* current; // current arena in chain + ArenaFlags flags; + U32 cmt_size; + U64 res_size; + U64 base_pos; + U64 pos; + U64 cmt; + 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; struct TempArena @@ -65,27 +67,51 @@ struct TempArena //////////////////////////////// //~ rjf: Arena Functions -//- rjf: arena creation/destruction -internal Arena* arena_alloc_(ArenaParams *params); -#define arena_alloc(...) arena_alloc_( & ( ArenaParams) { .reserve_size = MB(64), .commit_size = KB(64), __VA_ARGS__ } ) +MD_API void* arena_allocator_proc(void* allocator_data, AllocType type, SSIZE size, SSIZE alignment, void* old_memory, SSIZE old_size, U64 flags); -internal void arena_release(Arena *arena); +//- rjf: arena creation/destruction + +MD_API Arena* arena_alloc_(ArenaParams *params); +#define arena_alloc(...) arena_alloc_( & ( ArenaParams) { .reserve_size = MB(64), .commit_size = KB(64), __VA_ARGS__ } ) + +void arena_release(Arena *arena); //- rjf: arena push/pop/pos core functions + internal void *arena_push (Arena *arena, U64 size, U64 align); internal U64 arena_pos (Arena *arena); internal void arena_pop_to(Arena *arena, U64 pos); //- rjf: arena push/pop helpers + internal void arena_clear(Arena *arena); internal void arena_pop (Arena *arena, U64 amt); //- rjf: temporary arena scopes + internal TempArena temp_arena_begin(Arena *arena); internal void temp_arena_end(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))) +#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); + } +} + + diff --git a/code/base/base_types.h b/code/base/base_types.h index 7ea7c01..207eb20 100644 --- a/code/base/base_types.h +++ b/code/base/base_types.h @@ -57,6 +57,10 @@ typedef ptrdiff_t 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. #if defined( _WIN64 ) typedef signed __int64 SPTR; @@ -88,3 +92,5 @@ static_assert( sizeof( F64 ) == 8, "sizeof(F64) != 8" ); typedef S8 B8; typedef S16 B16; typedef S32 B32; + +typedef void VoidProc(void); diff --git a/code/base/debug.h b/code/base/debug.h new file mode 100644 index 0000000..811e923 --- /dev/null +++ b/code/base/debug.h @@ -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 diff --git a/code/base/file.h b/code/base/file.h new file mode 100644 index 0000000..89158b4 --- /dev/null +++ b/code/base/file.h @@ -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; +}; diff --git a/code/base/memory.h b/code/base/memory.h index 56acd5f..1b3f4ce 100644 --- a/code/base/memory.h +++ b/code/base/memory.h @@ -68,107 +68,283 @@ //////////////////////////////// //~ rjf: Type -> Alignment -#if COMPILER_MSVC -# define align_of(T) __alignof(T) -#elif COMPILER_CLANG -# define align_of(T) __alignof(T) -#elif COMPILER_GCC -# define align_of(T) __alignof__(T) -#else -# error AlignOf not defined for this compiler. +#ifndef align_of +# if COMPILER_MSVC +# define align_of(T) __alignof(T) +# elif COMPILER_CLANG +# define align_of(T) __alignof(T) +# elif COMPILER_GCC +# define align_of(T) __alignof__(T) +# else +# error AlignOf not defined for this compiler. +# endif #endif //////////////////////////////// //~ rjf: Member Offsets +#ifndef membeMD_DYN_LINKr #define member(T, m) ( ((T*) 0)->m ) +#endif +#ifndef offset_of #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))) +#endif +#ifndef cast_from_member #define cast_from_member(T, m, ptr) (T*) (((U8*)ptr) - offset_of(T, m)) +#endif //////////////////////////////// //~ rjf: For-Loop Construct Macros +#ifndef defer_loop #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)) +#endif +#ifndef each_enum_val #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 ) +#endif //////////////////////////////// //~ 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)) +#endif +#ifndef memory_str_len #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))) +#endif +#ifndef memory_copy_array #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)) +#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_array(a) memroy_zero((a), sizeof(a)) -#define memory_zero_type(m,c) memroy_zero((m), sizeof( *(m)) * (c)) +#endif +#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) +#endif +#ifndef memory_match_struct #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)) +#endif +#ifndef memory_read #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) ) - -//////////////////////////////// -//~ 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 -#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 -# define assert(x) assert_always(x) -#else -# define assert(x) (void)(x) -#endif + U8* dest_ptr = rcast( U8*, destination); + U8 const* src_ptr = rcast( U8 const*, source); -#define invalid_path assert( ! "Invalid Path!") -#define not_implemented assert( ! "Not Implemented!") -#define no_op ((void)0) -#define md_static_assert(C, ID) global U8 glue(ID, __LINE__)[ (C) ? 1 : -1 ] + if ( dest_ptr == src_ptr ) + return dest_ptr; + + 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 -#if OS_WINDOWS -# if ARCH_X64 -# 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_dec_eval(x) InterlockedDecrement64((volatile __int64 *)(x)) -# define ins_atomic_u64_eval_assign(x,c) InterlockedExchange64((volatile __int64 *)(x), (c)) -# define ins_atomic_u64_add_eval(x,c) InterlockedAdd64((volatile __int64 *)(x), c) -# define ins_atomic_u64_eval_cond_assign(x,k,c) InterlockedCompareExchange64((volatile __int64 *)(x), (k), (c)) -# define ins_atomic_u32_eval(x,c) InterlockedAdd((volatile LONG *)(x), 0) -# define ins_atomic_u32_eval_assign(x,c) InterlockedExchange((volatile LONG *)(x), (c)) -# define ins_atomic_u32_eval_cond_assign(x,k,c) InterlockedCompareExchange((volatile LONG *)(x), (k), (c)) -# define ins_atomic_ptr_eval_assign(x,c) (void*) ins_atomic_u64_eval_assign((volatile __int64 *)(x), (__int64)(c)) +#ifndef ins_atomic_u64_eval +# if OS_WINDOWS +# if ARCH_X64 +# 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_dec_eval(x) InterlockedDecrement64((volatile __int64 *)(x)) +# define ins_atomic_u64_eval_assign(x,c) InterlockedExchange64((volatile __int64 *)(x), (c)) +# define ins_atomic_u64_add_eval(x,c) InterlockedAdd64((volatile __int64 *)(x), c) +# define ins_atomic_u64_eval_cond_assign(x,k,c) InterlockedCompareExchange64((volatile __int64 *)(x), (k), (c)) +# define ins_atomic_u32_eval(x,c) InterlockedAdd((volatile LONG *)(x), 0) +# define ins_atomic_u32_eval_assign(x,c) InterlockedExchange((volatile LONG *)(x), (c)) +# define ins_atomic_u32_eval_cond_assign(x,k,c) InterlockedCompareExchange((volatile LONG *)(x), (k), (c)) +# define ins_atomic_ptr_eval_assign(x,c) (void*) ins_atomic_u64_eval_assign((volatile __int64 *)(x), (__int64)(c)) +# else +# error Atomic intrinsics not defined for this operating system / architecture combination. +# endif +# elif OS_LINUX +# if ARCH_X64 +# define ins_atomic_u64_inc_eval(x) __sync_fetch_and_add((volatile U64 *)(x), 1) +# else +# error Atomic intrinsics not defined for this operating system / architecture combination. +# endif # else -# error Atomic intrinsics not defined for this operating system / architecture combination. +# error Atomic intrinsics not defined for this operating system. # endif -#elif OS_LINUX -# if ARCH_X64 -# define ins_atomic_u64_inc_eval(x) __sync_fetch_and_add((volatile U64 *)(x), 1) -# else -# error Atomic intrinsics not defined for this operating system / architecture combination. -# endif -#else -# error Atomic intrinsics not defined for this operating system. #endif //////////////////////////////// @@ -176,11 +352,16 @@ //- rjf: linked list macro helpers +#ifndef check_nil #define check_nil(nil,p) ((p) == 0 || (p) == nil) +#endif +#ifndef set_nil #define set_nil(nil,p) ((p) = nil) +#endif //- rjf: doubly-linked-lists +#ifndef dll_insert_npz // insert next-previous with nil #define dll_insert_npz(nil, f, l, p, n, next, prev) ( \ check_nil(nil, f) ? ( \ @@ -213,10 +394,16 @@ ) \ ) \ ) +#endif +#ifndef dll_push_back_npz // 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) +#endif +#ifndef dll_push_front_npz // 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) +#endif +#ifndef dll_remove_npz // remove next-previous with nil #define dll_remove_npz(nil, f, l, n, next, prev) \ ( \ @@ -241,9 +428,11 @@ : ((n)->next->prev = (n)->prev) \ ) \ ) +#endif //- rjf: singly-linked, doubly-headed lists (queues) +#ifndef sll_queue_push_nz // queue-push next with nil #define sll_queue_push_nz(nil, f, l, n, next) \ ( \ @@ -257,6 +446,8 @@ set_nil(nil,(n)->next) \ ) \ ) +#endif +#ifndef sll_queue_push_front_nz // queue-push-front next with nil #define sll_queue_push_front_nz(nil, f, l, n, next) \ ( \ @@ -269,6 +460,8 @@ (f) = (n) \ ) \ ) +#endif +#ifndef sll_queue_pop_nz // queue-pop next with nil #define sll_queue_pop_nz(nil, f, l, next) \ ( \ @@ -280,68 +473,109 @@ (f)=(f)->next \ ) \ ) +#endif //- 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) ) +#endif +#ifndef sll_stack_pop_n #define sll_stack_pop_n(f,next) ( (f) = (f)->next ) +#endif //- 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) +#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) +#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) +#endif +#ifndef dll_remove_np #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) +#endif +#ifndef dll_push_back #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) +#endif +#ifndef dll_remove #define dll_remove(f, l, n) dll_remove_npz (0, f, l, n, next, prev) +#endif //- 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_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) +#endif +#ifndef sll_queue_push #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) +#endif +#ifndef sll_queue_pop #define sll_queue_pop(f, l) sll_queue_pop_nz (0, f, l, next) +#endif //- rjf: singly-linked, singly-headed list helpers +#ifndef sll_stack_push #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) +#endif //////////////////////////////// //~ rjf: Address Sanitizer Markup -#if COMPILER_MSVC -# if defined(__SANITIZE_ADDRESS__) -# define ASAN_ENABLED 1 -# define NO_ASAN __declspec(no_sanitize_address) -# else -# define NO_ASAN -# endif -#elif COMPILER_CLANG -# if defined(__has_feature) -# if __has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__) -# define ASAN_ENABLED 1 -# endif -# endif -# define NO_ASAN __attribute__((no_sanitize("address"))) -#else -# define NO_ASAN +#ifndef NO_ASAN +# if COMPILER_MSVC +# if defined(__SANITIZE_ADDRESS__) +# define ASAN_ENABLED 1 +# define NO_ASAN __declspec(no_sanitize_address) +# else +# define NO_ASAN +# endif +# elif COMPILER_CLANG +# if defined(__has_feature) +# if __has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__) +# define ASAN_ENABLED 1 +# endif +# endif +# define NO_ASAN __attribute__((no_sanitize("address"))) +# else +# define NO_ASAN +# endif #endif -#if MD_ASAN_ENABLED -# 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_unpoison_memory_region(void const volatile *addr, size_t size); +#ifndef asan_poison_memory_region +# if MD_ASAN_ENABLED +# 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_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_unpoison_memory_region(addr, size) __asan_unpoison_memory_region((addr), (size)) -#else -# define asan_poison_memory_region(addr, size) ((void)(addr), (void)(size)) -# define asan_unpoison_memory_region(addr, size) ((void)(addr), (void)(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)) +# else +# define asan_poison_memory_region(addr, size) ((void)(addr), (void)(size)) +# define asan_unpoison_memory_region(addr, size) ((void)(addr), (void)(size)) +# endif #endif //////////////////////////////// @@ -379,39 +613,61 @@ # endif #endif +#ifndef ptr_from_int #define ptr_from_int(i) (void*)((U8*)0 + (i)) +#endif +#ifndef compose_64bit #define compose_64bit(a,b) ((((U64)a) << 32) | ((U64)b)); -#define align_pow_2(x,b) (((x) + (b) - 1)&( ~((b) - 1))) -#define align_down_pow_2(x,b) ((x) & (~((b) - 1))) -#define align_pad_pow_2(x,b) ((0-(x)) & ((b) - 1)) -#define is_pow_2(x) ((x) != 0 && ((x )& ((x) - 1)) == 0) -#define is_pow_2_or_zero(x) ((((x) - 1) & (x)) == 0) +#endif +#ifndef align_pow2 +#define align_pow2(x,b) (((x) + (b) - 1) & ( ~((b) - 1))) +#endif +#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) - -#if LANG_CPP -# define zero_struct {} -#else -# define zero_struct {0} #endif -#if COMPILER_MSVC && COMPILER_MSVC_YEAR < 2015 -# define this_function_name "unknown" -#else -# define this_function_name __func__ +#ifndef zero_struct +# if LANG_CPP +# define zero_struct {} +# else +# define zero_struct {0} +# endif #endif -#if COMPILER_MSVC || (COMPILER_CLANG && OS_WINDOWS) -# pragma section(".rdata$", read) -# define read_only __declspec(allocate(".rdata$")) -#elif (COMPILER_CLANG && OS_LINUX) -# define read_only __attribute__((section(".rodata"))) -#else -// 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 -// strange warning about malformed section attributes, and it doesn't look -// like writing to that section reliably produces access violations, strangely -// enough. (It does on Clang) -# define read_only +#ifndef this_function_name +# if COMPILER_MSVC && COMPILER_MSVC_YEAR < 2015 +# define this_function_name "unknown" +# else +# define this_function_name __func__ +# endif +#endif + +#ifndef read_only +# if COMPILER_MSVC || (COMPILER_CLANG && OS_WINDOWS) +# pragma section(".rdata$", read) +# define read_only __declspec(allocate(".rdata$")) +# elif (COMPILER_CLANG && OS_LINUX) +# define read_only __attribute__((section(".rodata"))) +# else + // 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 + // strange warning about malformed section attributes, and it doesn't look + // like writing to that section reliably produces access violations, strangely + // enough. (It does on Clang) +# define read_only +# endif #endif diff --git a/code/base/memory_substrate.c b/code/base/memory_substrate.c new file mode 100644 index 0000000..a3d4a6f --- /dev/null +++ b/code/base/memory_substrate.c @@ -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) +{ + +} + diff --git a/code/base/memory_substrate.h b/code/base/memory_substrate.h index ad493c4..dd8a2ea 100644 --- a/code/base/memory_substrate.h +++ b/code/base/memory_substrate.h @@ -13,9 +13,11 @@ // 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. +#ifndef MD__ONES #define MD__ONES ( 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 typedef U32 AllocType; 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. void* resize_align( AllocatorInfo a, void* ptr, SSIZE old_size, SSIZE new_size, SSIZE alignment ); +#ifndef alloc_item //! Allocate memory for an item. #define alloc_item( allocator_, Type ) ( Type* )alloc( allocator_, size_of( Type ) ) +#endif +#ifndef alloc_array //! Allocate memory for an array of items. #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 */ /* 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 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 ); +#ifndef heap //! The heap allocator backed by operating system's memory manager. #define heap() (AllocatorInfo){ AllocatorInfo allocator = { heap_allocator_proc, nullptr }; return allocator; } +#endif +#ifndef malloc //! Helper to allocate memory using heap allocator. #define malloc( sz ) alloc( heap(), sz ) +#endif +#ifndef mfree //! Helper to free memory allocated by heap allocator. #define mfree( ptr ) free( heap(), ptr ) +#endif -typedef struct VMem; -struct VMem { +typedef U32 VMemoryFlags; +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 res_size; U64 base_pos; + U64 cmt; + U64 res; }; -AllocatorInfo vm_allocator(VMem* vm) { +AllocatorInfo vm_allocator(VMemory* vm) { AllocatorInfo info = { vm_allocator_proc, vm } 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; + } +} diff --git a/code/base/time.h b/code/base/time.h new file mode 100644 index 0000000..cfa59f2 --- /dev/null +++ b/code/base/time.h @@ -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; diff --git a/code/metadesk.h b/code/metadesk.h index e4f3c55..f2e8d28 100644 --- a/code/metadesk.h +++ b/code/metadesk.h @@ -4,6 +4,10 @@ // metadesk header: intended for "As-Is" library usage +// os + + + // base #include "base/context_cracking.h" @@ -15,6 +19,7 @@ MD_NS_BEGIN #include "base/base_types.h" +#include "base/debug.h" #include "base/memory.h" #include "base/memory_substrate.h" #include "base/arena.h" diff --git a/code/os/core/os_core.h b/code/os/core/os_core.h index 40de579..c652e57 100644 --- a/code/os/core/os_core.h +++ b/code/os/core/os_core.h @@ -1,10 +1,11 @@ #ifdef INTELLISENSE_DIRECTIVES # pragma once -# include "base/cracking_arch.h" -# include "base/cracking_compiler.h" -# include "base/cracking_os.h" +# include "base/context_cracking.h" # include "base/linkage.h" +# include "base/macros.h" # include "base/base_types.h" +# include "base/time.h" +# include "base/file.h" # include "base/strings.h" #endif @@ -140,7 +141,7 @@ struct OS_Guid U16 data3; 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 diff --git a/code/os/metagen_os_inc.h b/code/os/metagen_os_inc.h deleted file mode 100644 index 4ed76be..0000000 --- a/code/os/metagen_os_inc.h +++ /dev/null @@ -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 diff --git a/code/os/os.h b/code/os/os.h index e69de29..efa9a46 100644 --- a/code/os/os.h +++ b/code/os/os.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" diff --git a/gen_c11/c11.refactor b/gen_c11/c11.refactor index 5b7a9da..563c18f 100644 --- a/gen_c11/c11.refactor +++ b/gen_c11/c11.refactor @@ -15,6 +15,8 @@ // base module +// base/context_cracking.h + word HAS_ATTRIBUTE, MD_HAS_ATTRIBUTE namespace ARCH_, MD_ARCH_ @@ -23,9 +25,13 @@ namespace GCC_, MD_GCC_ namespace LANG_, MD_LANG_ namespace OS_, MD_OS_ +// base/linkage.h + word global, md_global word internal, md_internal +// base/macros.h + word local_persist, md_local_persist word thread_static, md_thread_static @@ -43,6 +49,8 @@ word typeof, word md_typeof word enum_underlying, md_enum_underlying word nullptr, md_nullptr +// base/base_types.h + word U8, MD_U8 word U16, MD_U16 word U32, MD_U32 @@ -62,10 +70,22 @@ word UPTR, MD_UPTR word F32, MD_F32 word F64, MD_F64 -word B8, MD_B8 +word B8, MD_B8 word B16, MD_B16 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 MEGABYTES, MD_MEGABYTES 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 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 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 AllocatorProc, MD_AllocatorProc @@ -145,8 +225,17 @@ word heap, md_heap word malloc, md_malloc word mfree, md_mfree +word VMem, MD_VMem +namespace vm_, md_vm_ + + + +// base/math.h + word Rng1U64, MD_Rng1U64 +// base/strings.h + word String8, MD_String8