diff --git a/src/base/base_arena.c b/src/base/base_arena.c index 06f38de4..f75dd30f 100644 --- a/src/base/base_arena.c +++ b/src/base/base_arena.c @@ -55,9 +55,6 @@ arena_alloc__sized(U64 init_res, U64 init_cmt) arena->cmt = cmt; arena->res = res; arena->align = 8; -#if ENABLE_DEV - arena->dev = 0; -#endif arena->grow = 1; arena->large_pages = large_pages; } @@ -209,10 +206,6 @@ arena_pop_to(Arena *arena, U64 big_pos_unclamped) internal void arena_absorb(Arena *arena, Arena *sub) { -#if ENABLE_DEV - arena_annotate_absorb__dev(arena, sub); -#endif - // base adjustment Arena *current = arena->current; U64 base_adjust = current->base_pos + current->res; @@ -233,9 +226,6 @@ internal void * arena_push(Arena *arena, U64 size) { void *memory = arena_push__impl(arena, size); -#if ENABLE_DEV - arena_annotate_push__dev(arena, size, memory); -#endif return memory; } @@ -246,9 +236,6 @@ arena_push_contiguous(Arena *arena, U64 size) arena->grow = 0; void *memory = arena_push(arena, size); arena->grow = restore; -#if ENABLE_DEV - arena_annotate_push__dev(arena, size, memory); -#endif return memory; } diff --git a/src/base/base_arena.h b/src/base/base_arena.h index 0a9ca92f..dd8249ce 100644 --- a/src/base/base_arena.h +++ b/src/base/base_arena.h @@ -36,7 +36,6 @@ struct Arena U64 cmt; U64 res; U64 align; - struct ArenaDev *dev; B8 grow; B8 large_pages; }; @@ -82,13 +81,7 @@ internal B32 ensure_commit(void **cmt, void *pos, U64 cmt_block_size); //////////////////////////////// //~ NOTE(allen): Main API Macros -#if !ENABLE_DEV -# define push_array_no_zero(a,T,c) (T*)arena_push((a), sizeof(T)*(c)) -#else -# define push_array_no_zero(a,T,c) (tctx_write_this_srcloc(), (T*)arena_push((a), sizeof(T)*(c))) -#endif -#define push_array_no_zero__no_annotation(a,T,c) (T*)arena_push__impl((a), sizeof(T)*(c)) - +#define push_array_no_zero(a,T,c) (T*)arena_push((a), sizeof(T)*(c)) #define push_array(a,T,c) (T*)MemoryZero(push_array_no_zero(a,T,c), sizeof(T)*(c)) #endif // BASE_ARENA_H diff --git a/src/base/base_arena_dev.c b/src/base/base_arena_dev.c deleted file mode 100644 index 94c334bd..00000000 --- a/src/base/base_arena_dev.c +++ /dev/null @@ -1,197 +0,0 @@ -// Copyright (c) 2024 Epic Games Tools -// Licensed under the MIT license (https://opensource.org/license/mit/) - -//////////////////////////////// -// NOTE(allen): Dev Arena - -#if ENABLE_DEV - -internal void -arena_annotate_push__dev(Arena *arena, U64 size, void *ptr){ - ArenaDev *dev = arena->dev; - if (dev != 0 && ptr != 0){ - //- read location - char *file_name = 0; - U64 line_number = 0; - tctx_read_srcloc(&file_name, &line_number); - tctx_write_srcloc(0, 0); - - //- profile - ArenaProf *prof = dev->prof; - if (prof != 0){ - // c string -> string - String8 file_name_str = str8_lit("(null)"); - if (file_name != 0){ - file_name_str = str8_cstring(file_name); - } - // record - arena_prof_inc_counters__dev(dev->arena, prof, file_name_str, line_number, size, 1); - } - } -} - -internal void -arena_annotate_absorb__dev(Arena *arena, Arena *sub){ - ArenaDev *dev = arena->dev; - ArenaDev *sub_dev = sub->dev; - if (dev != 0 && sub_dev != 0){ - //- merge profiles - ArenaProf *prof = dev->prof; - ArenaProf *sub_prof = sub_dev->prof; - if (prof != 0 && sub_prof != 0){ - for (ArenaProfNode *sub_node = sub_prof->first; - sub_node != 0; - sub_node = sub_node->next){ - arena_prof_inc_counters__dev(dev->arena, prof, sub_node->file_name, sub_node->line, - sub_node->size, sub_node->count); - } - } - } - //- release the sub dev memory - if (sub_dev != 0){ - arena_release(sub_dev->arena); - } -} - -internal ArenaDev* -arena_equip__dev(Arena *arena){ - ArenaDev *result = arena->dev; - if (result == 0){ - Arena *dev_arena = arena_alloc(); - ArenaDev *dev = (ArenaDev*)arena_push__impl(dev_arena, sizeof(ArenaDev)); - MemoryZeroStruct(dev); - dev->arena = dev_arena; - arena->dev = dev; - result = dev; - } - return(result); -} - -internal void -arena_equip_profile__dev(Arena *arena){ - ArenaDev *dev = arena_equip__dev(arena); - if (dev->prof == 0){ - dev->prof = (ArenaProf*)arena_push__impl(dev->arena, sizeof(ArenaProf)); - MemoryZeroStruct(dev->prof); - } -} - -internal void -arena_print_profile__dev(Arena *arena, Arena *out_arena, String8List *out){ - Assert(arena != out_arena); - - //- get dev & disable - ArenaDev *dev = arena->dev; - arena->dev = 0; - - //- get prof - ArenaProf *prof = (dev != 0)?dev->prof:0; - - //- not equipped with prof - if (prof == 0){ - str8_list_push(out_arena, out, str8_lit("not equipped with a memory profile\n")); - } - - //- print prof - if (prof != 0){ - Temp scratch = temp_begin(dev->arena); - - //- make flat array - U64 note_count = prof->count; - ArenaProfNode **notes = push_array_no_zero__no_annotation(scratch.arena, ArenaProfNode*, note_count); - { - ArenaProfNode **note_ptr = notes; - for (ArenaProfNode *node = prof->first; - node != 0; - node = node->next, note_ptr += 1){ - *note_ptr = node; - } - } - - //- file name size - U64 max_file_name_size = 0; - { - ArenaProfNode **note_ptr = notes; - for (U64 i = 0; i < note_count; i += 1, note_ptr += 1){ - max_file_name_size = Max(max_file_name_size, (**note_ptr).file_name.size); - } - } - - //- sort (> size, < [address]) - for (U64 i = 0; i < note_count; i += 1){ - ArenaProfNode **i_note = notes + i; - ArenaProfNode **min_note = i_note; - for (U64 j = i + 1; j < note_count; j += 1){ - ArenaProfNode **j_note = notes + j; - if ((**j_note).size > (**min_note).size || - ((**j_note).size == (**min_note).size && *j_note < *min_note)){ - min_note = j_note; - } - } - if (min_note != i_note){ - ArenaProfNode *t = *i_note; - *i_note = *min_note; - *min_note = t; - } - } - - //- total size - U64 total_size = 0; - { - ArenaProfNode **note_ptr = notes; - for (U64 i = 0; i < note_count; i += 1, note_ptr += 1){ - ArenaProfNode *note = *note_ptr; - total_size += note->size; - } - } - - //- print - { - str8_list_pushf(out_arena, out, "memory total: %llu\n", total_size); - - ArenaProfNode **note_ptr = notes; - for (U64 i = 0; i < note_count; i += 1, note_ptr += 1){ - ArenaProfNode *note = *note_ptr; - String8 location = push_str8f(scratch.arena, "%S:%5llu:", - note->file_name, note->line); - F32 percent = 100.f*((F32)note->size)/total_size; - str8_list_pushf(out_arena, out, "%*.*s %12llu %5.2f%% [%5llu]\n", - max_file_name_size + 7, str8_varg(location), - note->size, percent, note->count); - } - } - - temp_end(scratch); - } - - //- restore dev - arena->dev = dev; -} - -internal void -arena_prof_inc_counters__dev(Arena *dev_arena, ArenaProf *prof, String8 file_name, U64 line, - U64 size, U64 count){ - // find existing profile node - ArenaProfNode *prof_node = 0; - for (ArenaProfNode *node = prof->first; - node != 0; - node = node->next){ - if (node->line == line && str8_match(file_name, node->file_name, 0)){ - prof_node = node; - break; - } - } - // make new histogram node if necessary - if (prof_node == 0){ - prof_node = (ArenaProfNode*)arena_push(dev_arena, sizeof(*prof_node)); - SLLQueuePush(prof->first, prof->last, prof_node); - prof->count += 1; - prof_node->file_name = file_name; - prof_node->line = line; - } - // record this allocation - prof_node->size += size; - prof_node->count += count; -} - -#endif diff --git a/src/base/base_arena_dev.h b/src/base/base_arena_dev.h deleted file mode 100644 index 14d16b1d..00000000 --- a/src/base/base_arena_dev.h +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright (c) 2024 Epic Games Tools -// Licensed under the MIT license (https://opensource.org/license/mit/) - -#ifndef BASE_ARENA_DEV_H -#define BASE_ARENA_DEV_H - -//////////////////////////////// -//~ NOTE(allen): Dev Arena Types - -typedef struct ArenaDev ArenaDev; -struct ArenaDev -{ - Arena *arena; - struct ArenaProf *prof; -}; - -typedef struct ArenaProf ArenaProf; -struct ArenaProf -{ - struct ArenaProfNode *first; - struct ArenaProfNode *last; - U64 count; -}; - -typedef struct ArenaProfNode ArenaProfNode; -struct ArenaProfNode -{ - ArenaProfNode *next; - String8 file_name; - U64 line; - U64 size; - U64 count; -}; - -//////////////////////////////// -//~ NOTE(allen): Dev Arena Functions - -#if ENABLE_DEV -internal void arena_annotate_push__dev(Arena *arena, U64 size, void *ptr); -internal void arena_annotate_absorb__dev(Arena *arena, Arena *sub); -internal ArenaDev* arena_equip__dev(Arena *arena); -internal void arena_equip_profile__dev(Arena *arena); -internal void arena_print_profile__dev(Arena *arena, Arena *out_arena, String8List *out); -internal void arena_prof_inc_counters__dev(Arena *dev_arena, ArenaProf *prof, String8 file_name, U64 line, U64 size, U64 count); -#endif - -#endif // BASE_ARENA_DEV_H diff --git a/src/base/base_bits.c b/src/base/base_bits.c deleted file mode 100644 index 1cb13455..00000000 --- a/src/base/base_bits.c +++ /dev/null @@ -1,103 +0,0 @@ -// Copyright (c) 2024 Epic Games Tools -// Licensed under the MIT license (https://opensource.org/license/mit/) - -#if COMPILER_MSVC || (COMPILER_CLANG && OS_WINDOWS) - -internal U64 -count_bits_set16(U16 val) -{ - return __popcnt16(val); -} - -internal U64 -count_bits_set32(U32 val) -{ - return __popcnt(val); -} - -internal U64 -count_bits_set64(U64 val) -{ - return __popcnt64(val); -} - -internal U64 -ctz32(U32 mask) -{ - unsigned long idx; - _BitScanForward(&idx, mask); - return idx; -} - -internal U64 -ctz64(U64 mask) -{ - unsigned long idx; - _BitScanForward64(&idx, mask); - return idx; -} - -internal U64 -clz32(U32 mask) -{ - unsigned long idx; - _BitScanReverse(&idx, mask); - return 31 - idx; -} - -internal U64 -clz64(U64 mask) -{ - unsigned long idx; - _BitScanReverse64(&idx, mask); - return 63 - idx; -} - -#elif COMPILER_CLANG || COMPILER_GCC - -internal U64 -count_bits_set16(U16 val) -{ - NotImplemented; - return 0; -} - -internal U64 -count_bits_set32(U32 val) -{ - NotImplemented; - return 0; -} - -internal U64 -count_bits_set64(U64 val) -{ - NotImplemented; - return 0; -} - -internal U64 -ctz32(U32 val) -{ - NotImplemented; - return 0; -} - -internal U64 -clz32(U32 val) -{ - NotImplemented; - return 0; -} - -internal U64 -clz64(U64 val) -{ - NotImplemented; - return 0; -} - -#else -# error "bits not defined for this target" -#endif - diff --git a/src/base/base_bits.h b/src/base/base_bits.h deleted file mode 100644 index ab9482d3..00000000 --- a/src/base/base_bits.h +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright (c) 2024 Epic Games Tools -// Licensed under the MIT license (https://opensource.org/license/mit/) - -#ifndef BASE_BITS_H -#define BASE_BITS_H - -#define ExtractBit(word, idx) (((word) >> (idx)) & 1) - -internal U64 count_bits_set16(U16 val); -internal U64 count_bits_set32(U32 val); -internal U64 count_bits_set64(U64 val); - -internal U64 ctz32(U32 val); -internal U64 ctz64(U64 val); -internal U64 clz32(U32 val); -internal U64 clz64(U64 val); - -#endif // BASE_BITS_H diff --git a/src/base/base_types.c b/src/base/base_core.c similarity index 87% rename from src/base/base_types.c rename to src/base/base_core.c index f79bade6..24a6aaaa 100644 --- a/src/base/base_types.c +++ b/src/base/base_core.c @@ -2,7 +2,7 @@ // Licensed under the MIT license (https://opensource.org/license/mit/) //////////////////////////////// -//~ Safe Casts +//~ rjf: Safe Casts internal U16 safe_cast_u16(U32 x) @@ -141,6 +141,106 @@ bswap_u64(U64 x) return result; } +#if COMPILER_MSVC || (COMPILER_CLANG && OS_WINDOWS) + +internal U64 +count_bits_set16(U16 val) +{ + return __popcnt16(val); +} + +internal U64 +count_bits_set32(U32 val) +{ + return __popcnt(val); +} + +internal U64 +count_bits_set64(U64 val) +{ + return __popcnt64(val); +} + +internal U64 +ctz32(U32 mask) +{ + unsigned long idx; + _BitScanForward(&idx, mask); + return idx; +} + +internal U64 +ctz64(U64 mask) +{ + unsigned long idx; + _BitScanForward64(&idx, mask); + return idx; +} + +internal U64 +clz32(U32 mask) +{ + unsigned long idx; + _BitScanReverse(&idx, mask); + return 31 - idx; +} + +internal U64 +clz64(U64 mask) +{ + unsigned long idx; + _BitScanReverse64(&idx, mask); + return 63 - idx; +} + +#elif COMPILER_CLANG || COMPILER_GCC + +internal U64 +count_bits_set16(U16 val) +{ + NotImplemented; + return 0; +} + +internal U64 +count_bits_set32(U32 val) +{ + NotImplemented; + return 0; +} + +internal U64 +count_bits_set64(U64 val) +{ + NotImplemented; + return 0; +} + +internal U64 +ctz32(U32 val) +{ + NotImplemented; + return 0; +} + +internal U64 +clz32(U32 val) +{ + NotImplemented; + return 0; +} + +internal U64 +clz64(U64 val) +{ + NotImplemented; + return 0; +} + +#else +# error "Bit intrinsic functions not defined for this compiler." +#endif + //////////////////////////////// //~ rjf: Enum -> Sign diff --git a/src/base/base_types.h b/src/base/base_core.h similarity index 75% rename from src/base/base_types.h rename to src/base/base_core.h index 3eb1f78f..f0fddea2 100644 --- a/src/base/base_types.h +++ b/src/base/base_core.h @@ -34,6 +34,80 @@ # define read_only #endif +#if COMPILER_MSVC +# define thread_static __declspec(thread) +#elif COMPILER_CLANG || COMPILER_GCC +# define thread_static __thread +#endif + +//////////////////////////////// +//~ rjf: Linkage Keyword Macros + +#if OS_WINDOWS +# define shared_function C_LINKAGE __declspec(dllexport) +#else +# define shared_function C_LINKAGE +#endif + +#if LANG_CPP +# define C_LINKAGE_BEGIN extern "C"{ +# define C_LINKAGE_END } +# define C_LINKAGE extern "C" +#else +# define C_LINKAGE_BEGIN +# define C_LINKAGE_END +# define C_LINKAGE +#endif + +//////////////////////////////// +//~ rjf: Units + +#define KB(n) (((U64)(n)) << 10) +#define MB(n) (((U64)(n)) << 20) +#define GB(n) (((U64)(n)) << 30) +#define TB(n) (((U64)(n)) << 40) +#define Thousand(n) ((n)*1000) +#define Million(n) ((n)*1000000) +#define Billion(n) ((n)*1000000000) + +//////////////////////////////// +//~ rjf: Branch Predictor Hints + +#if defined(__clang__) +# define Expect(expr, val) __builtin_expect((expr), (val)) +#else +# define Expect(expr, val) (expr) +#endif + +#define Likely(expr) Expect(expr,1) +#define Unlikely(expr) Expect(expr,0) + +//////////////////////////////// +//~ rjf: Clamps, Mins, Maxes + +#define Min(A,B) (((A)<(B))?(A):(B)) +#define Max(A,B) (((A)>(B))?(A):(B)) +#define ClampTop(A,X) Min(A,X) +#define ClampBot(X,B) Max(X,B) +#define Clamp(A,X,B) (((X)<(A))?(A):((X)>(B))?(B):(X)) + +//////////////////////////////// +//~ rjf: Member Offsets + +#define Member(T,m) (((T*)0)->m) +#define OffsetOf(T,m) IntFromPtr(&Member(T,m)) +#define MemberFromOffset(T,ptr,off) (T)((((U8 *)ptr)+(off))) +#define CastFromMember(T,m,ptr) (T*)(((U8*)ptr) - OffsetOf(T,m)) + +//////////////////////////////// +//~ rjf: For-Loop Construct Macros + +#define DeferLoop(begin, end) for(int _i_ = ((begin), 0); !_i_; _i_ += 1, (end)) +#define DeferLoopChecked(begin, end) for(int _i_ = 2 * !(begin); (_i_ == 2 ? ((end), 0) : !_i_); _i_ += 1, (end)) + +#define EachEnumVal(type, it) type it = (type)0; it < type##_COUNT; it = (type)(it+1) +#define EachNonZeroEnumVal(type, it) type it = (type)1; it < type##_COUNT; it = (type)(it+1) + //////////////////////////////// //~ rjf: Memory Operation Macros @@ -56,19 +130,7 @@ #define MemoryMatchArray(a,b) MemoryMatch((a),(b),sizeof(a)) #define MemoryRead(T,p,e) ( ((p)+sizeof(T)<=(e))?(*(T*)(p)):(0) ) -#define MemoryConsume(T,p,e) \ -( ((p)+sizeof(T)<=(e))?((p)+=sizeof(T),*(T*)((p)-sizeof(T))):((p)=(e),0) ) - -//////////////////////////////// -//~ rjf: Units - -#define KB(n) (((U64)(n)) << 10) -#define MB(n) (((U64)(n)) << 20) -#define GB(n) (((U64)(n)) << 30) -#define TB(n) (((U64)(n)) << 40) -#define Thousand(n) ((n)*1000) -#define Million(n) ((n)*1000000) -#define Billion(n) ((n)*1000000000) +#define MemoryConsume(T,p,e) ( ((p)+sizeof(T)<=(e))?((p)+=sizeof(T),*(T*)((p)-sizeof(T))):((p)=(e),0) ) //////////////////////////////// //~ rjf: Asserts @@ -77,8 +139,8 @@ # define Trap() __debugbreak() #elif COMPILER_CLANG || COMPILER_GCC # define Trap() __builtin_trap() -# else -# error "undefined trap" +#else +# error Unknown trap intrinsic for this compiler. #endif #define AssertAlways(x) do{if(!(x)) {Trap();}}while(0) @@ -87,69 +149,158 @@ #else # define Assert(x) (void)(x) #endif -#define AssertImplies(a,b) Assert(!(a) || b) -#define AssertIff(a,b) Assert(!!(a) == !!(b)) #define InvalidPath Assert(!"Invalid Path!") #define NotImplemented Assert(!"Not Implemented!") #define NoOp ((void)0) - -#define StaticAssert(C,ID) global U8 Glue(ID,__LINE__)[(C)?1:-1] +#define StaticAssert(C, ID) global U8 Glue(ID, __LINE__)[(C)?1:-1] //////////////////////////////// -//~ rjf: Branch Predictor Hints +//~ rjf: Atomic Operations -#if defined(__clang__) -# define Expect(expr, val) __builtin_expect((expr), (val)) +#if OS_WINDOWS +# include +# include +# include +# include +# 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_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 -# define Expect(expr, val) (expr) +# error Atomic intrinsics not defined for this operating system. #endif -#define Likely(expr) Expect(expr,1) -#define Unlikely(expr) Expect(expr,0) +//////////////////////////////// +//~ rjf: Linked List Building Macros + +//- rjf: linked list macro helpers +#define CheckNil(nil,p) ((p) == 0 || (p) == nil) +#define SetNil(nil,p) ((p) = nil) + +//- rjf: doubly-linked-lists +#define DLLInsert_NPZ(nil,f,l,p,n,next,prev) (CheckNil(nil,f) ? \ +((f) = (l) = (n), SetNil(nil,(n)->next), SetNil(nil,(n)->prev)) :\ +CheckNil(nil,p) ? \ +((n)->next = (f), (f)->prev = (n), (f) = (n), SetNil(nil,(n)->prev)) :\ +((p)==(l)) ? \ +((l)->next = (n), (n)->prev = (l), (l) = (n), SetNil(nil, (n)->next)) :\ +(((!CheckNil(nil,p) && CheckNil(nil,(p)->next)) ? (0) : ((p)->next->prev = (n))), ((n)->next = (p)->next), ((p)->next = (n)), ((n)->prev = (p)))) +#define DLLPushBack_NPZ(nil,f,l,n,next,prev) DLLInsert_NPZ(nil,f,l,l,n,next,prev) +#define DLLPushFront_NPZ(nil,f,l,n,next,prev) DLLInsert_NPZ(nil,l,f,f,n,prev,next) +#define DLLRemove_NPZ(nil,f,l,n,next,prev) (((n) == (f) ? (f) = (n)->next : (0)),\ +((n) == (l) ? (l) = (l)->prev : (0)),\ +(CheckNil(nil,(n)->prev) ? (0) :\ +((n)->prev->next = (n)->next)),\ +(CheckNil(nil,(n)->next) ? (0) :\ +((n)->next->prev = (n)->prev))) + +//- rjf: singly-linked, doubly-headed lists (queues) +#define SLLQueuePush_NZ(nil,f,l,n,next) (CheckNil(nil,f)?\ +((f)=(l)=(n),SetNil(nil,(n)->next)):\ +((l)->next=(n),(l)=(n),SetNil(nil,(n)->next))) +#define SLLQueuePushFront_NZ(nil,f,l,n,next) (CheckNil(nil,f)?\ +((f)=(l)=(n),SetNil(nil,(n)->next)):\ +((n)->next=(f),(f)=(n))) +#define SLLQueuePop_NZ(nil,f,l,next) ((f)==(l)?\ +(SetNil(nil,f),SetNil(nil,l)):\ +((f)=(f)->next)) + +//- rjf: singly-linked, singly-headed lists (stacks) +#define SLLStackPush_N(f,n,next) ((n)->next=(f), (f)=(n)) +#define SLLStackPop_N(f,next) ((f)=(f)->next) + +//- rjf: doubly-linked-list helpers +#define DLLInsert_NP(f,l,p,n,next,prev) DLLInsert_NPZ(0,f,l,p,n,next,prev) +#define DLLPushBack_NP(f,l,n,next,prev) DLLPushBack_NPZ(0,f,l,n,next,prev) +#define DLLPushFront_NP(f,l,n,next,prev) DLLPushFront_NPZ(0,f,l,n,next,prev) +#define DLLRemove_NP(f,l,n,next,prev) DLLRemove_NPZ(0,f,l,n,next,prev) +#define DLLInsert(f,l,p,n) DLLInsert_NPZ(0,f,l,p,n,next,prev) +#define DLLPushBack(f,l,n) DLLPushBack_NPZ(0,f,l,n,next,prev) +#define DLLPushFront(f,l,n) DLLPushFront_NPZ(0,f,l,n,next,prev) +#define DLLRemove(f,l,n) DLLRemove_NPZ(0,f,l,n,next,prev) + +//- rjf: singly-linked, doubly-headed list helpers +#define SLLQueuePush_N(f,l,n,next) SLLQueuePush_NZ(0,f,l,n,next) +#define SLLQueuePushFront_N(f,l,n,next) SLLQueuePushFront_NZ(0,f,l,n,next) +#define SLLQueuePop_N(f,l,next) SLLQueuePop_NZ(0,f,l,next) +#define SLLQueuePush(f,l,n) SLLQueuePush_NZ(0,f,l,n,next) +#define SLLQueuePushFront(f,l,n) SLLQueuePushFront_NZ(0,f,l,n,next) +#define SLLQueuePop(f,l) SLLQueuePop_NZ(0,f,l,next) + +//- rjf: singly-linked, singly-headed list helpers +#define SLLStackPush(f,n) SLLStackPush_N(f,n,next) +#define SLLStackPop(f) SLLStackPop_N(f,next) + +//////////////////////////////// +//~ 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 +# error "NO_ASAN is not defined for this compiler." +#endif + +#if ASAN_ENABLED +#pragma comment(lib, "clang_rt.asan-x86_64.lib") +C_LINKAGE void __asan_poison_memory_region(void const volatile *addr, size_t size); +C_LINKAGE void __asan_unpoison_memory_region(void const volatile *addr, size_t size); +# define AsanPoisonMemoryRegion(addr, size) __asan_poison_memory_region((addr), (size)) +# define AsanUnpoisonMemoryRegion(addr, size) __asan_unpoison_memory_region((addr), (size)) +#else +# define AsanPoisonMemoryRegion(addr, size) ((void)(addr), (void)(size)) +# define AsanUnpoisonMemoryRegion(addr, size) ((void)(addr), (void)(size)) +#endif //////////////////////////////// //~ rjf: Misc. Helper Macros -#define ArrayCount(a) (sizeof(a) / sizeof((a)[0])) - -#define Stmnt(S) do{ S }while(0) - #define Stringify_(S) #S #define Stringify(S) Stringify_(S) #define Glue_(A,B) A##B #define Glue(A,B) Glue_(A,B) -#define Min(A,B) ( ((A)<(B))?(A):(B) ) -#define Max(A,B) ( ((A)>(B))?(A):(B) ) - -#define ClampTop(A,X) Min(A,X) -#define ClampBot(X,B) Max(X,B) -#define Clamp(A,X,B) ( ((X)<(A))?(A):((X)>(B))?(B):(X) ) - -#define PtrClampTop(A,X) ClampTop(A,X) -#define PtrClampBot(X,B) ClampBot(X,B) -#define PtrClamp(A,X,B) Clamp(A,X,B) +#define ArrayCount(a) (sizeof(a) / sizeof((a)[0])) #define CeilIntegerDiv(a,b) (((a) + (b) - 1)/(b)) -#define Swap(T,a,b) Stmnt( T t__ = a; a = b; b = t__; ) +#define Swap(T,a,b) do{T t__ = a; a = b; b = t__;}while(0) #if ARCH_64BIT # define IntFromPtr(ptr) ((U64)(ptr)) #elif ARCH_32BIT # define IntFromPtr(ptr) ((U32)(ptr)) #else -# error missing ptr cast for this architecture +# error Missing pointer-to-integer cast for this architecture. #endif - #define PtrFromInt(i) (void*)((U8*)0 + (i)) -#define Member(T,m) (((T*)0)->m) -#define OffsetOf(T,m) IntFromPtr(&Member(T,m)) -#define MemberFromOffset(T,ptr,off) (T)((((U8 *)ptr)+(off))) -#define CastFromMember(T,m,ptr) (T*)(((U8*)ptr) - OffsetOf(T,m)) - #define Compose64Bit(a,b) ((((U64)a) << 32) | ((U64)b)); #define AlignPow2(x,b) (((x) + (b) - 1)&(~((b) - 1))) #define AlignDownPow2(x,b) ((x)&(~((b) - 1))) @@ -157,11 +308,7 @@ #define IsPow2(x) ((x)!=0 && ((x)&((x)-1))==0) #define IsPow2OrZero(x) ((((x) - 1)&(x)) == 0) -#define DeferLoop(begin, end) for(int _i_ = ((begin), 0); !_i_; _i_ += 1, (end)) -#define DeferLoopChecked(begin, end) for(int _i_ = 2 * !(begin); (_i_ == 2 ? ((end), 0) : !_i_); _i_ += 1, (end)) - -#define EachEnumVal(type, it) type it = (type)0; it < type##_COUNT; it = (type)(it+1) -#define EachNonZeroEnumVal(type, it) type it = (type)1; it < type##_COUNT; it = (type)(it+1) +#define ExtractBit(word, idx) (((word) >> (idx)) & 1) #if LANG_CPP # define zero_struct {} @@ -175,66 +322,6 @@ # define this_function_name __func__ #endif -#if LANG_CPP -# define C_LINKAGE_BEGIN extern "C"{ -# define C_LINKAGE_END } -# define C_LINKAGE extern "C" -#else -# define C_LINKAGE_BEGIN -# define C_LINKAGE_END -# define C_LINKAGE -#endif - -#if COMPILER_MSVC -# define thread_static __declspec(thread) -#elif COMPILER_CLANG || COMPILER_GCC -# define thread_static __thread -#endif - -#if OS_WINDOWS -# define shared_function C_LINKAGE __declspec(dllexport) -#else -# define shared_function C_LINKAGE -#endif - -//////////////////////////////// -//~ 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 -# error "NO_ASAN is not defined" -#endif - -#if ASAN_ENABLED - -#pragma comment(lib, "clang_rt.asan-x86_64.lib") - -C_LINKAGE_BEGIN -void __asan_poison_memory_region(void const volatile *addr, size_t size); -void __asan_unpoison_memory_region(void const volatile *addr, size_t size); -C_LINKAGE_END - -# define AsanPoisonMemoryRegion(addr, size) __asan_poison_memory_region((addr), (size)) -# define AsanUnpoisonMemoryRegion(addr, size) __asan_unpoison_memory_region((addr), (size)) -#else -# define AsanPoisonMemoryRegion(addr, size) ((void)(addr), (void)(size)) -# define AsanUnpoisonMemoryRegion(addr, size) ((void)(addr), (void)(size)) - -#endif - //////////////////////////////// //~ rjf: Base Types @@ -252,10 +339,7 @@ typedef S32 B32; typedef S64 B64; typedef float F32; typedef double F64; - -//////////////////////////////// -//~ rjf: Large Base Types - +typedef void VoidProc(void); typedef struct U128 U128; struct U128 { @@ -265,8 +349,6 @@ struct U128 //////////////////////////////// //~ rjf: Basic Types & Spaces -typedef void VoidProc(void); - typedef enum Dimension { Dimension_X, @@ -562,11 +644,13 @@ struct DateTime U16 min; // [0,59] U16 hour; // [0,24] U16 day; // [0,30] - union{ + union + { WeekDay week_day; U32 wday; }; - union{ + union + { Month month; U32 mon; }; @@ -594,7 +678,7 @@ struct FileProperties }; //////////////////////////////// -//~ Safe Casts +//~ rjf: Safe Casts internal U16 safe_cast_u16(U32 x); internal U32 safe_cast_u32(U64 x); @@ -622,6 +706,15 @@ internal U16 bswap_u16(U16 x); internal U32 bswap_u32(U32 x); internal U64 bswap_u64(U64 x); +internal U64 count_bits_set16(U16 val); +internal U64 count_bits_set32(U32 val); +internal U64 count_bits_set64(U64 val); + +internal U64 ctz32(U32 val); +internal U64 ctz64(U64 val); +internal U64 clz32(U32 val); +internal U64 clz64(U64 val); + //////////////////////////////// //~ rjf: Enum -> Sign @@ -670,4 +763,4 @@ internal U64 ring_read(U8 *ring_base, U64 ring_size, U64 ring_pos, void *dst_dat #define ring_write_struct(ring_base, ring_size, ring_pos, ptr) ring_write((ring_base), (ring_size), (ring_pos), (ptr), sizeof(*(ptr))) #define ring_read_struct(ring_base, ring_size, ring_pos, ptr) ring_read((ring_base), (ring_size), (ring_pos), (ptr), sizeof(*(ptr))) -#endif // BASE_TYPES_H +#endif // BASE_CORE_H diff --git a/src/base/base_inc.c b/src/base/base_inc.c index 7c3e7cca..9e26e544 100644 --- a/src/base/base_inc.c +++ b/src/base/base_inc.c @@ -7,13 +7,11 @@ #undef RADDBG_LAYER_COLOR #define RADDBG_LAYER_COLOR 0.20f, 0.60f, 0.80f -#include "base_types.c" +#include "base_core.c" #include "base_profile.c" #include "base_arena.c" #include "base_math.c" -#include "base_string.c" +#include "base_strings.c" #include "base_thread_context.c" #include "base_command_line.c" -#include "base_arena_dev.c" -#include "base_bits.c" #include "base_markup.c" diff --git a/src/base/base_inc.h b/src/base/base_inc.h index f5ed9a5e..6ecfea56 100644 --- a/src/base/base_inc.h +++ b/src/base/base_inc.h @@ -8,17 +8,14 @@ //~ rjf: Base Includes #include "base_context_cracking.h" -#include "base_types.h" + +#include "base_core.h" #include "base_profile.h" -#include "base_ins.h" -#include "base_linked_lists.h" #include "base_arena.h" #include "base_math.h" -#include "base_string.h" +#include "base_strings.h" #include "base_thread_context.h" #include "base_command_line.h" -#include "base_arena_dev.h" -#include "base_bits.h" #include "base_markup.h" #endif // BASE_INC_H diff --git a/src/base/base_ins.h b/src/base/base_ins.h deleted file mode 100644 index 6908e7cd..00000000 --- a/src/base/base_ins.h +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright (c) 2024 Epic Games Tools -// Licensed under the MIT license (https://opensource.org/license/mit/) - -#ifndef BASE_INS_H -#define BASE_INS_H - -//////////////////////////////// -// NOTE(allen): Implementations of Intrinsics - -#if OS_WINDOWS - -# include -# include -# include -# include - -# 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_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)) -# endif - -#elif OS_LINUX - -# if ARCH_X64 -# define ins_atomic_u64_inc_eval(x) __sync_fetch_and_add((volatile U64 *)(x), 1) -# endif - -#else -// TODO(allen): -#endif - -//////////////////////////////// -// NOTE(allen): Intrinsic Checks - -#if ARCH_X64 - -# if !defined(ins_atomic_u64_inc_eval) -# error missing: ins_atomic_u64_inc_eval -# endif - -#else -# error the intrinsic set for this arch is not developed -#endif - - -#endif //BASE_INS_H diff --git a/src/base/base_linked_lists.h b/src/base/base_linked_lists.h deleted file mode 100644 index 436cedc5..00000000 --- a/src/base/base_linked_lists.h +++ /dev/null @@ -1,73 +0,0 @@ -// Copyright (c) 2024 Epic Games Tools -// Licensed under the MIT license (https://opensource.org/license/mit/) - -#ifndef BASE_LINKED_LIST_H -#define BASE_LINKED_LIST_H - -//////////////////////////////// -//~ rjf: Helpers - -#define CheckNil(nil,p) ((p) == 0 || (p) == nil) -#define SetNil(nil,p) ((p) = nil) - -//////////////////////////////// -//~ rjf: Base Macros - -//- rjf: Base Doubly-Linked-List Macros -#define DLLInsert_NPZ(nil,f,l,p,n,next,prev) (CheckNil(nil,f) ? \ -((f) = (l) = (n), SetNil(nil,(n)->next), SetNil(nil,(n)->prev)) :\ -CheckNil(nil,p) ? \ -((n)->next = (f), (f)->prev = (n), (f) = (n), SetNil(nil,(n)->prev)) :\ -((p)==(l)) ? \ -((l)->next = (n), (n)->prev = (l), (l) = (n), SetNil(nil, (n)->next)) :\ -(((!CheckNil(nil,p) && CheckNil(nil,(p)->next)) ? (0) : ((p)->next->prev = (n))), ((n)->next = (p)->next), ((p)->next = (n)), ((n)->prev = (p)))) -#define DLLPushBack_NPZ(nil,f,l,n,next,prev) DLLInsert_NPZ(nil,f,l,l,n,next,prev) -#define DLLPushFront_NPZ(nil,f,l,n,next,prev) DLLInsert_NPZ(nil,l,f,f,n,prev,next) -#define DLLRemove_NPZ(nil,f,l,n,next,prev) (((n) == (f) ? (f) = (n)->next : (0)),\ -((n) == (l) ? (l) = (l)->prev : (0)),\ -(CheckNil(nil,(n)->prev) ? (0) :\ -((n)->prev->next = (n)->next)),\ -(CheckNil(nil,(n)->next) ? (0) :\ -((n)->next->prev = (n)->prev))) - -//- rjf: Base Singly-Linked-List Queue Macros -#define SLLQueuePush_NZ(nil,f,l,n,next) (CheckNil(nil,f)?\ -((f)=(l)=(n),SetNil(nil,(n)->next)):\ -((l)->next=(n),(l)=(n),SetNil(nil,(n)->next))) -#define SLLQueuePushFront_NZ(nil,f,l,n,next) (CheckNil(nil,f)?\ -((f)=(l)=(n),SetNil(nil,(n)->next)):\ -((n)->next=(f),(f)=(n))) -#define SLLQueuePop_NZ(nil,f,l,next) ((f)==(l)?\ -(SetNil(nil,f),SetNil(nil,l)):\ -((f)=(f)->next)) - -//- rjf: Base Singly-Linked-List Stack Macros -#define SLLStackPush_N(f,n,next) ((n)->next=(f), (f)=(n)) -#define SLLStackPop_N(f,next) ((f)=(f)->next) - -//////////////////////////////// -//~ rjf: Convenience Wrappers - -//- rjf: Doubly-Linked-List Wrappers -#define DLLInsert_NP(f,l,p,n,next,prev) DLLInsert_NPZ(0,f,l,p,n,next,prev) -#define DLLPushBack_NP(f,l,n,next,prev) DLLPushBack_NPZ(0,f,l,n,next,prev) -#define DLLPushFront_NP(f,l,n,next,prev) DLLPushFront_NPZ(0,f,l,n,next,prev) -#define DLLRemove_NP(f,l,n,next,prev) DLLRemove_NPZ(0,f,l,n,next,prev) -#define DLLInsert(f,l,p,n) DLLInsert_NPZ(0,f,l,p,n,next,prev) -#define DLLPushBack(f,l,n) DLLPushBack_NPZ(0,f,l,n,next,prev) -#define DLLPushFront(f,l,n) DLLPushFront_NPZ(0,f,l,n,next,prev) -#define DLLRemove(f,l,n) DLLRemove_NPZ(0,f,l,n,next,prev) - -//- rjf: Singly-Linked-List Queue Wrappers -#define SLLQueuePush_N(f,l,n,next) SLLQueuePush_NZ(0,f,l,n,next) -#define SLLQueuePushFront_N(f,l,n,next) SLLQueuePushFront_NZ(0,f,l,n,next) -#define SLLQueuePop_N(f,l,next) SLLQueuePop_NZ(0,f,l,next) -#define SLLQueuePush(f,l,n) SLLQueuePush_NZ(0,f,l,n,next) -#define SLLQueuePushFront(f,l,n) SLLQueuePushFront_NZ(0,f,l,n,next) -#define SLLQueuePop(f,l) SLLQueuePop_NZ(0,f,l,next) - -//- rjf: Singly-Linked-List Stack Wrappers -#define SLLStackPush(f,n) SLLStackPush_N(f,n,next) -#define SLLStackPop(f) SLLStackPop_N(f,next) - -#endif //BASE_LINKED_LIST_H diff --git a/src/base/base_string.c b/src/base/base_strings.c similarity index 100% rename from src/base/base_string.c rename to src/base/base_strings.c diff --git a/src/base/base_string.h b/src/base/base_strings.h similarity index 99% rename from src/base/base_string.h rename to src/base/base_strings.h index 5090f1bb..cfce641e 100644 --- a/src/base/base_string.h +++ b/src/base/base_strings.h @@ -1,8 +1,8 @@ // Copyright (c) 2024 Epic Games Tools // Licensed under the MIT license (https://opensource.org/license/mit/) -#ifndef BASE_STRING_H -#define BASE_STRING_H +#ifndef BASE_STRINGS_H +#define BASE_STRINGS_H //////////////////////////////// //~ rjf: Third Party Includes @@ -368,4 +368,4 @@ internal U64 str8_deserial_read_block(String8 string, U64 off, U64 size, Stri #define str8_deserial_read_array(string, off, ptr, count) str8_deserial_read((string), (off), (ptr), sizeof(*(ptr))*(count), sizeof(*(ptr))) #define str8_deserial_read_struct(string, off, ptr) str8_deserial_read((string), (off), (ptr), sizeof(*(ptr)), sizeof(*(ptr))) -#endif // BASE_STRING_H +#endif // BASE_STRINGS_H diff --git a/src/raddbgi_from_dwarf/raddbgi_dwarf.c b/src/raddbgi_from_dwarf/raddbgi_dwarf.c index 06abc03c..a9f43b52 100644 --- a/src/raddbgi_from_dwarf/raddbgi_dwarf.c +++ b/src/raddbgi_from_dwarf/raddbgi_dwarf.c @@ -374,7 +374,7 @@ dwarf_names_from_data(Arena *arena, String8 data){ U8 *augmentation_string = ptr; { U8 *ptr_raw = ptr + augmentation_string_size; - ptr = PtrClampTop(ptr_raw, unit_opl); + ptr = ClampTop(ptr_raw, unit_opl); } // offset size @@ -555,7 +555,7 @@ dwarf_line_from_data(Arena *arena, String8 data){ // header opl U8 *header_opl_raw = ptr + header_length; - U8 *header_opl = PtrClampTop(header_opl_raw, unit_opl); + U8 *header_opl = ClampTop(header_opl_raw, unit_opl); // minimum_instruction_length minimum_instruction_length = MemoryConsume(U8, ptr, header_opl); @@ -662,7 +662,7 @@ dwarf_line_from_data(Arena *arena, String8 data){ // header opl U8 *header_opl_raw = ptr + header_length; - U8 *header_opl = PtrClampTop(header_opl_raw, unit_opl); + U8 *header_opl = ClampTop(header_opl_raw, unit_opl); // minimum_instruction_length minimum_instruction_length = MemoryConsume(U8, ptr, header_opl); diff --git a/src/scratch/ryan_scratch.c b/src/scratch/ryan_scratch.c index 7a1d7af8..46717f0a 100644 --- a/src/scratch/ryan_scratch.c +++ b/src/scratch/ryan_scratch.c @@ -5,8 +5,8 @@ #include "lib_raddbgi_format/raddbgi_format.c" #include "lib_raddbgi_format/raddbgi_format_parse.h" #include "lib_raddbgi_format/raddbgi_format_parse.c" -#include "lib_raddbgi_cons/raddbgi_cons.h" -#include "lib_raddbgi_cons/raddbgi_cons.c" +#include "lib_raddbgi_make/raddbgi_make.h" +#include "lib_raddbgi_make/raddbgi_make.c" int main(int argument_count, char **arguments) {