Clean up some of the base layer and port Seasight changes over
This commit is contained in:
+67
-38
@@ -1,21 +1,50 @@
|
||||
#define DN_BASE_CPP
|
||||
|
||||
#include "../dn_clangd.h"
|
||||
|
||||
// NOTE: [$INTR] Intrinsics ////////////////////////////////////////////////////////////////////////
|
||||
DN_CPUFeatureDecl g_dn_cpu_feature_decl[DN_CPUFeature_Count];
|
||||
#include "../dn_base_inc.h"
|
||||
|
||||
#if !defined(DN_PLATFORM_ARM64) && !defined(DN_PLATFORM_EMSCRIPTEN)
|
||||
#define DN_SUPPORTS_CPU_ID
|
||||
#endif
|
||||
|
||||
#if defined(DN_SUPPORTS_CPU_ID)
|
||||
#if defined(DN_COMPILER_GCC) || defined(DN_COMPILER_CLANG)
|
||||
#include <cpuid.h>
|
||||
#endif
|
||||
#endif // defined(DN_SUPPORTS_CPU_ID)
|
||||
#if defined(DN_SUPPORTS_CPU_ID) && (defined(DN_COMPILER_GCC) || defined(DN_COMPILER_CLANG))
|
||||
#include <cpuid.h>
|
||||
#endif
|
||||
|
||||
DN_API DN_CPUIDResult DN_CPU_ID(DN_CPUIDArgs args)
|
||||
static DN_CPUFeatureDecl g_dn_cpu_feature_decl[DN_CPUFeature_Count];
|
||||
|
||||
DN_API DN_U64 DN_AtomicSetValue64(DN_U64 volatile *target, DN_U64 value)
|
||||
{
|
||||
#if defined(DN_COMPILER_MSVC) || defined(DN_COMPILER_CLANG_CL)
|
||||
__int64 result;
|
||||
do {
|
||||
result = *target;
|
||||
} while (DN_AtomicCompareExchange64(target, value, result) != result);
|
||||
return DN_CAST(DN_U64) result;
|
||||
#elif defined(DN_COMPILER_GCC) || defined(DN_COMPILER_CLANG)
|
||||
DN_U64 result = __sync_lock_test_and_set(target, value);
|
||||
return result;
|
||||
#else
|
||||
#error Unsupported compiler
|
||||
#endif
|
||||
}
|
||||
|
||||
DN_API DN_U32 DN_AtomicSetValue32(DN_U32 volatile *target, DN_U32 value)
|
||||
{
|
||||
#if defined(DN_COMPILER_MSVC) || defined(DN_COMPILER_CLANG_CL)
|
||||
long result;
|
||||
do {
|
||||
result = *target;
|
||||
} while (DN_AtomicCompareExchange32(target, value, result) != result);
|
||||
return result;
|
||||
#elif defined(DN_COMPILER_GCC) || defined(DN_COMPILER_CLANG)
|
||||
long result = __sync_lock_test_and_set(target, value);
|
||||
return result;
|
||||
#else
|
||||
#error Unsupported compiler
|
||||
#endif
|
||||
}
|
||||
|
||||
DN_API DN_CPUIDResult DN_CPUID(DN_CPUIDArgs args)
|
||||
{
|
||||
DN_CPUIDResult result = {};
|
||||
#if defined(DN_SUPPORTS_CPU_ID)
|
||||
@@ -24,7 +53,7 @@ DN_API DN_CPUIDResult DN_CPU_ID(DN_CPUIDArgs args)
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_USize DN_CPU_HasFeatureArray(DN_CPUReport const *report, DN_CPUFeatureQuery *features, DN_USize features_size)
|
||||
DN_API DN_USize DN_CPUHasFeatureArray(DN_CPUReport const *report, DN_CPUFeatureQuery *features, DN_USize features_size)
|
||||
{
|
||||
DN_USize result = 0;
|
||||
DN_USize const BITS = sizeof(report->features[0]) * 8;
|
||||
@@ -40,23 +69,23 @@ DN_API DN_USize DN_CPU_HasFeatureArray(DN_CPUReport const *report, DN_CPUFeature
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API bool DN_CPU_HasFeature(DN_CPUReport const *report, DN_CPUFeature feature)
|
||||
DN_API bool DN_CPUHasFeature(DN_CPUReport const *report, DN_CPUFeature feature)
|
||||
{
|
||||
DN_CPUFeatureQuery query = {};
|
||||
query.feature = feature;
|
||||
bool result = DN_CPU_HasFeatureArray(report, &query, 1) == 1;
|
||||
bool result = DN_CPUHasFeatureArray(report, &query, 1) == 1;
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API bool DN_CPU_HasAllFeatures(DN_CPUReport const *report, DN_CPUFeature const *features, DN_USize features_size)
|
||||
DN_API bool DN_CPUHasAllFeatures(DN_CPUReport const *report, DN_CPUFeature const *features, DN_USize features_size)
|
||||
{
|
||||
bool result = true;
|
||||
for (DN_USize index = 0; result && index < features_size; index++)
|
||||
result &= DN_CPU_HasFeature(report, features[index]);
|
||||
result &= DN_CPUHasFeature(report, features[index]);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API void DN_CPU_SetFeature(DN_CPUReport *report, DN_CPUFeature feature)
|
||||
DN_API void DN_CPUSetFeature(DN_CPUReport *report, DN_CPUFeature feature)
|
||||
{
|
||||
DN_Assert(feature < DN_CPUFeature_Count);
|
||||
DN_USize const BITS = sizeof(report->features[0]) * 8;
|
||||
@@ -65,7 +94,7 @@ DN_API void DN_CPU_SetFeature(DN_CPUReport *report, DN_CPUFeature feature)
|
||||
report->features[chunk_index] |= (1ULL << chunk_bit);
|
||||
}
|
||||
|
||||
DN_API DN_CPUReport DN_CPU_Report()
|
||||
DN_API DN_CPUReport DN_CPUGetReport()
|
||||
{
|
||||
DN_CPUReport result = {};
|
||||
#if defined(DN_SUPPORTS_CPU_ID)
|
||||
@@ -80,12 +109,12 @@ DN_API DN_CPUReport DN_CPU_Report()
|
||||
|
||||
// NOTE: Query standard function (e.g. eax = 0x0) for function count + cpu vendor
|
||||
args = {};
|
||||
fn_0000_[0] = DN_CPU_ID(args);
|
||||
fn_0000_[0] = DN_CPUID(args);
|
||||
|
||||
// NOTE: Query extended function (e.g. eax = 0x8000'0000) for function count + cpu vendor
|
||||
args = {};
|
||||
args.eax = DN_CAST(int) EXTENDED_FUNC_BASE_EAX;
|
||||
fn_8000_[0] = DN_CPU_ID(args);
|
||||
fn_8000_[0] = DN_CPUID(args);
|
||||
}
|
||||
|
||||
// NOTE: Extract function count ////////////////////////////////////////////////////////////////
|
||||
@@ -104,13 +133,13 @@ DN_API DN_CPUReport DN_CPU_Report()
|
||||
for (int eax = 1; eax <= STANDARD_FUNC_MAX_EAX; eax++) {
|
||||
DN_CPUIDArgs args = {};
|
||||
args.eax = eax;
|
||||
fn_0000_[eax] = DN_CPU_ID(args);
|
||||
fn_0000_[eax] = DN_CPUID(args);
|
||||
}
|
||||
|
||||
for (int eax = EXTENDED_FUNC_BASE_EAX + 1, index = 1; eax <= EXTENDED_FUNC_MAX_EAX; eax++, index++) {
|
||||
DN_CPUIDArgs args = {};
|
||||
args.eax = eax;
|
||||
fn_8000_[index] = DN_CPU_ID(args);
|
||||
fn_8000_[index] = DN_CPUID(args);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -207,7 +236,7 @@ DN_API DN_CPUReport DN_CPU_Report()
|
||||
}
|
||||
|
||||
if (available)
|
||||
DN_CPU_SetFeature(&result, DN_CAST(DN_CPUFeature) ext_index);
|
||||
DN_CPUSetFeature(&result, DN_CAST(DN_CPUFeature) ext_index);
|
||||
}
|
||||
#endif // DN_SUPPORTS_CPU_ID
|
||||
return result;
|
||||
@@ -216,18 +245,18 @@ DN_API DN_CPUReport DN_CPU_Report()
|
||||
// NOTE: DN_TicketMutex ////////////////////////////////////////////////////////////////////////////
|
||||
DN_API void DN_TicketMutex_Begin(DN_TicketMutex *mutex)
|
||||
{
|
||||
unsigned int ticket = DN_Atomic_AddU32(&mutex->ticket, 1);
|
||||
unsigned int ticket = DN_AtomicAddU32(&mutex->ticket, 1);
|
||||
DN_TicketMutex_BeginTicket(mutex, ticket);
|
||||
}
|
||||
|
||||
DN_API void DN_TicketMutex_End(DN_TicketMutex *mutex)
|
||||
{
|
||||
DN_Atomic_AddU32(&mutex->serving, 1);
|
||||
DN_AtomicAddU32(&mutex->serving, 1);
|
||||
}
|
||||
|
||||
DN_API DN_UInt DN_TicketMutex_MakeTicket(DN_TicketMutex *mutex)
|
||||
{
|
||||
DN_UInt result = DN_Atomic_AddU32(&mutex->ticket, 1);
|
||||
DN_UInt result = DN_AtomicAddU32(&mutex->ticket, 1);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -257,60 +286,60 @@ DN_API bool DN_TicketMutex_CanLock(DN_TicketMutex const *mutex, DN_UInt ticket)
|
||||
#endif
|
||||
|
||||
// NOTE: DN_Bit ////////////////////////////////////////////////////////////////////////////////////
|
||||
DN_API void DN_Bit_UnsetInplace(DN_USize *flags, DN_USize bitfield)
|
||||
DN_API void DN_BitUnsetInplace(DN_USize *flags, DN_USize bitfield)
|
||||
{
|
||||
*flags = (*flags & ~bitfield);
|
||||
}
|
||||
|
||||
DN_API void DN_Bit_SetInplace(DN_USize *flags, DN_USize bitfield)
|
||||
DN_API void DN_BitSetInplace(DN_USize *flags, DN_USize bitfield)
|
||||
{
|
||||
*flags = (*flags | bitfield);
|
||||
}
|
||||
|
||||
DN_API bool DN_Bit_IsSet(DN_USize bits, DN_USize bits_to_set)
|
||||
DN_API bool DN_BitIsSet(DN_USize bits, DN_USize bits_to_set)
|
||||
{
|
||||
auto result = DN_CAST(bool)((bits & bits_to_set) == bits_to_set);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API bool DN_Bit_IsNotSet(DN_USize bits, DN_USize bits_to_check)
|
||||
DN_API bool DN_BitIsNotSet(DN_USize bits, DN_USize bits_to_check)
|
||||
{
|
||||
auto result = !DN_Bit_IsSet(bits, bits_to_check);
|
||||
auto result = !DN_BitIsSet(bits, bits_to_check);
|
||||
return result;
|
||||
}
|
||||
|
||||
// NOTE: DN_Safe ///////////////////////////////////////////////////////////////////////////////////
|
||||
DN_API DN_I64 DN_Safe_AddI64(int64_t a, int64_t b)
|
||||
DN_API DN_I64 DN_SafeAddI64(int64_t a, int64_t b)
|
||||
{
|
||||
DN_I64 result = DN_CheckF(a <= INT64_MAX - b, "a=%zd, b=%zd", a, b) ? (a + b) : INT64_MAX;
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_I64 DN_Safe_MulI64(int64_t a, int64_t b)
|
||||
DN_API DN_I64 DN_SafeMulI64(int64_t a, int64_t b)
|
||||
{
|
||||
DN_I64 result = DN_CheckF(a <= INT64_MAX / b, "a=%zd, b=%zd", a, b) ? (a * b) : INT64_MAX;
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_U64 DN_Safe_AddU64(DN_U64 a, DN_U64 b)
|
||||
DN_API DN_U64 DN_SafeAddU64(DN_U64 a, DN_U64 b)
|
||||
{
|
||||
DN_U64 result = DN_CheckF(a <= UINT64_MAX - b, "a=%zu, b=%zu", a, b) ? (a + b) : UINT64_MAX;
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_U64 DN_Safe_SubU64(DN_U64 a, DN_U64 b)
|
||||
DN_API DN_U64 DN_SafeSubU64(DN_U64 a, DN_U64 b)
|
||||
{
|
||||
DN_U64 result = DN_CheckF(a >= b, "a=%zu, b=%zu", a, b) ? (a - b) : 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_U64 DN_Safe_MulU64(DN_U64 a, DN_U64 b)
|
||||
DN_API DN_U64 DN_SafeMulU64(DN_U64 a, DN_U64 b)
|
||||
{
|
||||
DN_U64 result = DN_CheckF(a <= UINT64_MAX / b, "a=%zu, b=%zu", a, b) ? (a * b) : UINT64_MAX;
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_U32 DN_Safe_SubU32(DN_U32 a, DN_U32 b)
|
||||
DN_API DN_U32 DN_SafeSubU32(DN_U32 a, DN_U32 b)
|
||||
{
|
||||
DN_U32 result = DN_CheckF(a >= b, "a=%u, b=%u", a, b) ? (a - b) : 0;
|
||||
return result;
|
||||
@@ -699,7 +728,7 @@ static_assert(DN_IsPowerOfTwoAligned(DN_ASAN_POISON_GUARD_SIZE, DN_ASAN_POISON_A
|
||||
"ASAN poison guard size must be a power-of-two and aligned to ASAN's alignment"
|
||||
"requirement (8 bytes)");
|
||||
|
||||
DN_API void DN_ASAN_PoisonMemoryRegion(void const volatile *ptr, DN_USize size)
|
||||
DN_API void DN_ASanPoisonMemoryRegion(void const volatile *ptr, DN_USize size)
|
||||
{
|
||||
if (!ptr || !size)
|
||||
return;
|
||||
@@ -719,7 +748,7 @@ DN_API void DN_ASAN_PoisonMemoryRegion(void const volatile *ptr, DN_USize size)
|
||||
#endif
|
||||
}
|
||||
|
||||
DN_API void DN_ASAN_UnpoisonMemoryRegion(void const volatile *ptr, DN_USize size)
|
||||
DN_API void DN_ASanUnpoisonMemoryRegion(void const volatile *ptr, DN_USize size)
|
||||
{
|
||||
if (!ptr || !size)
|
||||
return;
|
||||
|
||||
+148
-279
@@ -1,6 +1,8 @@
|
||||
#if !defined(DN_BASE_H)
|
||||
#define DN_BASE_H
|
||||
|
||||
#include "../dn_base_inc.h"
|
||||
|
||||
// NOTE: Macros ////////////////////////////////////////////////////////////////////////////////////
|
||||
#define DN_Stringify(x) #x
|
||||
#define DN_TokenCombine2(x, y) x ## y
|
||||
@@ -149,7 +151,7 @@ struct DN_DeferHelper
|
||||
};
|
||||
|
||||
#define DN_UniqueName(prefix) DN_TokenCombine(prefix, __LINE__)
|
||||
#define DN_DEFER const auto DN_UniqueName(defer_lambda_) = DN_DeferHelper() + [&]()
|
||||
#define DN_DEFER const auto DN_UniqueName(defer_lambda_) = DN_DeferHelper() + [&]()
|
||||
#endif // defined(__cplusplus)
|
||||
|
||||
#define DN_DeferLoop(begin, end) \
|
||||
@@ -233,30 +235,25 @@ struct DN_CallSite
|
||||
DN_Str8 function;
|
||||
DN_U32 line;
|
||||
};
|
||||
|
||||
#define DN_CALL_SITE \
|
||||
DN_CallSite \
|
||||
{ \
|
||||
DN_STR8(__FILE__), DN_STR8(__func__), __LINE__ \
|
||||
}
|
||||
#define DN_CALL_SITE DN_CallSite { DN_STR8(__FILE__), DN_STR8(__func__), __LINE__ }
|
||||
|
||||
// NOTE: Intrinsics ////////////////////////////////////////////////////////////////////////////////
|
||||
// NOTE: DN_Atomic_Add/Exchange return the previous value store in the target
|
||||
// NOTE: DN_AtomicAdd/Exchange return the previous value store in the target
|
||||
#if defined(DN_COMPILER_MSVC) || defined(DN_COMPILER_CLANG_CL)
|
||||
#include <intrin.h>
|
||||
#define DN_Atomic_CompareExchange64(dest, desired_val, prev_val) _InterlockedCompareExchange64((__int64 volatile *)dest, desired_val, prev_val)
|
||||
#define DN_Atomic_CompareExchange32(dest, desired_val, prev_val) _InterlockedCompareExchange((long volatile *)dest, desired_val, prev_val)
|
||||
#define DN_AtomicCompareExchange64(dest, desired_val, prev_val) _InterlockedCompareExchange64((__int64 volatile *)dest, desired_val, prev_val)
|
||||
#define DN_AtomicCompareExchange32(dest, desired_val, prev_val) _InterlockedCompareExchange((long volatile *)dest, desired_val, prev_val)
|
||||
|
||||
#define DN_Atomic_LoadU64(target) *(target)
|
||||
#define DN_Atomic_LoadU32(target) *(target)
|
||||
#define DN_Atomic_AddU32(target, value) _InterlockedExchangeAdd((long volatile *)target, value)
|
||||
#define DN_Atomic_AddU64(target, value) _InterlockedExchangeAdd64((__int64 volatile *)target, value)
|
||||
#define DN_Atomic_SubU32(target, value) DN_Atomic_AddU32(DN_CAST(long volatile *) target, (long)-value)
|
||||
#define DN_Atomic_SubU64(target, value) DN_Atomic_AddU64(target, (DN_U64) - value)
|
||||
#define DN_AtomicLoadU64(target) *(target)
|
||||
#define DN_AtomicLoadU32(target) *(target)
|
||||
#define DN_AtomicAddU32(target, value) _InterlockedExchangeAdd((long volatile *)target, value)
|
||||
#define DN_AtomicAddU64(target, value) _InterlockedExchangeAdd64((__int64 volatile *)target, value)
|
||||
#define DN_AtomicSubU32(target, value) DN_AtomicAddU32(DN_CAST(long volatile *) target, (long)-value)
|
||||
#define DN_AtomicSubU64(target, value) DN_AtomicAddU64(target, (DN_U64) - value)
|
||||
|
||||
#define DN_CountLeadingZerosU64(value) __lzcnt64(value)
|
||||
#define DN_CountLeadingZerosU32(value) __lzcnt(value)
|
||||
#define DN_CPU_TSC() __rdtsc()
|
||||
#define DN_CPUGetTSC() __rdtsc()
|
||||
#define DN_CompilerReadBarrierAndCPUReadFence _ReadBarrier(); _mm_lfence()
|
||||
#define DN_CompilerWriteBarrierAndCPUWriteFence _WriteBarrier(); _mm_sfence()
|
||||
#elif defined(DN_COMPILER_GCC) || defined(DN_COMPILER_CLANG)
|
||||
@@ -270,20 +267,20 @@ struct DN_CallSite
|
||||
#include <x86intrin.h>
|
||||
#endif
|
||||
|
||||
#define DN_Atomic_LoadU64(target) __atomic_load_n(x, __ATOMIC_SEQ_CST)
|
||||
#define DN_Atomic_LoadU32(target) __atomic_load_n(x, __ATOMIC_SEQ_CST)
|
||||
#define DN_Atomic_AddU32(target, value) __atomic_fetch_add(target, value, __ATOMIC_ACQ_REL)
|
||||
#define DN_Atomic_AddU64(target, value) __atomic_fetch_add(target, value, __ATOMIC_ACQ_REL)
|
||||
#define DN_Atomic_SubU32(target, value) __atomic_fetch_sub(target, value, __ATOMIC_ACQ_REL)
|
||||
#define DN_Atomic_SubU64(target, value) __atomic_fetch_sub(target, value, __ATOMIC_ACQ_REL)
|
||||
#define DN_AtomicLoadU64(target) __atomic_load_n(x, __ATOMIC_SEQ_CST)
|
||||
#define DN_AtomicLoadU32(target) __atomic_load_n(x, __ATOMIC_SEQ_CST)
|
||||
#define DN_AtomicAddU32(target, value) __atomic_fetch_add(target, value, __ATOMIC_ACQ_REL)
|
||||
#define DN_AtomicAddU64(target, value) __atomic_fetch_add(target, value, __ATOMIC_ACQ_REL)
|
||||
#define DN_AtomicSubU32(target, value) __atomic_fetch_sub(target, value, __ATOMIC_ACQ_REL)
|
||||
#define DN_AtomicSubU64(target, value) __atomic_fetch_sub(target, value, __ATOMIC_ACQ_REL)
|
||||
|
||||
#define DN_CountLeadingZerosU64(value) __builtin_clzll(value)
|
||||
#define DN_CountLeadingZerosU32(value) __builtin_clzl(value)
|
||||
|
||||
#if defined(DN_COMPILER_GCC)
|
||||
#define DN_CPU_TSC() __rdtsc()
|
||||
#define DN_CPUTSC() __rdtsc()
|
||||
#else
|
||||
#define DN_CPU_TSC() __builtin_readcyclecounter()
|
||||
#define DN_CPUTSC() __builtin_readcyclecounter()
|
||||
#endif
|
||||
|
||||
#if defined(DN_PLATFORM_EMSCRIPTEN)
|
||||
@@ -303,7 +300,6 @@ struct DN_CallSite
|
||||
#define DN_CountLeadingZerosUSize(value) DN_CountLeadingZerosU32(value)
|
||||
#endif
|
||||
|
||||
#if !defined(DN_PLATFORM_ARM64)
|
||||
struct DN_CPURegisters
|
||||
{
|
||||
int eax;
|
||||
@@ -318,67 +314,63 @@ union DN_CPUIDResult
|
||||
int values[4];
|
||||
};
|
||||
|
||||
struct DN_CPUIDArgs
|
||||
{
|
||||
int eax;
|
||||
int ecx;
|
||||
};
|
||||
struct DN_CPUIDArgs { int eax; int ecx; };
|
||||
|
||||
#define DN_CPU_FEAT_XMACRO \
|
||||
DN_CPU_FEAT_XENTRY(3DNow) \
|
||||
DN_CPU_FEAT_XENTRY(3DNowExt) \
|
||||
DN_CPU_FEAT_XENTRY(ABM) \
|
||||
DN_CPU_FEAT_XENTRY(AES) \
|
||||
DN_CPU_FEAT_XENTRY(AVX) \
|
||||
DN_CPU_FEAT_XENTRY(AVX2) \
|
||||
DN_CPU_FEAT_XENTRY(AVX512F) \
|
||||
DN_CPU_FEAT_XENTRY(AVX512DQ) \
|
||||
DN_CPU_FEAT_XENTRY(AVX512IFMA) \
|
||||
DN_CPU_FEAT_XENTRY(AVX512PF) \
|
||||
DN_CPU_FEAT_XENTRY(AVX512ER) \
|
||||
DN_CPU_FEAT_XENTRY(AVX512CD) \
|
||||
DN_CPU_FEAT_XENTRY(AVX512BW) \
|
||||
DN_CPU_FEAT_XENTRY(AVX512VL) \
|
||||
DN_CPU_FEAT_XENTRY(AVX512VBMI) \
|
||||
DN_CPU_FEAT_XENTRY(AVX512VBMI2) \
|
||||
DN_CPU_FEAT_XENTRY(AVX512VNNI) \
|
||||
DN_CPU_FEAT_XENTRY(AVX512BITALG) \
|
||||
DN_CPU_FEAT_XENTRY(AVX512VPOPCNTDQ) \
|
||||
DN_CPU_FEAT_XENTRY(AVX5124VNNIW) \
|
||||
DN_CPU_FEAT_XENTRY(AVX5124FMAPS) \
|
||||
DN_CPU_FEAT_XENTRY(AVX512VP2INTERSECT) \
|
||||
DN_CPU_FEAT_XENTRY(AVX512FP16) \
|
||||
DN_CPU_FEAT_XENTRY(CLZERO) \
|
||||
DN_CPU_FEAT_XENTRY(CMPXCHG8B) \
|
||||
DN_CPU_FEAT_XENTRY(CMPXCHG16B) \
|
||||
DN_CPU_FEAT_XENTRY(F16C) \
|
||||
DN_CPU_FEAT_XENTRY(FMA) \
|
||||
DN_CPU_FEAT_XENTRY(FMA4) \
|
||||
DN_CPU_FEAT_XENTRY(FP128) \
|
||||
DN_CPU_FEAT_XENTRY(FP256) \
|
||||
DN_CPU_FEAT_XENTRY(FPU) \
|
||||
DN_CPU_FEAT_XENTRY(MMX) \
|
||||
DN_CPU_FEAT_XENTRY(MONITOR) \
|
||||
DN_CPU_FEAT_XENTRY(MOVBE) \
|
||||
DN_CPU_FEAT_XENTRY(MOVU) \
|
||||
DN_CPU_FEAT_XENTRY(MmxExt) \
|
||||
DN_CPU_FEAT_XENTRY(PCLMULQDQ) \
|
||||
DN_CPU_FEAT_XENTRY(POPCNT) \
|
||||
DN_CPU_FEAT_XENTRY(RDRAND) \
|
||||
DN_CPU_FEAT_XENTRY(RDSEED) \
|
||||
DN_CPU_FEAT_XENTRY(RDTSCP) \
|
||||
DN_CPU_FEAT_XENTRY(SHA) \
|
||||
DN_CPU_FEAT_XENTRY(SSE) \
|
||||
DN_CPU_FEAT_XENTRY(SSE2) \
|
||||
DN_CPU_FEAT_XENTRY(SSE3) \
|
||||
DN_CPU_FEAT_XENTRY(SSE41) \
|
||||
DN_CPU_FEAT_XENTRY(SSE42) \
|
||||
DN_CPU_FEAT_XENTRY(SSE4A) \
|
||||
DN_CPU_FEAT_XENTRY(SSSE3) \
|
||||
DN_CPU_FEAT_XENTRY(TSC) \
|
||||
DN_CPU_FEAT_XENTRY(TscInvariant) \
|
||||
DN_CPU_FEAT_XENTRY(VAES) \
|
||||
DN_CPU_FEAT_XENTRY(VPCMULQDQ)
|
||||
#define DN_CPU_FEAT_XMACRO \
|
||||
DN_CPU_FEAT_XENTRY(3DNow) \
|
||||
DN_CPU_FEAT_XENTRY(3DNowExt) \
|
||||
DN_CPU_FEAT_XENTRY(ABM) \
|
||||
DN_CPU_FEAT_XENTRY(AES) \
|
||||
DN_CPU_FEAT_XENTRY(AVX) \
|
||||
DN_CPU_FEAT_XENTRY(AVX2) \
|
||||
DN_CPU_FEAT_XENTRY(AVX512F) \
|
||||
DN_CPU_FEAT_XENTRY(AVX512DQ) \
|
||||
DN_CPU_FEAT_XENTRY(AVX512IFMA) \
|
||||
DN_CPU_FEAT_XENTRY(AVX512PF) \
|
||||
DN_CPU_FEAT_XENTRY(AVX512ER) \
|
||||
DN_CPU_FEAT_XENTRY(AVX512CD) \
|
||||
DN_CPU_FEAT_XENTRY(AVX512BW) \
|
||||
DN_CPU_FEAT_XENTRY(AVX512VL) \
|
||||
DN_CPU_FEAT_XENTRY(AVX512VBMI) \
|
||||
DN_CPU_FEAT_XENTRY(AVX512VBMI2) \
|
||||
DN_CPU_FEAT_XENTRY(AVX512VNNI) \
|
||||
DN_CPU_FEAT_XENTRY(AVX512BITALG) \
|
||||
DN_CPU_FEAT_XENTRY(AVX512VPOPCNTDQ) \
|
||||
DN_CPU_FEAT_XENTRY(AVX5124VNNIW) \
|
||||
DN_CPU_FEAT_XENTRY(AVX5124FMAPS) \
|
||||
DN_CPU_FEAT_XENTRY(AVX512VP2INTERSECT) \
|
||||
DN_CPU_FEAT_XENTRY(AVX512FP16) \
|
||||
DN_CPU_FEAT_XENTRY(CLZERO) \
|
||||
DN_CPU_FEAT_XENTRY(CMPXCHG8B) \
|
||||
DN_CPU_FEAT_XENTRY(CMPXCHG16B) \
|
||||
DN_CPU_FEAT_XENTRY(F16C) \
|
||||
DN_CPU_FEAT_XENTRY(FMA) \
|
||||
DN_CPU_FEAT_XENTRY(FMA4) \
|
||||
DN_CPU_FEAT_XENTRY(FP128) \
|
||||
DN_CPU_FEAT_XENTRY(FP256) \
|
||||
DN_CPU_FEAT_XENTRY(FPU) \
|
||||
DN_CPU_FEAT_XENTRY(MMX) \
|
||||
DN_CPU_FEAT_XENTRY(MONITOR) \
|
||||
DN_CPU_FEAT_XENTRY(MOVBE) \
|
||||
DN_CPU_FEAT_XENTRY(MOVU) \
|
||||
DN_CPU_FEAT_XENTRY(MmxExt) \
|
||||
DN_CPU_FEAT_XENTRY(PCLMULQDQ) \
|
||||
DN_CPU_FEAT_XENTRY(POPCNT) \
|
||||
DN_CPU_FEAT_XENTRY(RDRAND) \
|
||||
DN_CPU_FEAT_XENTRY(RDSEED) \
|
||||
DN_CPU_FEAT_XENTRY(RDTSCP) \
|
||||
DN_CPU_FEAT_XENTRY(SHA) \
|
||||
DN_CPU_FEAT_XENTRY(SSE) \
|
||||
DN_CPU_FEAT_XENTRY(SSE2) \
|
||||
DN_CPU_FEAT_XENTRY(SSE3) \
|
||||
DN_CPU_FEAT_XENTRY(SSE41) \
|
||||
DN_CPU_FEAT_XENTRY(SSE42) \
|
||||
DN_CPU_FEAT_XENTRY(SSE4A) \
|
||||
DN_CPU_FEAT_XENTRY(SSSE3) \
|
||||
DN_CPU_FEAT_XENTRY(TSC) \
|
||||
DN_CPU_FEAT_XENTRY(TscInvariant) \
|
||||
DN_CPU_FEAT_XENTRY(VAES) \
|
||||
DN_CPU_FEAT_XENTRY(VPCMULQDQ)
|
||||
|
||||
enum DN_CPUFeature
|
||||
{
|
||||
@@ -407,218 +399,95 @@ struct DN_CPUReport
|
||||
DN_U64 features[(DN_CPUFeature_Count / (sizeof(DN_U64) * 8)) + 1];
|
||||
};
|
||||
|
||||
extern DN_CPUFeatureDecl g_dn_cpu_feature_decl[DN_CPUFeature_Count];
|
||||
#endif // DN_PLATFORM_ARM64
|
||||
|
||||
// NOTE: DN_TicketMutex ////////////////////////////////////////////////////////////////////////////
|
||||
struct DN_TicketMutex
|
||||
{
|
||||
unsigned int volatile ticket; // The next ticket to give out to the thread taking the mutex
|
||||
unsigned int volatile serving; // The ticket ID to block the mutex on until it is returned
|
||||
};
|
||||
|
||||
// NOTE: Intrinsics ////////////////////////////////////////////////////////////////////////////////
|
||||
DN_FORCE_INLINE DN_U64 DN_Atomic_SetValue64 (DN_U64 volatile *target, DN_U64 value);
|
||||
DN_FORCE_INLINE DN_U32 DN_Atomic_SetValue32 (DN_U32 volatile *target, DN_U32 value);
|
||||
DN_API DN_U64 DN_AtomicSetValue64 (DN_U64 volatile *target, DN_U64 value);
|
||||
DN_API DN_U32 DN_AtomicSetValue32 (DN_U32 volatile *target, DN_U32 value);
|
||||
|
||||
#if !defined (DN_PLATFORM_ARM64)
|
||||
DN_API DN_CPUIDResult DN_CPU_ID (DN_CPUIDArgs args);
|
||||
DN_API DN_USize DN_CPU_HasFeatureArray (DN_CPUReport const *report, DN_CPUFeatureQuery *features, DN_USize features_size);
|
||||
DN_API bool DN_CPU_HasFeature (DN_CPUReport const *report, DN_CPUFeature feature);
|
||||
DN_API bool DN_CPU_HasAllFeatures (DN_CPUReport const *report, DN_CPUFeature const *features, DN_USize features_size);
|
||||
template <DN_USize N>
|
||||
bool DN_CPU_HasAllFeaturesCArray(DN_CPUReport const *report, DN_CPUFeature const (&features)[N]);
|
||||
DN_API void DN_CPU_SetFeature (DN_CPUReport *report, DN_CPUFeature feature);
|
||||
DN_API DN_CPUReport DN_CPU_Report ();
|
||||
#endif
|
||||
DN_API DN_CPUIDResult DN_CPUID (DN_CPUIDArgs args);
|
||||
DN_API DN_USize DN_CPUHasFeatureArray (DN_CPUReport const *report, DN_CPUFeatureQuery *features, DN_USize features_size);
|
||||
DN_API bool DN_CPUHasFeature (DN_CPUReport const *report, DN_CPUFeature feature);
|
||||
DN_API bool DN_CPUHasAllFeatures (DN_CPUReport const *report, DN_CPUFeature const *features, DN_USize features_size);
|
||||
DN_API void DN_CPUSetFeature (DN_CPUReport *report, DN_CPUFeature feature);
|
||||
DN_API DN_CPUReport DN_CPUGetReport ();
|
||||
|
||||
// NOTE: DN_TicketMutex ////////////////////////////////////////////////////////////////////////////
|
||||
DN_API void DN_TicketMutex_Begin (DN_TicketMutex *mutex);
|
||||
DN_API void DN_TicketMutex_End (DN_TicketMutex *mutex);
|
||||
DN_API DN_UInt DN_TicketMutex_MakeTicket (DN_TicketMutex *mutex);
|
||||
DN_API void DN_TicketMutex_BeginTicket(DN_TicketMutex const *mutex, DN_UInt ticket);
|
||||
DN_API bool DN_TicketMutex_CanLock (DN_TicketMutex const *mutex, DN_UInt ticket);
|
||||
DN_API void DN_TicketMutex_Begin (DN_TicketMutex *mutex);
|
||||
DN_API void DN_TicketMutex_End (DN_TicketMutex *mutex);
|
||||
DN_API DN_UInt DN_TicketMutex_MakeTicket (DN_TicketMutex *mutex);
|
||||
DN_API void DN_TicketMutex_BeginTicket (DN_TicketMutex const *mutex, DN_UInt ticket);
|
||||
DN_API bool DN_TicketMutex_CanLock (DN_TicketMutex const *mutex, DN_UInt ticket);
|
||||
|
||||
// NOTE: DN_DLList /////////////////////////////////////////////////////////////////////////////////
|
||||
#define DN_DLList_Init(list) \
|
||||
(list)->next = (list)->prev = (list)
|
||||
DN_API void DN_BitUnsetInplace (DN_USize *flags, DN_USize bitfield);
|
||||
DN_API void DN_BitSetInplace (DN_USize *flags, DN_USize bitfield);
|
||||
DN_API bool DN_BitIsSet (DN_USize bits, DN_USize bits_to_set);
|
||||
DN_API bool DN_BitIsNotSet (DN_USize bits, DN_USize bits_to_check);
|
||||
#define DN_BitClearNextLSB(value) (value) & ((value) - 1)
|
||||
|
||||
#define DN_DLList_IsSentinel(list, item) ((list) == (item))
|
||||
DN_API DN_I64 DN_SafeAddI64 (DN_I64 a, DN_I64 b);
|
||||
DN_API DN_I64 DN_SafeMulI64 (DN_I64 a, DN_I64 b);
|
||||
|
||||
#define DN_DLList_InitArena(list, T, arena) \
|
||||
do { \
|
||||
(list) = DN_Arena_New(arena, T, DN_ZeroMem_Yes); \
|
||||
DN_DLList_Init(list); \
|
||||
} while (0)
|
||||
DN_API DN_U64 DN_SafeAddU64 (DN_U64 a, DN_U64 b);
|
||||
DN_API DN_U64 DN_SafeMulU64 (DN_U64 a, DN_U64 b);
|
||||
|
||||
#define DN_DLList_InitPool(list, T, pool) \
|
||||
do { \
|
||||
(list) = DN_Pool_New(pool, T); \
|
||||
DN_DLList_Init(list); \
|
||||
} while (0)
|
||||
DN_API DN_U64 DN_SafeSubU64 (DN_U64 a, DN_U64 b);
|
||||
DN_API DN_U32 DN_SafeSubU32 (DN_U32 a, DN_U32 b);
|
||||
|
||||
#define DN_DLList_Detach(item) \
|
||||
do { \
|
||||
if (item) { \
|
||||
(item)->prev->next = (item)->next; \
|
||||
(item)->next->prev = (item)->prev; \
|
||||
(item)->next = nullptr; \
|
||||
(item)->prev = nullptr; \
|
||||
} \
|
||||
} while (0)
|
||||
DN_API int DN_SaturateCastUSizeToInt (DN_USize val);
|
||||
DN_API DN_I8 DN_SaturateCastUSizeToI8 (DN_USize val);
|
||||
DN_API DN_I16 DN_SaturateCastUSizeToI16 (DN_USize val);
|
||||
DN_API DN_I32 DN_SaturateCastUSizeToI32 (DN_USize val);
|
||||
DN_API DN_I64 DN_SaturateCastUSizeToI64 (DN_USize val);
|
||||
|
||||
#define DN_DLList_Dequeue(list, dest_ptr) \
|
||||
if (DN_DLList_HasItems(list)) { \
|
||||
dest_ptr = (list)->next; \
|
||||
DN_DLList_Detach(dest_ptr); \
|
||||
}
|
||||
DN_API int DN_SaturateCastU64ToInt (DN_U64 val);
|
||||
DN_API DN_I8 DN_SaturateCastU8ToI8 (DN_U64 val);
|
||||
DN_API DN_I16 DN_SaturateCastU16ToI16 (DN_U64 val);
|
||||
DN_API DN_I32 DN_SaturateCastU32ToI32 (DN_U64 val);
|
||||
DN_API DN_I64 DN_SaturateCastU64ToI64 (DN_U64 val);
|
||||
DN_API DN_UInt DN_SaturateCastU64ToUInt (DN_U64 val);
|
||||
DN_API DN_U8 DN_SaturateCastU64ToU8 (DN_U64 val);
|
||||
DN_API DN_U16 DN_SaturateCastU64ToU16 (DN_U64 val);
|
||||
DN_API DN_U32 DN_SaturateCastU64ToU32 (DN_U64 val);
|
||||
|
||||
#define DN_DLList_Append(list, item) \
|
||||
do { \
|
||||
if (item) { \
|
||||
if ((item)->next) \
|
||||
DN_DLList_Detach(item); \
|
||||
(item)->next = (list)->next; \
|
||||
(item)->prev = (list); \
|
||||
(item)->next->prev = (item); \
|
||||
(item)->prev->next = (item); \
|
||||
} \
|
||||
} while (0)
|
||||
DN_API DN_U8 DN_SaturateCastUSizeToU8 (DN_USize val);
|
||||
DN_API DN_U16 DN_SaturateCastUSizeToU16 (DN_USize val);
|
||||
DN_API DN_U32 DN_SaturateCastUSizeToU32 (DN_USize val);
|
||||
DN_API DN_U64 DN_SaturateCastUSizeToU64 (DN_USize val);
|
||||
|
||||
#define DN_DLList_Prepend(list, item) \
|
||||
do { \
|
||||
if (item) { \
|
||||
if ((item)->next) \
|
||||
DN_DLList_Detach(item); \
|
||||
(item)->next = (list); \
|
||||
(item)->prev = (list)->prev; \
|
||||
(item)->next->prev = (item); \
|
||||
(item)->prev->next = (item); \
|
||||
} \
|
||||
} while (0)
|
||||
DN_API int DN_SaturateCastISizeToInt (DN_ISize val);
|
||||
DN_API DN_I8 DN_SaturateCastISizeToI8 (DN_ISize val);
|
||||
DN_API DN_I16 DN_SaturateCastISizeToI16 (DN_ISize val);
|
||||
DN_API DN_I32 DN_SaturateCastISizeToI32 (DN_ISize val);
|
||||
DN_API DN_I64 DN_SaturateCastISizeToI64 (DN_ISize val);
|
||||
|
||||
#define DN_DLList_IsEmpty(list) \
|
||||
(!(list) || ((list) == (list)->next))
|
||||
DN_API DN_UInt DN_SaturateCastISizeToUInt (DN_ISize val);
|
||||
DN_API DN_U8 DN_SaturateCastISizeToU8 (DN_ISize val);
|
||||
DN_API DN_U16 DN_SaturateCastISizeToU16 (DN_ISize val);
|
||||
DN_API DN_U32 DN_SaturateCastISizeToU32 (DN_ISize val);
|
||||
DN_API DN_U64 DN_SaturateCastISizeToU64 (DN_ISize val);
|
||||
|
||||
#define DN_DLList_IsInit(list) \
|
||||
((list)->next && (list)->prev)
|
||||
DN_API DN_ISize DN_SaturateCastI64ToISize (DN_I64 val);
|
||||
DN_API DN_I8 DN_SaturateCastI64ToI8 (DN_I64 val);
|
||||
DN_API DN_I16 DN_SaturateCastI64ToI16 (DN_I64 val);
|
||||
DN_API DN_I32 DN_SaturateCastI64ToI32 (DN_I64 val);
|
||||
|
||||
#define DN_DLList_HasItems(list) \
|
||||
((list) && ((list) != (list)->next))
|
||||
DN_API DN_UInt DN_SaturateCastI64ToUInt (DN_I64 val);
|
||||
DN_API DN_ISize DN_SaturateCastI64ToUSize (DN_I64 val);
|
||||
DN_API DN_U8 DN_SaturateCastI64ToU8 (DN_I64 val);
|
||||
DN_API DN_U16 DN_SaturateCastI64ToU16 (DN_I64 val);
|
||||
DN_API DN_U32 DN_SaturateCastI64ToU32 (DN_I64 val);
|
||||
DN_API DN_U64 DN_SaturateCastI64ToU64 (DN_I64 val);
|
||||
|
||||
#define DN_DLList_ForEach(it, list) \
|
||||
auto *it = (list)->next; (it) != (list); (it) = (it)->next
|
||||
DN_API DN_I8 DN_SaturateCastIntToI8 (int val);
|
||||
DN_API DN_I16 DN_SaturateCastIntToI16 (int val);
|
||||
DN_API DN_U8 DN_SaturateCastIntToU8 (int val);
|
||||
DN_API DN_U16 DN_SaturateCastIntToU16 (int val);
|
||||
DN_API DN_U32 DN_SaturateCastIntToU32 (int val);
|
||||
DN_API DN_U64 DN_SaturateCastIntToU64 (int val);
|
||||
|
||||
// NOTE: Intrinsics ////////////////////////////////////////////////////////////////////////////////
|
||||
DN_FORCE_INLINE DN_U64 DN_Atomic_SetValue64(DN_U64 volatile *target, DN_U64 value)
|
||||
{
|
||||
#if defined(DN_COMPILER_MSVC) || defined(DN_COMPILER_CLANG_CL)
|
||||
__int64 result;
|
||||
do {
|
||||
result = *target;
|
||||
} while (DN_Atomic_CompareExchange64(target, value, result) != result);
|
||||
return DN_CAST(DN_U64) result;
|
||||
#elif defined(DN_COMPILER_GCC) || defined(DN_COMPILER_CLANG)
|
||||
DN_U64 result = __sync_lock_test_and_set(target, value);
|
||||
return result;
|
||||
#else
|
||||
#error Unsupported compiler
|
||||
#endif
|
||||
}
|
||||
|
||||
DN_FORCE_INLINE DN_U32 DN_Atomic_SetValue32(DN_U32 volatile *target, DN_U32 value)
|
||||
{
|
||||
#if defined(DN_COMPILER_MSVC) || defined(DN_COMPILER_CLANG_CL)
|
||||
long result;
|
||||
do {
|
||||
result = *target;
|
||||
} while (DN_Atomic_CompareExchange32(target, value, result) != result);
|
||||
return result;
|
||||
#elif defined(DN_COMPILER_GCC) || defined(DN_COMPILER_CLANG)
|
||||
long result = __sync_lock_test_and_set(target, value);
|
||||
return result;
|
||||
#else
|
||||
#error Unsupported compiler
|
||||
#endif
|
||||
}
|
||||
|
||||
template <DN_USize N>
|
||||
bool DN_CPU_HasAllFeaturesCArray(DN_CPUReport const *report, DN_CPUFeature const (&features)[N])
|
||||
{
|
||||
bool result = DN_CPU_HasAllFeatures(report, features, N);
|
||||
return result;
|
||||
}
|
||||
|
||||
// NOTE: DN_Bit ////////////////////////////////////////////////////////////////////////////////////
|
||||
DN_API void DN_Bit_UnsetInplace (DN_USize *flags, DN_USize bitfield);
|
||||
DN_API void DN_Bit_SetInplace (DN_USize *flags, DN_USize bitfield);
|
||||
DN_API bool DN_Bit_IsSet (DN_USize bits, DN_USize bits_to_set);
|
||||
DN_API bool DN_Bit_IsNotSet (DN_USize bits, DN_USize bits_to_check);
|
||||
#define DN_Bit_ClearNextLSB(value) (value) & ((value) - 1)
|
||||
|
||||
// NOTE: DN_Safe ///////////////////////////////////////////////////////////////////////////////////
|
||||
DN_API DN_I64 DN_Safe_AddI64 (DN_I64 a, DN_I64 b);
|
||||
DN_API DN_I64 DN_Safe_MulI64 (DN_I64 a, DN_I64 b);
|
||||
|
||||
DN_API DN_U64 DN_Safe_AddU64 (DN_U64 a, DN_U64 b);
|
||||
DN_API DN_U64 DN_Safe_MulU64 (DN_U64 a, DN_U64 b);
|
||||
|
||||
DN_API DN_U64 DN_Safe_SubU64 (DN_U64 a, DN_U64 b);
|
||||
DN_API DN_U32 DN_Safe_SubU32 (DN_U32 a, DN_U32 b);
|
||||
|
||||
DN_API int DN_SaturateCastUSizeToInt (DN_USize val);
|
||||
DN_API DN_I8 DN_SaturateCastUSizeToI8 (DN_USize val);
|
||||
DN_API DN_I16 DN_SaturateCastUSizeToI16 (DN_USize val);
|
||||
DN_API DN_I32 DN_SaturateCastUSizeToI32 (DN_USize val);
|
||||
DN_API DN_I64 DN_SaturateCastUSizeToI64 (DN_USize val);
|
||||
|
||||
DN_API int DN_SaturateCastU64ToInt (DN_U64 val);
|
||||
DN_API DN_I8 DN_SaturateCastU8ToI8 (DN_U64 val);
|
||||
DN_API DN_I16 DN_SaturateCastU16ToI16 (DN_U64 val);
|
||||
DN_API DN_I32 DN_SaturateCastU32ToI32 (DN_U64 val);
|
||||
DN_API DN_I64 DN_SaturateCastU64ToI64 (DN_U64 val);
|
||||
DN_API DN_UInt DN_SaturateCastU64ToUInt (DN_U64 val);
|
||||
DN_API DN_U8 DN_SaturateCastU64ToU8 (DN_U64 val);
|
||||
DN_API DN_U16 DN_SaturateCastU64ToU16 (DN_U64 val);
|
||||
DN_API DN_U32 DN_SaturateCastU64ToU32 (DN_U64 val);
|
||||
|
||||
DN_API DN_U8 DN_SaturateCastUSizeToU8 (DN_USize val);
|
||||
DN_API DN_U16 DN_SaturateCastUSizeToU16 (DN_USize val);
|
||||
DN_API DN_U32 DN_SaturateCastUSizeToU32 (DN_USize val);
|
||||
DN_API DN_U64 DN_SaturateCastUSizeToU64 (DN_USize val);
|
||||
|
||||
DN_API int DN_SaturateCastISizeToInt (DN_ISize val);
|
||||
DN_API DN_I8 DN_SaturateCastISizeToI8 (DN_ISize val);
|
||||
DN_API DN_I16 DN_SaturateCastISizeToI16 (DN_ISize val);
|
||||
DN_API DN_I32 DN_SaturateCastISizeToI32 (DN_ISize val);
|
||||
DN_API DN_I64 DN_SaturateCastISizeToI64 (DN_ISize val);
|
||||
|
||||
DN_API DN_UInt DN_SaturateCastISizeToUInt (DN_ISize val);
|
||||
DN_API DN_U8 DN_SaturateCastISizeToU8 (DN_ISize val);
|
||||
DN_API DN_U16 DN_SaturateCastISizeToU16 (DN_ISize val);
|
||||
DN_API DN_U32 DN_SaturateCastISizeToU32 (DN_ISize val);
|
||||
DN_API DN_U64 DN_SaturateCastISizeToU64 (DN_ISize val);
|
||||
|
||||
DN_API DN_ISize DN_SaturateCastI64ToISize (DN_I64 val);
|
||||
DN_API DN_I8 DN_SaturateCastI64ToI8 (DN_I64 val);
|
||||
DN_API DN_I16 DN_SaturateCastI64ToI16 (DN_I64 val);
|
||||
DN_API DN_I32 DN_SaturateCastI64ToI32 (DN_I64 val);
|
||||
|
||||
DN_API DN_UInt DN_SaturateCastI64ToUInt (DN_I64 val);
|
||||
DN_API DN_ISize DN_SaturateCastI64ToUSize (DN_I64 val);
|
||||
DN_API DN_U8 DN_SaturateCastI64ToU8 (DN_I64 val);
|
||||
DN_API DN_U16 DN_SaturateCastI64ToU16 (DN_I64 val);
|
||||
DN_API DN_U32 DN_SaturateCastI64ToU32 (DN_I64 val);
|
||||
DN_API DN_U64 DN_SaturateCastI64ToU64 (DN_I64 val);
|
||||
|
||||
DN_API DN_I8 DN_SaturateCastIntToI8 (int val);
|
||||
DN_API DN_I16 DN_SaturateCastIntToI16 (int val);
|
||||
DN_API DN_U8 DN_SaturateCastIntToU8 (int val);
|
||||
DN_API DN_U16 DN_SaturateCastIntToU16 (int val);
|
||||
DN_API DN_U32 DN_SaturateCastIntToU32 (int val);
|
||||
DN_API DN_U64 DN_SaturateCastIntToU64 (int val);
|
||||
|
||||
// NOTE: DN_Asan ///////////////////////////////////////////////////////////////////////////////////
|
||||
DN_API void DN_ASAN_PoisonMemoryRegion (void const volatile *ptr, DN_USize size);
|
||||
DN_API void DN_ASAN_UnpoisonMemoryRegion (void const volatile *ptr, DN_USize size);
|
||||
DN_API void DN_ASanPoisonMemoryRegion (void const volatile *ptr, DN_USize size);
|
||||
DN_API void DN_ASanUnpoisonMemoryRegion(void const volatile *ptr, DN_USize size);
|
||||
#endif // !defined(DN_BASE_H)
|
||||
|
||||
@@ -1,56 +1,34 @@
|
||||
#if !defined(DN_BASE_ASSERT_H)
|
||||
#define DN_BASE_ASSERT_H
|
||||
|
||||
#define DN_HardAssertF(expr, fmt, ...) \
|
||||
do { \
|
||||
if (!(expr)) { \
|
||||
DN_Str8 stack_trace_ = DN_StackTrace_WalkStr8FromHeap(128 /*limit*/, 2 /*skip*/); \
|
||||
DN_LOG_ErrorF("Hard assertion [" #expr "], stack trace was:\n\n%.*s\n\n" fmt, \
|
||||
DN_STR_FMT(stack_trace_), \
|
||||
##__VA_ARGS__); \
|
||||
DN_DebugBreak; \
|
||||
} \
|
||||
} while (0)
|
||||
#define DN_HardAssert(expr) DN_HardAssertF(expr, "")
|
||||
|
||||
#if defined(DN_FREESTANDING)
|
||||
#define DN_HardAssertF(expr, fmt, ...) \
|
||||
do { \
|
||||
if (!(expr)) { \
|
||||
DN_DebugBreak; \
|
||||
(*(int *)0) = 0; \
|
||||
} \
|
||||
} while (0)
|
||||
#else
|
||||
#define DN_HardAssertF(expr, fmt, ...) \
|
||||
do { \
|
||||
if (!(expr)) { \
|
||||
DN_Str8 stack_trace_ = DN_StackTrace_WalkStr8FromHeap(128 /*limit*/, 2 /*skip*/); \
|
||||
DN_LOG_ErrorF("Hard assertion [" #expr "], stack trace was:\n\n%.*s\n\n" fmt, \
|
||||
DN_STR_FMT(stack_trace_), \
|
||||
##__VA_ARGS__); \
|
||||
DN_DebugBreak; \
|
||||
} \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#if defined(DN_NO_ASSERT)
|
||||
#define DN_Assert(...)
|
||||
#define DN_AssertOnce(...)
|
||||
#define DN_AssertF(...)
|
||||
#define DN_AssertFOnce(...)
|
||||
#else
|
||||
#if defined(DN_FREESTANDING)
|
||||
#define DN_AssertF(expr, fmt, ...) \
|
||||
do { \
|
||||
if (!(expr)) { \
|
||||
DN_DebugBreak; \
|
||||
(*(int *)0) = 0; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#else
|
||||
#define DN_AssertF(expr, fmt, ...) \
|
||||
do { \
|
||||
if (!(expr)) { \
|
||||
DN_Str8 stack_trace_ = DN_StackTrace_WalkStr8FromHeap(128 /*limit*/, 2 /*skip*/); \
|
||||
DN_LOG_ErrorF("Assertion [" #expr "], stack trace was:\n\n%.*s\n\n" fmt, \
|
||||
DN_STR_FMT(stack_trace_), \
|
||||
##__VA_ARGS__); \
|
||||
DN_DebugBreak; \
|
||||
} \
|
||||
} while (0)
|
||||
#endif
|
||||
#define DN_AssertF(expr, fmt, ...) \
|
||||
do { \
|
||||
if (!(expr)) { \
|
||||
DN_Str8 stack_trace_ = DN_StackTrace_WalkStr8FromHeap(128 /*limit*/, 2 /*skip*/); \
|
||||
DN_LOG_ErrorF("Assertion [" #expr "], stack trace was:\n\n%.*s\n\n" fmt, \
|
||||
DN_STR_FMT(stack_trace_), \
|
||||
##__VA_ARGS__); \
|
||||
DN_DebugBreak; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define DN_AssertFOnce(expr, fmt, ...) \
|
||||
do { \
|
||||
@@ -72,19 +50,13 @@
|
||||
#define DN_InvalidCodePathF(fmt, ...) DN_HardAssertF(0, fmt, ##__VA_ARGS__)
|
||||
#define DN_InvalidCodePath DN_InvalidCodePathF("Invalid code path triggered")
|
||||
|
||||
// NOTE: Check macro ///////////////////////////////////////////////////////////////////////////////
|
||||
#define DN_Check(expr) DN_CheckF(expr, "")
|
||||
|
||||
#if defined(DN_FREESTANDING)
|
||||
#define DN_CheckF(expr, fmt, ...) (expr)
|
||||
#if defined(DN_NO_CHECK_BREAK)
|
||||
#define DN_CheckF(expr, fmt, ...) \
|
||||
((expr) ? true : (DN_LOG_WarningF(fmt, ##__VA_ARGS__), false))
|
||||
#else
|
||||
#if defined(DN_NO_CHECK_BREAK)
|
||||
#define DN_CheckF(expr, fmt, ...) \
|
||||
((expr) ? true : (DN_LOG_WarningF(fmt, ##__VA_ARGS__), false))
|
||||
#else
|
||||
#define DN_CheckF(expr, fmt, ...) \
|
||||
((expr) ? true : (DN_LOG_ErrorF(fmt, ##__VA_ARGS__), DN_StackTrace_Print(128 /*limit*/), DN_DebugBreak, false))
|
||||
#endif
|
||||
#define DN_CheckF(expr, fmt, ...) \
|
||||
((expr) ? true : (DN_LOG_ErrorF(fmt, ##__VA_ARGS__), DN_StackTrace_Print(128 /*limit*/), DN_DebugBreak, false))
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -203,6 +203,76 @@ template <typename T> struct DN_List
|
||||
// MyLinkItem *first_item = DN_ISLList_Detach(&my_link, MyLinkItem);
|
||||
// ```
|
||||
|
||||
#define DN_DLList_Init(list) \
|
||||
(list)->next = (list)->prev = (list)
|
||||
|
||||
#define DN_DLList_IsSentinel(list, item) ((list) == (item))
|
||||
|
||||
#define DN_DLList_InitArena(list, T, arena) \
|
||||
do { \
|
||||
(list) = DN_Arena_New(arena, T, DN_ZeroMem_Yes); \
|
||||
DN_DLList_Init(list); \
|
||||
} while (0)
|
||||
|
||||
#define DN_DLList_InitPool(list, T, pool) \
|
||||
do { \
|
||||
(list) = DN_Pool_New(pool, T); \
|
||||
DN_DLList_Init(list); \
|
||||
} while (0)
|
||||
|
||||
#define DN_DLList_Detach(item) \
|
||||
do { \
|
||||
if (item) { \
|
||||
(item)->prev->next = (item)->next; \
|
||||
(item)->next->prev = (item)->prev; \
|
||||
(item)->next = nullptr; \
|
||||
(item)->prev = nullptr; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define DN_DLList_Dequeue(list, dest_ptr) \
|
||||
if (DN_DLList_HasItems(list)) { \
|
||||
dest_ptr = (list)->next; \
|
||||
DN_DLList_Detach(dest_ptr); \
|
||||
}
|
||||
|
||||
#define DN_DLList_Append(list, item) \
|
||||
do { \
|
||||
if (item) { \
|
||||
if ((item)->next) \
|
||||
DN_DLList_Detach(item); \
|
||||
(item)->next = (list)->next; \
|
||||
(item)->prev = (list); \
|
||||
(item)->next->prev = (item); \
|
||||
(item)->prev->next = (item); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define DN_DLList_Prepend(list, item) \
|
||||
do { \
|
||||
if (item) { \
|
||||
if ((item)->next) \
|
||||
DN_DLList_Detach(item); \
|
||||
(item)->next = (list); \
|
||||
(item)->prev = (list)->prev; \
|
||||
(item)->next->prev = (item); \
|
||||
(item)->prev->next = (item); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define DN_DLList_IsEmpty(list) \
|
||||
(!(list) || ((list) == (list)->next))
|
||||
|
||||
#define DN_DLList_IsInit(list) \
|
||||
((list)->next && (list)->prev)
|
||||
|
||||
#define DN_DLList_HasItems(list) \
|
||||
((list) && ((list) != (list)->next))
|
||||
|
||||
#define DN_DLList_ForEach(it, list) \
|
||||
auto *it = (list)->next; (it) != (list); (it) = (it)->next
|
||||
|
||||
|
||||
#define DN_ISLList_Detach(list) (decltype(list)) DN_CSLList_Detach((void **)&(list), (void **)&(list)->next)
|
||||
|
||||
#define DN_LArray_ResizeFromPool(c_array, size, max, pool, new_max) DN_CArray2_ResizeFromPool((void **)&(c_array), size, max, sizeof((c_array)[0]), pool, new_max)
|
||||
|
||||
@@ -78,11 +78,11 @@ DN_API DN_Str8 DN_CVT_BytesToHex (DN_Arena
|
||||
#define DN_CVT_BytesToHexFromTLS(...) DN_CVT_BytesToHex(DN_OS_TLSTopArena(), __VA_ARGS__)
|
||||
#define DN_CVT_BytesToHexFromFrame(...) DN_CVT_BytesToHex(DN_OS_TLSFrameArena(), __VA_ARGS__)
|
||||
|
||||
DN_API DN_USize DN_CVT_HexToBytesPtrUnchecked (DN_Str8 hex, void *dest, DN_USize dest_size);
|
||||
DN_API DN_USize DN_CVT_HexToBytesPtr (DN_Str8 hex, void *dest, DN_USize dest_size);
|
||||
DN_API DN_Str8 DN_CVT_HexToBytesUnchecked (DN_Arena *arena, DN_Str8 hex);
|
||||
#define DN_CVT_HexToBytesUncheckedFromTLS(...) DN_CVT_HexToBytesUnchecked(DN_OS_TLSTopArena(), __VA_ARGS__)
|
||||
DN_API DN_Str8 DN_CVT_HexToBytes (DN_Arena *arena, DN_Str8 hex);
|
||||
#define DN_CVT_HexToBytesFromFrame(...) DN_CVT_HexToBytes(DN_OS_TLSFrameArena(), __VA_ARGS__)
|
||||
#define DN_CVT_HexToBytesFromTLS(...) DN_CVT_HexToBytes(DN_OS_TLSTopArena(), __VA_ARGS__)
|
||||
DN_API DN_USize DN_CVT_HexToBytesPtrUnchecked (DN_Str8 hex, void *dest, DN_USize dest_size);
|
||||
DN_API DN_USize DN_CVT_HexToBytesPtr (DN_Str8 hex, void *dest, DN_USize dest_size);
|
||||
DN_API DN_Str8 DN_CVT_HexToBytesUnchecked (DN_Arena *arena, DN_Str8 hex);
|
||||
#define DN_CVT_HexToBytesUncheckedFromTLS(...) DN_CVT_HexToBytesUnchecked(DN_OS_TLSTopArena(), __VA_ARGS__)
|
||||
DN_API DN_Str8 DN_CVT_HexToBytes (DN_Arena *arena, DN_Str8 hex);
|
||||
#define DN_CVT_HexToBytesFromFrame(...) DN_CVT_HexToBytes(DN_OS_TLSFrameArena(), __VA_ARGS__)
|
||||
#define DN_CVT_HexToBytesFromTLS(...) DN_CVT_HexToBytes(DN_OS_TLSTopArena(), __VA_ARGS__)
|
||||
#endif // defined(DN_BASE_CONVERT_H)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#define DN_BASE_LOG_CPP
|
||||
|
||||
#include "../dn_clangd.h"
|
||||
#include "../dn_base_inc.h"
|
||||
|
||||
static DN_LOGEmitFromTypeFVFunc *g_dn_base_log_emit_from_type_fv_func_;
|
||||
static void *g_dn_base_log_emit_from_type_fv_user_context_;
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#if !defined(DN_BASE_LOG_H)
|
||||
#define DN_BASE_LOG_H
|
||||
|
||||
#include "../dn_base_inc.h"
|
||||
|
||||
enum DN_LOGType
|
||||
{
|
||||
DN_LOGType_Debug,
|
||||
@@ -67,6 +69,4 @@ DN_API DN_LOGTypeParam DN_LOG_MakeU32LogTypeParam (DN_LOGType type);
|
||||
#define DN_LOG_InfoF(fmt, ...) DN_LOG_EmitFromType(DN_LOG_MakeU32LogTypeParam(DN_LOGType_Info), DN_CALL_SITE, fmt, ##__VA_ARGS__)
|
||||
#define DN_LOG_WarningF(fmt, ...) DN_LOG_EmitFromType(DN_LOG_MakeU32LogTypeParam(DN_LOGType_Warning), DN_CALL_SITE, fmt, ##__VA_ARGS__)
|
||||
#define DN_LOG_ErrorF(fmt, ...) DN_LOG_EmitFromType(DN_LOG_MakeU32LogTypeParam(DN_LOGType_Error), DN_CALL_SITE, fmt, ##__VA_ARGS__)
|
||||
|
||||
|
||||
#endif // !defined(DN_BASE_LOG_H)
|
||||
|
||||
+10
-10
@@ -46,7 +46,7 @@ static DN_ArenaBlock *DN_Arena_BlockInitFromMemFuncs_(DN_U64 reserve, DN_U64 com
|
||||
}
|
||||
|
||||
if (track_alloc && result)
|
||||
DN_Debug_TrackAlloc(result, result->reserve, alloc_can_leak);
|
||||
DN_DBGTrackAlloc(result, result->reserve, alloc_can_leak);
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -57,7 +57,7 @@ static DN_ArenaBlock *DN_Arena_BlockInitFlagsFromMemFuncs_(DN_U64 reserve, DN_U6
|
||||
bool alloc_can_leak = flags & DN_ArenaFlags_AllocCanLeak;
|
||||
DN_ArenaBlock *result = DN_Arena_BlockInitFromMemFuncs_(reserve, commit, track_alloc, alloc_can_leak, mem_funcs);
|
||||
if (result && ((flags & DN_ArenaFlags_NoPoison) == 0))
|
||||
DN_ASAN_PoisonMemoryRegion(DN_CAST(char *) result + DN_ARENA_HEADER_SIZE, result->commit - DN_ARENA_HEADER_SIZE);
|
||||
DN_ASanPoisonMemoryRegion(DN_CAST(char *) result + DN_ARENA_HEADER_SIZE, result->commit - DN_ARENA_HEADER_SIZE);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -89,7 +89,7 @@ DN_API DN_Arena DN_Arena_InitFromBuffer(void *buffer, DN_USize size, DN_ArenaFla
|
||||
block->reserve = size;
|
||||
block->used = DN_ARENA_HEADER_SIZE;
|
||||
if (block && ((flags & DN_ArenaFlags_NoPoison) == 0))
|
||||
DN_ASAN_PoisonMemoryRegion(DN_CAST(char *) block + DN_ARENA_HEADER_SIZE, block->commit - DN_ARENA_HEADER_SIZE);
|
||||
DN_ASanPoisonMemoryRegion(DN_CAST(char *) block + DN_ARENA_HEADER_SIZE, block->commit - DN_ARENA_HEADER_SIZE);
|
||||
|
||||
DN_Arena result = {};
|
||||
result.flags = flags | DN_ArenaFlags_NoGrow | DN_ArenaFlags_NoAllocTrack | DN_ArenaFlags_AllocCanLeak | DN_ArenaFlags_UserBuffer;
|
||||
@@ -112,9 +112,9 @@ DN_API DN_Arena DN_Arena_InitFromMemFuncs(DN_U64 reserve, DN_U64 commit, DN_Aren
|
||||
static void DN_Arena_BlockDeinit_(DN_Arena const *arena, DN_ArenaBlock *block)
|
||||
{
|
||||
DN_USize release_size = block->reserve;
|
||||
if (DN_Bit_IsNotSet(arena->flags, DN_ArenaFlags_NoAllocTrack))
|
||||
DN_Debug_TrackDealloc(block);
|
||||
DN_ASAN_UnpoisonMemoryRegion(block, block->commit);
|
||||
if (DN_BitIsNotSet(arena->flags, DN_ArenaFlags_NoAllocTrack))
|
||||
DN_DBGTrackDealloc(block);
|
||||
DN_ASanUnpoisonMemoryRegion(block, block->commit);
|
||||
if (arena->flags & DN_ArenaFlags_MemFuncs) {
|
||||
if (arena->mem_funcs.type == DN_ArenaMemFuncType_Basic)
|
||||
arena->mem_funcs.basic_dealloc(block);
|
||||
@@ -156,7 +156,7 @@ DN_API bool DN_Arena_CommitTo(DN_Arena *arena, DN_U64 pos)
|
||||
|
||||
bool poison = DN_ASAN_POISON && ((arena->flags & DN_ArenaFlags_NoPoison) == 0);
|
||||
if (poison)
|
||||
DN_ASAN_PoisonMemoryRegion(commit_ptr, commit_size);
|
||||
DN_ASanPoisonMemoryRegion(commit_ptr, commit_size);
|
||||
|
||||
curr->commit = end_commit;
|
||||
return true;
|
||||
@@ -230,7 +230,7 @@ DN_API void *DN_Arena_Alloc(DN_Arena *arena, DN_U64 size, uint8_t align, DN_Zero
|
||||
if (!arena->mem_funcs.vmem_commit(commit_ptr, commit_size, DN_MemPage_ReadWrite))
|
||||
return nullptr;
|
||||
if (poison)
|
||||
DN_ASAN_PoisonMemoryRegion(commit_ptr, commit_size);
|
||||
DN_ASanPoisonMemoryRegion(commit_ptr, commit_size);
|
||||
curr->commit = end_commit;
|
||||
arena->stats.info.commit += commit_size;
|
||||
arena->stats.hwm.commit = DN_Max(arena->stats.hwm.commit, arena->stats.info.commit);
|
||||
@@ -240,7 +240,7 @@ DN_API void *DN_Arena_Alloc(DN_Arena *arena, DN_U64 size, uint8_t align, DN_Zero
|
||||
curr->used += alloc_size;
|
||||
arena->stats.info.used += alloc_size;
|
||||
arena->stats.hwm.used = DN_Max(arena->stats.hwm.used, arena->stats.info.used);
|
||||
DN_ASAN_UnpoisonMemoryRegion(result, size);
|
||||
DN_ASanUnpoisonMemoryRegion(result, size);
|
||||
|
||||
if (zero_mem == DN_ZeroMem_Yes) {
|
||||
DN_USize reused_bytes = DN_Min(prev_arena_commit - offset_pos, size);
|
||||
@@ -296,7 +296,7 @@ DN_API void DN_Arena_PopTo(DN_Arena *arena, DN_U64 init_used)
|
||||
curr->used = used - curr->reserve_sum;
|
||||
char *poison_ptr = (char *)curr + DN_AlignUpPowerOfTwo(curr->used, DN_ASAN_POISON_ALIGNMENT);
|
||||
DN_USize poison_size = ((char *)curr + curr->commit) - poison_ptr;
|
||||
DN_ASAN_PoisonMemoryRegion(poison_ptr, poison_size);
|
||||
DN_ASanPoisonMemoryRegion(poison_ptr, poison_size);
|
||||
arena->stats.info.used += curr->used;
|
||||
}
|
||||
|
||||
|
||||
+37
-50
@@ -1,7 +1,7 @@
|
||||
#if !defined(DN_BASE_MEM_H)
|
||||
#define DN_BASE_MEM_H
|
||||
|
||||
#include "../dn_clangd.h"
|
||||
#include "../dn_base_inc.h"
|
||||
|
||||
enum DN_MemCommit
|
||||
{
|
||||
@@ -146,32 +146,6 @@ struct DN_ArenaTempMemScope
|
||||
|
||||
DN_USize const DN_ARENA_HEADER_SIZE = DN_AlignUpPowerOfTwo(sizeof(DN_Arena), 64);
|
||||
|
||||
// NOTE: DN_Arena //////////////////////////////////////////////////////////////////////////////////
|
||||
DN_API DN_Arena DN_Arena_InitFromBuffer (void *buffer, DN_USize size, DN_ArenaFlags flags);
|
||||
DN_API DN_Arena DN_Arena_InitFromMemFuncs (DN_U64 reserve, DN_U64 commit, DN_ArenaFlags flags, DN_ArenaMemFuncs mem_funcs);
|
||||
DN_API void DN_Arena_Deinit (DN_Arena *arena);
|
||||
DN_API bool DN_Arena_Commit (DN_Arena *arena, DN_U64 size);
|
||||
DN_API bool DN_Arena_CommitTo (DN_Arena *arena, DN_U64 pos);
|
||||
DN_API bool DN_Arena_Grow (DN_Arena *arena, DN_U64 reserve, DN_U64 commit);
|
||||
DN_API void * DN_Arena_Alloc (DN_Arena *arena, DN_U64 size, uint8_t align, DN_ZeroMem zero_mem);
|
||||
DN_API void * DN_Arena_AllocContiguous (DN_Arena *arena, DN_U64 size, uint8_t align, DN_ZeroMem zero_mem);
|
||||
DN_API void * DN_Arena_Copy (DN_Arena *arena, void const *data, DN_U64 size, uint8_t align);
|
||||
DN_API void DN_Arena_PopTo (DN_Arena *arena, DN_U64 init_used);
|
||||
DN_API void DN_Arena_Pop (DN_Arena *arena, DN_U64 amount);
|
||||
DN_API DN_U64 DN_Arena_Pos (DN_Arena const *arena);
|
||||
DN_API void DN_Arena_Clear (DN_Arena *arena);
|
||||
DN_API bool DN_Arena_OwnsPtr (DN_Arena const *arena, void *ptr);
|
||||
DN_API DN_ArenaStats DN_Arena_SumStatsArray (DN_ArenaStats const *array, DN_USize size);
|
||||
DN_API DN_ArenaStats DN_Arena_SumStats (DN_ArenaStats lhs, DN_ArenaStats rhs);
|
||||
DN_API DN_ArenaStats DN_Arena_SumArenaArrayToStats (DN_Arena const *array, DN_USize size);
|
||||
DN_API DN_ArenaTempMem DN_Arena_TempMemBegin (DN_Arena *arena);
|
||||
DN_API void DN_Arena_TempMemEnd (DN_ArenaTempMem mem);
|
||||
#define DN_Arena_New_Frame(T, zero_mem) (T *)DN_Arena_Alloc(DN_OS_TLSGet()->frame_arena, sizeof(T), alignof(T), zero_mem)
|
||||
#define DN_Arena_New(arena, T, zero_mem) (T *)DN_Arena_Alloc(arena, sizeof(T), alignof(T), zero_mem)
|
||||
#define DN_Arena_NewArray(arena, T, count, zero_mem) (T *)DN_Arena_Alloc(arena, sizeof(T) * (count), alignof(T), zero_mem)
|
||||
#define DN_Arena_NewCopy(arena, T, src) (T *)DN_Arena_Copy (arena, (src), sizeof(T), alignof(T))
|
||||
#define DN_Arena_NewArrayCopy(arena, T, src, count) (T *)DN_Arena_Copy (arena, (src), sizeof(T) * (count), alignof(T))
|
||||
|
||||
#if !defined(DN_POOL_DEFAULT_ALIGN)
|
||||
#define DN_POOL_DEFAULT_ALIGN 16
|
||||
#endif
|
||||
@@ -225,29 +199,42 @@ struct DN_Pool
|
||||
DN_U8 align;
|
||||
};
|
||||
|
||||
// NOTE: DN_Pool ///////////////////////////////////////////////////////////////////////////////////
|
||||
DN_API DN_Pool DN_Pool_Init (DN_Arena *arena, DN_U8 align);
|
||||
DN_API bool DN_Pool_IsValid (DN_Pool const *pool);
|
||||
DN_API void * DN_Pool_Alloc (DN_Pool *pool, DN_USize size);
|
||||
DN_API DN_Str8 DN_Pool_AllocStr8FV (DN_Pool *pool, DN_FMT_ATTRIB char const *fmt, va_list args);
|
||||
DN_API DN_Str8 DN_Pool_AllocStr8F (DN_Pool *pool, DN_FMT_ATTRIB char const *fmt, ...);
|
||||
DN_API DN_Str8 DN_Pool_AllocStr8Copy (DN_Pool *pool, DN_Str8 string);
|
||||
DN_API void DN_Pool_Dealloc (DN_Pool *pool, void *ptr);
|
||||
DN_API void * DN_Pool_Copy (DN_Pool *pool, void const *data, DN_U64 size, uint8_t align);
|
||||
DN_API DN_Arena DN_Arena_InitFromBuffer (void *buffer, DN_USize size, DN_ArenaFlags flags);
|
||||
DN_API DN_Arena DN_Arena_InitFromMemFuncs (DN_U64 reserve, DN_U64 commit, DN_ArenaFlags flags, DN_ArenaMemFuncs mem_funcs);
|
||||
DN_API void DN_Arena_Deinit (DN_Arena *arena);
|
||||
DN_API bool DN_Arena_Commit (DN_Arena *arena, DN_U64 size);
|
||||
DN_API bool DN_Arena_CommitTo (DN_Arena *arena, DN_U64 pos);
|
||||
DN_API bool DN_Arena_Grow (DN_Arena *arena, DN_U64 reserve, DN_U64 commit);
|
||||
DN_API void * DN_Arena_Alloc (DN_Arena *arena, DN_U64 size, uint8_t align, DN_ZeroMem zero_mem);
|
||||
DN_API void * DN_Arena_AllocContiguous (DN_Arena *arena, DN_U64 size, uint8_t align, DN_ZeroMem zero_mem);
|
||||
DN_API void * DN_Arena_Copy (DN_Arena *arena, void const *data, DN_U64 size, uint8_t align);
|
||||
DN_API void DN_Arena_PopTo (DN_Arena *arena, DN_U64 init_used);
|
||||
DN_API void DN_Arena_Pop (DN_Arena *arena, DN_U64 amount);
|
||||
DN_API DN_U64 DN_Arena_Pos (DN_Arena const *arena);
|
||||
DN_API void DN_Arena_Clear (DN_Arena *arena);
|
||||
DN_API bool DN_Arena_OwnsPtr (DN_Arena const *arena, void *ptr);
|
||||
DN_API DN_ArenaStats DN_Arena_SumStatsArray (DN_ArenaStats const *array, DN_USize size);
|
||||
DN_API DN_ArenaStats DN_Arena_SumStats (DN_ArenaStats lhs, DN_ArenaStats rhs);
|
||||
DN_API DN_ArenaStats DN_Arena_SumArenaArrayToStats (DN_Arena const *array, DN_USize size);
|
||||
DN_API DN_ArenaTempMem DN_Arena_TempMemBegin (DN_Arena *arena);
|
||||
DN_API void DN_Arena_TempMemEnd (DN_ArenaTempMem mem);
|
||||
#define DN_Arena_New_Frame(T, zero_mem) (T *)DN_Arena_Alloc(DN_OS_TLSGet()->frame_arena, sizeof(T), alignof(T), zero_mem)
|
||||
#define DN_Arena_New(arena, T, zero_mem) (T *)DN_Arena_Alloc(arena, sizeof(T), alignof(T), zero_mem)
|
||||
#define DN_Arena_NewArray(arena, T, count, zero_mem) (T *)DN_Arena_Alloc(arena, sizeof(T) * (count), alignof(T), zero_mem)
|
||||
#define DN_Arena_NewCopy(arena, T, src) (T *)DN_Arena_Copy (arena, (src), sizeof(T), alignof(T))
|
||||
#define DN_Arena_NewArrayCopy(arena, T, src, count) (T *)DN_Arena_Copy (arena, (src), sizeof(T) * (count), alignof(T))
|
||||
|
||||
#define DN_Pool_New(pool, T) (T *)DN_Pool_Alloc(pool, sizeof(T))
|
||||
#define DN_Pool_NewArray(pool, T, count) (T *)DN_Pool_Alloc(pool, count * sizeof(T))
|
||||
#define DN_Pool_NewCopy(arena, T, src) (T *)DN_Pool_Copy (arena, (src), sizeof(T), alignof(T))
|
||||
#define DN_Pool_NewArrayCopy(arena, T, src, count) (T *)DN_Pool_Copy (arena, (src), sizeof(T) * (count), alignof(T))
|
||||
DN_API DN_Pool DN_Pool_Init (DN_Arena *arena, DN_U8 align);
|
||||
DN_API bool DN_Pool_IsValid (DN_Pool const *pool);
|
||||
DN_API void * DN_Pool_Alloc (DN_Pool *pool, DN_USize size);
|
||||
DN_API DN_Str8 DN_Pool_AllocStr8FV (DN_Pool *pool, DN_FMT_ATTRIB char const *fmt, va_list args);
|
||||
DN_API DN_Str8 DN_Pool_AllocStr8F (DN_Pool *pool, DN_FMT_ATTRIB char const *fmt, ...);
|
||||
DN_API DN_Str8 DN_Pool_AllocStr8Copy (DN_Pool *pool, DN_Str8 string);
|
||||
DN_API void DN_Pool_Dealloc (DN_Pool *pool, void *ptr);
|
||||
DN_API void * DN_Pool_Copy (DN_Pool *pool, void const *data, DN_U64 size, uint8_t align);
|
||||
|
||||
// NOTE: DN_Debug //////////////////////////////////////////////////////////////////////////////////
|
||||
#if defined(DN_LEAK_TRACKING) && !defined(DN_FREESTANDING)
|
||||
DN_API void DN_Debug_TrackAlloc (void *ptr, DN_USize size, bool alloc_can_leak);
|
||||
DN_API void DN_Debug_TrackDealloc(void *ptr);
|
||||
DN_API void DN_Debug_DumpLeaks ();
|
||||
#else
|
||||
#define DN_Debug_TrackAlloc(ptr, size, alloc_can_leak) do { (void)ptr; (void)size; (void)alloc_can_leak; } while (0)
|
||||
#define DN_Debug_TrackDealloc(ptr) do { (void)ptr; } while (0)
|
||||
#define DN_Debug_DumpLeaks() do { } while (0)
|
||||
#endif
|
||||
#define DN_Pool_New(pool, T) (T *)DN_Pool_Alloc(pool, sizeof(T))
|
||||
#define DN_Pool_NewArray(pool, T, count) (T *)DN_Pool_Alloc(pool, count * sizeof(T))
|
||||
#define DN_Pool_NewCopy(arena, T, src) (T *)DN_Pool_Copy (arena, (src), sizeof(T), alignof(T))
|
||||
#define DN_Pool_NewArrayCopy(arena, T, src, count) (T *)DN_Pool_Copy (arena, (src), sizeof(T) * (count), alignof(T))
|
||||
#endif // !defined(DN_BASE_MEM_H)
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#if !defined(DN_BASE_OS_H)
|
||||
#define DN_BASE_OS_H
|
||||
|
||||
#include "../dn_base_inc.h"
|
||||
|
||||
// NOTE: OS primitives that the OS layer can provide for the base layer but is optional.
|
||||
|
||||
struct DN_StackTraceFrame
|
||||
@@ -30,7 +32,19 @@ struct DN_StackTraceWalkResultIterator
|
||||
DN_U16 index;
|
||||
};
|
||||
|
||||
DN_API DN_Str8 DN_StackTrace_WalkStr8FromHeap (DN_U16 limit, DN_U16 skip);
|
||||
|
||||
#if defined(DN_FREESTANDING)
|
||||
#define DN_StackTrace_WalkStr8FromHeap(...) DN_STR8("N/A")
|
||||
#define DN_StackTrace_Walk(...)
|
||||
#define DN_StackTrace_WalkResultIterate(...)
|
||||
#define DN_StackTrace_WalkResultToStr8(...) DN_STR8("N/A")
|
||||
#define DN_StackTrace_WalkStr8(...) DN_STR8("N/A")
|
||||
#define DN_StackTrace_WalkStr8FromHeap(...) DN_STR8("N/A")
|
||||
#define DN_StackTrace_GetFrames(...)
|
||||
#define DN_StackTrace_RawFrameToFrame(...)
|
||||
#define DN_StackTrace_Print(...)
|
||||
#define DN_StackTrace_ReloadSymbols(...)
|
||||
#else
|
||||
DN_API DN_StackTraceWalkResult DN_StackTrace_Walk (struct DN_Arena *arena, DN_U16 limit);
|
||||
DN_API bool DN_StackTrace_WalkResultIterate(DN_StackTraceWalkResultIterator *it, DN_StackTraceWalkResult const *walk);
|
||||
DN_API DN_Str8 DN_StackTrace_WalkResultToStr8 (struct DN_Arena *arena, DN_StackTraceWalkResult const *walk, DN_U16 skip);
|
||||
@@ -40,7 +54,5 @@ DN_API DN_Slice<DN_StackTraceFrame> DN_StackTrace_GetFrames (struct DN_Ar
|
||||
DN_API DN_StackTraceFrame DN_StackTrace_RawFrameToFrame (struct DN_Arena *arena, DN_StackTraceRawFrame raw_frame);
|
||||
DN_API void DN_StackTrace_Print (DN_U16 limit);
|
||||
DN_API void DN_StackTrace_ReloadSymbols ();
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#endif // !defined(DN_BASE_OS_H)
|
||||
|
||||
@@ -542,9 +542,9 @@ DN_API DN_Str8ToU64Result DN_Str8_ToU64(DN_Str8 string, char separator)
|
||||
if (!DN_Char_IsDigit(ch))
|
||||
return result;
|
||||
|
||||
result.value = DN_Safe_MulU64(result.value, 10);
|
||||
result.value = DN_SafeMulU64(result.value, 10);
|
||||
uint64_t digit = ch - '0';
|
||||
result.value = DN_Safe_AddU64(result.value, digit);
|
||||
result.value = DN_SafeAddU64(result.value, digit);
|
||||
}
|
||||
|
||||
result.success = true;
|
||||
@@ -587,9 +587,9 @@ DN_API DN_Str8ToI64Result DN_Str8_ToI64(DN_Str8 string, char separator)
|
||||
if (!DN_Char_IsDigit(ch))
|
||||
return result;
|
||||
|
||||
result.value = DN_Safe_MulU64(result.value, 10);
|
||||
result.value = DN_SafeMulU64(result.value, 10);
|
||||
uint64_t digit = ch - '0';
|
||||
result.value = DN_Safe_AddU64(result.value, digit);
|
||||
result.value = DN_SafeAddU64(result.value, digit);
|
||||
}
|
||||
|
||||
if (negative)
|
||||
|
||||
@@ -18,24 +18,6 @@ DN_MSVC_WARNING_POP
|
||||
#define DN_VSPrintF(...) STB_SPRINTF_DECORATE(vsprintf)(__VA_ARGS__)
|
||||
#define DN_VSNPrintF(...) STB_SPRINTF_DECORATE(vsnprintf)(__VA_ARGS__)
|
||||
|
||||
/*
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// $$$$$$\ $$$$$$$$\ $$$$$$$\ $$$$$$\ $$\ $$\ $$$$$$\
|
||||
// $$ __$$\\__$$ __|$$ __$$\ \_$$ _|$$$\ $$ |$$ __$$\
|
||||
// $$ / \__| $$ | $$ | $$ | $$ | $$$$\ $$ |$$ / \__|
|
||||
// \$$$$$$\ $$ | $$$$$$$ | $$ | $$ $$\$$ |$$ |$$$$\
|
||||
// \____$$\ $$ | $$ __$$< $$ | $$ \$$$$ |$$ |\_$$ |
|
||||
// $$\ $$ | $$ | $$ | $$ | $$ | $$ |\$$$ |$$ | $$ |
|
||||
// \$$$$$$ | $$ | $$ | $$ |$$$$$$\ $$ | \$$ |\$$$$$$ |
|
||||
// \______/ \__| \__| \__|\______|\__| \__| \______/
|
||||
//
|
||||
// dn_base_string.h
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
*/
|
||||
|
||||
// NOTE: DN_Str8 //////////////////////////////////////////////////////////////////////////////////
|
||||
struct DN_Str8Link
|
||||
{
|
||||
DN_Str8 string; // The string
|
||||
@@ -105,7 +87,6 @@ struct DN_Str8DotTruncateResult
|
||||
DN_Str8 str8;
|
||||
};
|
||||
|
||||
// NOTE: DN_FStr8 //////////////////////////////////////////////////////////////////////////////////
|
||||
#if !defined(DN_NO_FSTR8)
|
||||
template <DN_USize N>
|
||||
struct DN_FStr8
|
||||
|
||||
Reference in New Issue
Block a user