Import latest revision of dqn lib from CSIGHT
This commit is contained in:
parent
7f2a0152e0
commit
158d058d5d
@ -71,7 +71,7 @@ void Dqn_CppPrint(Dqn_CppFile *cpp, char const *fmt, ...);
|
||||
|
||||
#define Dqn_CppForBlock(cpp, fmt, ...) \
|
||||
for (bool DQN_CPP_TOKEN_PASTE_(once_, __LINE__) = \
|
||||
(Dqn_CppBeginForBLock(cpp, fmt, ##__VA_ARGS__), true); \
|
||||
(Dqn_CppBeginForBlock(cpp, fmt, ##__VA_ARGS__), true); \
|
||||
DQN_CPP_TOKEN_PASTE_(once_, __LINE__); \
|
||||
DQN_CPP_TOKEN_PASTE_(once_, __LINE__) = (Dqn_CppEndForBlock(cpp), false))
|
||||
|
||||
|
@ -220,7 +220,7 @@ DQN_API void Dqn_Arena_Pop(Dqn_Arena *arena, uint64_t amount)
|
||||
Dqn_Arena_PopTo(arena, pop_to);
|
||||
}
|
||||
|
||||
DQN_API uint64_t Dqn_Arena_Pos(Dqn_Arena *arena)
|
||||
DQN_API uint64_t Dqn_Arena_Pos(Dqn_Arena const *arena)
|
||||
{
|
||||
uint64_t result = (arena && arena->curr) ? arena->curr->reserve_sum + arena->curr->used : 0;
|
||||
return result;
|
||||
@ -231,6 +231,18 @@ DQN_API void Dqn_Arena_Clear(Dqn_Arena *arena)
|
||||
Dqn_Arena_PopTo(arena, 0);
|
||||
}
|
||||
|
||||
DQN_API bool Dqn_Arena_OwnsPtr(Dqn_Arena const *arena, void *ptr)
|
||||
{
|
||||
bool result = false;
|
||||
uintptr_t uint_ptr = DQN_CAST(uintptr_t)ptr;
|
||||
for (Dqn_ArenaBlock const *block = arena ? arena->curr : nullptr; !result && block; ) {
|
||||
uintptr_t begin = DQN_CAST(uintptr_t) block + DQN_ARENA_HEADER_SIZE;
|
||||
uintptr_t end = begin + block->reserve;
|
||||
result = uint_ptr >= begin && uint_ptr <= end;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
DQN_API Dqn_ArenaTempMem Dqn_Arena_TempMemBegin(Dqn_Arena *arena)
|
||||
{
|
||||
Dqn_ArenaTempMem result = {};
|
||||
|
@ -145,8 +145,9 @@ DQN_API void * Dqn_Arena_AllocContiguous (Dqn_Arena *arena,
|
||||
DQN_API void * Dqn_Arena_Copy (Dqn_Arena *arena, void const *data, uint64_t size, uint8_t align);
|
||||
DQN_API void Dqn_Arena_PopTo (Dqn_Arena *arena, uint64_t init_used);
|
||||
DQN_API void Dqn_Arena_Pop (Dqn_Arena *arena, uint64_t amount);
|
||||
DQN_API uint64_t Dqn_Arena_Pos (Dqn_Arena *arena);
|
||||
DQN_API uint64_t Dqn_Arena_Pos (Dqn_Arena const *arena);
|
||||
DQN_API void Dqn_Arena_Clear (Dqn_Arena *arena);
|
||||
DQN_API bool Dqn_Arena_OwnsPtr (Dqn_Arena const *arena, void *ptr);
|
||||
DQN_API Dqn_ArenaTempMem Dqn_Arena_TempMemBegin (Dqn_Arena *arena);
|
||||
DQN_API void Dqn_Arena_TempMemEnd (Dqn_ArenaTempMem mem);
|
||||
#define Dqn_Arena_New(arena, T, zero_mem) (T *)Dqn_Arena_Alloc(arena, sizeof(T), alignof(T), zero_mem)
|
||||
|
14
dqn_base.cpp
14
dqn_base.cpp
@ -419,6 +419,12 @@ DQN_API Dqn_ErrorSink *Dqn_ErrorSink_Begin(Dqn_ErrorSinkMode mode)
|
||||
return result;
|
||||
}
|
||||
|
||||
DQN_API bool Dqn_ErrorSink_HasError(Dqn_ErrorSink *error)
|
||||
{
|
||||
bool result = error && error->stack->error;
|
||||
return result;
|
||||
}
|
||||
|
||||
DQN_API Dqn_ErrorSinkNode Dqn_ErrorSink_End(Dqn_Arena *arena, Dqn_ErrorSink *error)
|
||||
{
|
||||
Dqn_ErrorSinkNode result = {};
|
||||
@ -445,7 +451,7 @@ DQN_API bool Dqn_ErrorSink_EndAndLogError(Dqn_ErrorSink *error, Dqn_Str8 error_m
|
||||
Dqn_ErrorSinkNode node = Dqn_ErrorSink_End(scratch.arena, error);
|
||||
if (node.error) {
|
||||
if (Dqn_Str8_HasData(error_msg)) {
|
||||
Dqn_Log_TypeFCallSite(Dqn_LogType_Error, node.call_site, "%.*s. %.*s", DQN_STR_FMT(error_msg), DQN_STR_FMT(node.msg));
|
||||
Dqn_Log_TypeFCallSite(Dqn_LogType_Error, node.call_site, "%.*s: %.*s", DQN_STR_FMT(error_msg), DQN_STR_FMT(node.msg));
|
||||
} else {
|
||||
Dqn_Log_TypeFCallSite(Dqn_LogType_Error, node.call_site, "%.*s", DQN_STR_FMT(node.msg));
|
||||
}
|
||||
@ -475,8 +481,10 @@ DQN_API bool Dqn_ErrorSink_EndAndLogErrorF(Dqn_ErrorSink *error, DQN_FMT_ATTRIB
|
||||
|
||||
DQN_API void Dqn_ErrorSink_EndAndExitIfErrorFV(Dqn_ErrorSink *error, uint32_t exit_code, DQN_FMT_ATTRIB char const *fmt, va_list args)
|
||||
{
|
||||
if (Dqn_ErrorSink_EndAndLogErrorFV(error, fmt, args))
|
||||
if (Dqn_ErrorSink_EndAndLogErrorFV(error, fmt, args)) {
|
||||
DQN_DEBUG_BREAK;
|
||||
Dqn_OS_Exit(exit_code);
|
||||
}
|
||||
}
|
||||
|
||||
DQN_API void Dqn_ErrorSink_EndAndExitIfErrorF(Dqn_ErrorSink *error, uint32_t exit_code, DQN_FMT_ATTRIB char const *fmt, ...)
|
||||
@ -500,7 +508,7 @@ DQN_API void Dqn_ErrorSink_MakeFV_(Dqn_ErrorSink *error, uint32_t error_code, DQ
|
||||
node->error = true;
|
||||
node->call_site = Dqn_ThreadContext_Get()->call_site;
|
||||
if (node->mode == Dqn_ErrorSinkMode_ExitOnError)
|
||||
Dqn_ErrorSink_EndAndExitIfErrorF(error, error_code, "Fatal error encountered: (%u) %.*s", error_code, DQN_STR_FMT(node->msg));
|
||||
Dqn_ErrorSink_EndAndExitIfErrorF(error, error_code, "Fatal error %u", error_code);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -285,8 +285,8 @@
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#define DQN_INVALID_CODE_PATHF(fmt, ...) DQN_ASSERTF(0, fmt, ##__VA_ARGS__)
|
||||
#define DQN_INVALID_CODE_PATH DQN_INVALID_CODE_PATHF("Invalid code path triggered")
|
||||
#define DQN_INVALID_CODE_PATHF(fmt, ...) DQN_HARD_ASSERTF(0, fmt, ##__VA_ARGS__)
|
||||
#define DQN_INVALID_CODE_PATH DQN_INVALID_CODE_PATHF("Invalid code path triggered")
|
||||
|
||||
// NOTE: Check macro ///////////////////////////////////////////////////////////////////////////////
|
||||
#define DQN_CHECK(expr) DQN_CHECKF(expr, "")
|
||||
@ -621,6 +621,7 @@ DQN_API void Dqn_Log_FCallSite
|
||||
|
||||
// NOTE: [$ERRS] Dqn_ErrorSink /////////////////////////////////////////////////////////////////////
|
||||
DQN_API Dqn_ErrorSink * Dqn_ErrorSink_Begin (Dqn_ErrorSinkMode mode);
|
||||
DQN_API bool Dqn_ErrorSink_HasError (Dqn_ErrorSink *error);
|
||||
DQN_API Dqn_ErrorSinkNode Dqn_ErrorSink_End (Dqn_Arena *arena, Dqn_ErrorSink *error);
|
||||
DQN_API bool Dqn_ErrorSink_EndAndLogError (Dqn_ErrorSink *error, Dqn_Str8 error_msg);
|
||||
DQN_API bool Dqn_ErrorSink_EndAndLogErrorFV (Dqn_ErrorSink *error, DQN_FMT_ATTRIB char const *fmt, va_list args);
|
||||
|
37
dqn_cgen.cpp
37
dqn_cgen.cpp
@ -105,6 +105,9 @@ static bool Dqn_CGen_GatherTables_(Dqn_CGen *cgen, Dqn_ErrorSink *error)
|
||||
DQN_ARRAY_UCOUNT(DQN_CGEN_TABLE_TYPE_LIST),
|
||||
"Table 'type' specified invalid value");
|
||||
table->type = DQN_CAST(Dqn_CGenTableType) table_type_validator.enum_val;
|
||||
|
||||
DQN_ASSERT(table->type <= Dqn_CGenTableType_Count);
|
||||
cgen->table_counts[table->type]++;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
@ -454,6 +457,7 @@ DQN_API bool Dqn_CGen_LookupNextTableInCodeGenTable(Dqn_CGen *cgen, Dqn_CGenTabl
|
||||
// NOTE: Lookup the table in this row that we will code generate from. Not
|
||||
// applicable when we are doing builtin types as the types are just put
|
||||
// in-line into the code generation table itself.
|
||||
it->cgen_table = cgen_table;
|
||||
it->cgen_table_row = cgen_table->rows + it->row_index++;
|
||||
if (cgen_table->type != Dqn_CGenTableType_CodeGenBuiltinTypes) {
|
||||
Dqn_CGenTableColumn cgen_table_column = it->cgen_table_row->columns[cgen_table->column_indexes[Dqn_CGenTableHeaderType_Table]];
|
||||
@ -752,7 +756,7 @@ DQN_API void Dqn_CGen_EmitCodeForTables(Dqn_CGen *cgen, Dqn_CGenEmit emit, Dqn_C
|
||||
}
|
||||
|
||||
Dqn_CppBlock(cpp, ";\n\n", "Dqn_TypeInfo const g_%.*s_types[] =", DQN_STR_FMT(emit_prefix)) {
|
||||
Dqn_CppLine(cpp, "{DQN_STR8(\"\"),%*sDqn_TypeKind_Nil, /*fields*/ NULL, /*count*/ 0},", 1 + longest_name_across_all_tables, "");
|
||||
Dqn_CppLine(cpp, "{DQN_STR8(\"\"),%*sDqn_TypeKind_Nil, 0, /*fields*/ NULL, /*count*/ 0},", 1 + longest_name_across_all_tables, "");
|
||||
for (Dqn_CGenTable *table = cgen->first_table; table != 0; table = table->next) {
|
||||
for (Dqn_CGenLookupTableIterator it = {}; Dqn_CGen_LookupNextTableInCodeGenTable(cgen, table, &it);) {
|
||||
Dqn_Str8 type_name = it.cgen_table_column[Dqn_CGenTableHeaderType_Name].string;
|
||||
@ -794,16 +798,45 @@ DQN_API void Dqn_CGen_EmitCodeForTables(Dqn_CGen *cgen, Dqn_CGenEmit emit, Dqn_C
|
||||
}
|
||||
|
||||
Dqn_CppLine(cpp,
|
||||
"{DQN_STR8(\"%.*s\"),%*s%.*s, %s/*fields*/ %.*s,%*s/*count*/ %.*s},",
|
||||
"{DQN_STR8(\"%.*s\"),%*s%.*s, %ssizeof(%.*s),%*s/*fields*/ %.*s,%*s/*count*/ %.*s},",
|
||||
DQN_STR_FMT(type_name),
|
||||
name_padding, "",
|
||||
DQN_STR_FMT(type_info_kind),
|
||||
type_info_kind_padding,
|
||||
DQN_STR_FMT(type_name),
|
||||
name_padding, "",
|
||||
DQN_STR_FMT(fields),
|
||||
fields_padding, "",
|
||||
DQN_STR_FMT(fields_count));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (Dqn_CGenTable *table = cgen->first_table; table != 0; table = table->next) {
|
||||
if (table->type != Dqn_CGenTableType_CodeGenEnum)
|
||||
continue;
|
||||
|
||||
for (Dqn_CGenLookupTableIterator it = {}; Dqn_CGen_LookupNextTableInCodeGenTable(cgen, table, &it);) {
|
||||
Dqn_Str8 type_name = it.cgen_table_column[Dqn_CGenTableHeaderType_Name].string;
|
||||
Dqn_CppStructBlock(cpp, "%.*sStr8ToEnumResult", DQN_STR_FMT(type_name)) {
|
||||
Dqn_CppLine(cpp, "bool success;");
|
||||
Dqn_CppLine(cpp, "%.*s value;", DQN_STR_FMT(type_name));
|
||||
}
|
||||
|
||||
Dqn_CppFuncBlock(cpp, "%.*sStr8ToEnumResult %.*s_Str8ToEnum(Dqn_Str8 string)", DQN_STR_FMT(type_name), DQN_STR_FMT(type_name)) {
|
||||
Dqn_CppLine(cpp, "%.*sStr8ToEnumResult result = {};", DQN_STR_FMT(type_name));
|
||||
Dqn_CppForBlock(cpp, "Dqn_usize index = 0; !result.success && index < DQN_ARRAY_UCOUNT(g_%.*s_type_fields); index++", DQN_STR_FMT(type_name)) {
|
||||
Dqn_CppIfChain(cpp) {
|
||||
Dqn_CppLine(cpp, "Dqn_TypeField field = g_%.*s_type_fields[index];", DQN_STR_FMT(type_name));
|
||||
Dqn_CppIfOrElseIfBlock(cpp, "string == field.name") {
|
||||
Dqn_CppLine(cpp, "result.success = true;");
|
||||
Dqn_CppLine(cpp, "result.value = (%.*s)index;", DQN_STR_FMT(type_name));
|
||||
}
|
||||
}
|
||||
}
|
||||
Dqn_CppLine(cpp, "return result;");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -43,6 +43,7 @@ enum Dqn_CGenTableType
|
||||
Dqn_CGenTableType_CodeGenBuiltinTypes,
|
||||
Dqn_CGenTableType_CodeGenStruct,
|
||||
Dqn_CGenTableType_CodeGenEnum,
|
||||
Dqn_CGenTableType_Count,
|
||||
};
|
||||
|
||||
enum Dqn_CGenTableRowTagType
|
||||
@ -123,6 +124,7 @@ struct Dqn_CGen
|
||||
MD_Map table_map;
|
||||
Dqn_CGenTable *first_table;
|
||||
Dqn_CGenTable *last_table;
|
||||
Dqn_usize table_counts[Dqn_CGenTableType_Count];
|
||||
};
|
||||
|
||||
struct Dqn_CGenMapNodeToEnum
|
||||
@ -133,6 +135,7 @@ struct Dqn_CGenMapNodeToEnum
|
||||
|
||||
struct Dqn_CGenLookupTableIterator
|
||||
{
|
||||
Dqn_CGenTable *cgen_table;
|
||||
Dqn_CGenTableRow *cgen_table_row;
|
||||
Dqn_CGenTableColumn cgen_table_column[Dqn_CGenTableHeaderType_Count];
|
||||
Dqn_CGenTable *table;
|
||||
|
@ -400,11 +400,11 @@ template <typename T> T *Dqn_CArray_InsertArray(T *data, Dqn_usize *size, Dqn_us
|
||||
|
||||
Dqn_usize clamped_index = DQN_MIN(index, *size);
|
||||
if (clamped_index != *size) {
|
||||
char const *src = DQN_CAST(char *)(data + clamped_index);
|
||||
char const *dest = DQN_CAST(char *)(data + (clamped_index + count));
|
||||
char const *end = DQN_CAST(char *)(data + (*size));
|
||||
Dqn_usize bytes_to_move = end - src;
|
||||
DQN_MEMMOVE(DQN_CAST(void *)dest, src, bytes_to_move);
|
||||
char const *src = DQN_CAST(char *)(data + clamped_index);
|
||||
char const *dest = DQN_CAST(char *)(data + (clamped_index + count));
|
||||
char const *end = DQN_CAST(char *)(data + (*size));
|
||||
Dqn_usize bytes_to_move = end - src;
|
||||
DQN_MEMMOVE(DQN_CAST(void *) dest, src, bytes_to_move);
|
||||
}
|
||||
|
||||
result = data + clamped_index;
|
||||
@ -561,7 +561,7 @@ template <typename T> T *Dqn_VArray_InsertArray(Dqn_VArray<T> *array, Dqn_usize
|
||||
T *result = nullptr;
|
||||
if (!Dqn_VArray_IsValid(array))
|
||||
return result;
|
||||
if (Dqn_VArray_Reserve(array, count))
|
||||
if (Dqn_VArray_Reserve(array, array->size + count))
|
||||
result = Dqn_CArray_InsertArray(array->data, &array->size, array->max, index, items, count);
|
||||
return result;
|
||||
}
|
||||
|
200
dqn_helpers.cpp
200
dqn_helpers.cpp
@ -523,8 +523,7 @@ DQN_API uint32_t Dqn_Safe_SubU32(uint32_t a, uint32_t b)
|
||||
return result;
|
||||
}
|
||||
|
||||
// NOTE: Dqn_Safe_SaturateCastUSizeToI*
|
||||
// -----------------------------------------------------------------------------
|
||||
// NOTE: Dqn_Safe_SaturateCastUSizeToI* ////////////////////////////////////////////////////////////
|
||||
// INT*_MAX literals will be promoted to the type of uintmax_t as uintmax_t is
|
||||
// the highest possible rank (unsigned > signed).
|
||||
DQN_API int Dqn_Safe_SaturateCastUSizeToInt(Dqn_usize val)
|
||||
@ -557,8 +556,7 @@ DQN_API int64_t Dqn_Safe_SaturateCastUSizeToI64(Dqn_usize val)
|
||||
return result;
|
||||
}
|
||||
|
||||
// NOTE: Dqn_Safe_SaturateCastUSizeToU*
|
||||
// -----------------------------------------------------------------------------
|
||||
// NOTE: Dqn_Safe_SaturateCastUSizeToU* ////////////////////////////////////////////////////////////
|
||||
// Both operands are unsigned and the lowest rank operand will be promoted to
|
||||
// match the highest rank operand.
|
||||
DQN_API uint8_t Dqn_Safe_SaturateCastUSizeToU8(Dqn_usize val)
|
||||
@ -624,8 +622,7 @@ DQN_API uint32_t Dqn_Safe_SaturateCastU64ToU32(uint64_t val)
|
||||
return result;
|
||||
}
|
||||
|
||||
// NOTE: Dqn_Safe_SaturateCastISizeToI*
|
||||
// -----------------------------------------------------------------------------
|
||||
// NOTE: Dqn_Safe_SaturateCastISizeToI* ////////////////////////////////////////////////////////////
|
||||
// Both operands are signed so the lowest rank operand will be promoted to
|
||||
// match the highest rank operand.
|
||||
DQN_API int Dqn_Safe_SaturateCastISizeToInt(Dqn_isize val)
|
||||
@ -663,8 +660,7 @@ DQN_API int64_t Dqn_Safe_SaturateCastISizeToI64(Dqn_isize val)
|
||||
return result;
|
||||
}
|
||||
|
||||
// NOTE: Dqn_Safe_SaturateCastISizeToU*
|
||||
// -----------------------------------------------------------------------------
|
||||
// NOTE: Dqn_Safe_SaturateCastISizeToU* ////////////////////////////////////////////////////////////
|
||||
// If the value is a negative integer, we clamp to 0. Otherwise, we know that
|
||||
// the value is >=0, we can upcast safely to bounds check against the maximum
|
||||
// allowed value.
|
||||
@ -728,8 +724,7 @@ DQN_API uint64_t Dqn_Safe_SaturateCastISizeToU64(Dqn_isize val)
|
||||
return result;
|
||||
}
|
||||
|
||||
// NOTE: Dqn_Safe_SaturateCastI64To*
|
||||
// -----------------------------------------------------------------------------
|
||||
// NOTE: Dqn_Safe_SaturateCastI64To* ///////////////////////////////////////////////////////////////
|
||||
// Both operands are signed so the lowest rank operand will be promoted to
|
||||
// match the highest rank operand.
|
||||
DQN_API Dqn_isize Dqn_Safe_SaturateCastI64ToISize(int64_t val)
|
||||
@ -760,8 +755,79 @@ DQN_API int32_t Dqn_Safe_SaturateCastI64ToI32(int64_t val)
|
||||
return result;
|
||||
}
|
||||
|
||||
// NOTE: Dqn_Safe_SaturateCastIntTo*
|
||||
// -----------------------------------------------------------------------------
|
||||
DQN_API unsigned int Dqn_Safe_SaturateCastI64ToUInt(int64_t val)
|
||||
{
|
||||
unsigned int result = 0;
|
||||
if (DQN_CHECK(val >= DQN_CAST(int64_t) 0)) {
|
||||
if (DQN_CHECK(DQN_CAST(uintmax_t) val <= UINT_MAX))
|
||||
result = DQN_CAST(unsigned int) val;
|
||||
else
|
||||
result = UINT_MAX;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
DQN_API Dqn_isize Dqn_Safe_SaturateCastI64ToUSize(int64_t val)
|
||||
{
|
||||
Dqn_usize result = 0;
|
||||
if (DQN_CHECK(val >= DQN_CAST(int64_t) 0)) {
|
||||
if (DQN_CHECK(DQN_CAST(uintmax_t) val <= DQN_USIZE_MAX))
|
||||
result = DQN_CAST(Dqn_usize) val;
|
||||
else
|
||||
result = DQN_USIZE_MAX;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
DQN_API uint8_t Dqn_Safe_SaturateCastI64ToU8(int64_t val)
|
||||
{
|
||||
uint8_t result = 0;
|
||||
if (DQN_CHECK(val >= DQN_CAST(int64_t) 0)) {
|
||||
if (DQN_CHECK(DQN_CAST(uintmax_t) val <= UINT8_MAX))
|
||||
result = DQN_CAST(uint8_t) val;
|
||||
else
|
||||
result = UINT8_MAX;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
DQN_API uint16_t Dqn_Safe_SaturateCastI64ToU16(int64_t val)
|
||||
{
|
||||
uint16_t result = 0;
|
||||
if (DQN_CHECK(val >= DQN_CAST(int64_t) 0)) {
|
||||
if (DQN_CHECK(DQN_CAST(uintmax_t) val <= UINT16_MAX))
|
||||
result = DQN_CAST(uint16_t) val;
|
||||
else
|
||||
result = UINT16_MAX;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
DQN_API uint32_t Dqn_Safe_SaturateCastI64ToU32(int64_t val)
|
||||
{
|
||||
uint32_t result = 0;
|
||||
if (DQN_CHECK(val >= DQN_CAST(int64_t) 0)) {
|
||||
if (DQN_CHECK(DQN_CAST(uintmax_t) val <= UINT32_MAX))
|
||||
result = DQN_CAST(uint32_t) val;
|
||||
else
|
||||
result = UINT32_MAX;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
DQN_API uint64_t Dqn_Safe_SaturateCastI64ToU64(int64_t val)
|
||||
{
|
||||
uint64_t result = 0;
|
||||
if (DQN_CHECK(val >= DQN_CAST(int64_t) 0)) {
|
||||
if (DQN_CHECK(DQN_CAST(uintmax_t) val <= UINT64_MAX))
|
||||
result = DQN_CAST(uint64_t) val;
|
||||
else
|
||||
result = UINT64_MAX;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// NOTE: Dqn_Safe_SaturateCastIntTo* ///////////////////////////////////////////////////////////////
|
||||
DQN_API int8_t Dqn_Safe_SaturateCastIntToI8(int val)
|
||||
{
|
||||
DQN_CHECK(val >= INT8_MIN && val <= INT8_MAX);
|
||||
@ -1260,87 +1326,113 @@ void Dqn_Profiler_Dump(uint64_t tsc_per_second)
|
||||
// NOTE: [$JOBQ] Dqn_JobQueue ///////////////////////////////////////////////////////////////////////
|
||||
DQN_API Dqn_JobQueueSPMC Dqn_OS_JobQueueSPMCInit()
|
||||
{
|
||||
Dqn_JobQueueSPMC result = {};
|
||||
result.thread_wait_for_job_semaphore = Dqn_OS_SemaphoreInit(0 /*initial_count*/);
|
||||
result.wait_for_completion_semaphore = Dqn_OS_SemaphoreInit(0 /*initial_count*/);
|
||||
result.mutex = Dqn_OS_MutexInit();
|
||||
Dqn_JobQueueSPMC result = {};
|
||||
result.thread_wait_for_job_semaphore = Dqn_OS_SemaphoreInit(0 /*initial_count*/);
|
||||
result.wait_for_completion_semaphore = Dqn_OS_SemaphoreInit(0 /*initial_count*/);
|
||||
result.complete_queue_write_semaphore = Dqn_OS_SemaphoreInit(DQN_ARRAY_UCOUNT(result.complete_queue));
|
||||
result.mutex = Dqn_OS_MutexInit();
|
||||
return result;
|
||||
}
|
||||
|
||||
DQN_API bool Dqn_OS_JobQueueSPMCAddArray(Dqn_JobQueueSPMC *job_queue, Dqn_Job *jobs, uint32_t count)
|
||||
DQN_API bool Dqn_OS_JobQueueSPMCAddArray(Dqn_JobQueueSPMC *queue, Dqn_Job *jobs, uint32_t count)
|
||||
{
|
||||
if (!job_queue)
|
||||
if (!queue)
|
||||
return false;
|
||||
|
||||
uint32_t const pot_mask = DQN_ARRAY_UCOUNT(job_queue->jobs) - 1;
|
||||
uint32_t read_index = job_queue->read_index;
|
||||
uint32_t write_index = job_queue->write_index;
|
||||
uint32_t const pot_mask = DQN_ARRAY_UCOUNT(queue->jobs) - 1;
|
||||
uint32_t read_index = queue->read_index;
|
||||
uint32_t write_index = queue->write_index;
|
||||
uint32_t size = write_index - read_index;
|
||||
|
||||
if ((size + count) > DQN_ARRAY_UCOUNT(job_queue->jobs))
|
||||
if ((size + count) > DQN_ARRAY_UCOUNT(queue->jobs))
|
||||
return false;
|
||||
|
||||
for (size_t offset = 0; offset < count; offset++) {
|
||||
uint32_t wrapped_write_index = (write_index + offset) & pot_mask;
|
||||
job_queue->jobs[wrapped_write_index] = jobs[offset];
|
||||
queue->jobs[wrapped_write_index] = jobs[offset];
|
||||
}
|
||||
|
||||
Dqn_OS_MutexLock(&job_queue->mutex);
|
||||
job_queue->write_index += count;
|
||||
Dqn_OS_SemaphoreIncrement(&job_queue->thread_wait_for_job_semaphore, count);
|
||||
Dqn_OS_MutexUnlock(&job_queue->mutex);
|
||||
Dqn_OS_MutexLock(&queue->mutex);
|
||||
queue->write_index += count;
|
||||
Dqn_OS_SemaphoreIncrement(&queue->thread_wait_for_job_semaphore, count);
|
||||
Dqn_OS_MutexUnlock(&queue->mutex);
|
||||
return true;
|
||||
}
|
||||
|
||||
DQN_API bool Dqn_OS_JobQueueSPMCAdd(Dqn_JobQueueSPMC *job_queue, Dqn_Job job)
|
||||
DQN_API bool Dqn_OS_JobQueueSPMCAdd(Dqn_JobQueueSPMC *queue, Dqn_Job job)
|
||||
{
|
||||
bool result = Dqn_OS_JobQueueSPMCAddArray(job_queue, &job, 1);
|
||||
bool result = Dqn_OS_JobQueueSPMCAddArray(queue, &job, 1);
|
||||
return result;
|
||||
}
|
||||
|
||||
DQN_API int32_t Dqn_OS_JobQueueSPMCThread(Dqn_OSThread *thread)
|
||||
{
|
||||
Dqn_JobQueueSPMC *job_queue = DQN_CAST(Dqn_JobQueueSPMC *) thread->user_context;
|
||||
uint32_t const pot_mask = DQN_ARRAY_UCOUNT(job_queue->jobs) - 1;
|
||||
Dqn_JobQueueSPMC *queue = DQN_CAST(Dqn_JobQueueSPMC *) thread->user_context;
|
||||
uint32_t const pot_mask = DQN_ARRAY_UCOUNT(queue->jobs) - 1;
|
||||
static_assert(DQN_ARRAY_UCOUNT(queue->jobs) == DQN_ARRAY_UCOUNT(queue->complete_queue), "PoT mask is used to mask access to both arrays");
|
||||
|
||||
for (;;) {
|
||||
Dqn_OS_SemaphoreWait(&job_queue->thread_wait_for_job_semaphore, DQN_OS_SEMAPHORE_INFINITE_TIMEOUT);
|
||||
if (job_queue->quit)
|
||||
Dqn_OS_SemaphoreWait(&queue->thread_wait_for_job_semaphore, DQN_OS_SEMAPHORE_INFINITE_TIMEOUT);
|
||||
if (queue->quit)
|
||||
break;
|
||||
|
||||
DQN_ASSERT(job_queue->read_index != job_queue->write_index);
|
||||
DQN_ASSERT(queue->read_index != queue->write_index);
|
||||
|
||||
Dqn_OS_MutexLock(&job_queue->mutex);
|
||||
uint32_t wrapped_read_index = job_queue->read_index & pot_mask;
|
||||
Dqn_Job job = job_queue->jobs[wrapped_read_index];
|
||||
job_queue->read_index += 1;
|
||||
Dqn_OS_MutexUnlock(&job_queue->mutex);
|
||||
Dqn_OS_MutexLock(&queue->mutex);
|
||||
uint32_t wrapped_read_index = queue->read_index & pot_mask;
|
||||
Dqn_Job job = queue->jobs[wrapped_read_index];
|
||||
queue->read_index += 1;
|
||||
Dqn_OS_MutexUnlock(&queue->mutex);
|
||||
|
||||
job.func(job.user_context);
|
||||
Dqn_Arena_Deinit(job.arena);
|
||||
|
||||
Dqn_OS_MutexLock(&job_queue->mutex);
|
||||
job_queue->complete_index += 1;
|
||||
if (job_queue->complete_index == job_queue->write_index && job_queue->threads_waiting_for_completion) {
|
||||
Dqn_OS_SemaphoreIncrement(&job_queue->wait_for_completion_semaphore,
|
||||
job_queue->threads_waiting_for_completion);
|
||||
job_queue->threads_waiting_for_completion = 0;
|
||||
if (job.add_to_completion_queue) {
|
||||
Dqn_OS_SemaphoreWait(&queue->complete_queue_write_semaphore, DQN_OS_SEMAPHORE_INFINITE_TIMEOUT);
|
||||
Dqn_OS_MutexLock(&queue->mutex);
|
||||
queue->complete_queue[(queue->complete_write_index++ & pot_mask)] = job;
|
||||
Dqn_OS_MutexUnlock(&queue->mutex);
|
||||
Dqn_OS_SemaphoreIncrement(&queue->complete_queue_write_semaphore, 1);
|
||||
}
|
||||
Dqn_OS_MutexUnlock(&job_queue->mutex);
|
||||
|
||||
Dqn_OS_MutexLock(&queue->mutex);
|
||||
queue->finish_index += 1;
|
||||
if (queue->finish_index == queue->write_index && queue->threads_waiting_for_completion) {
|
||||
Dqn_OS_SemaphoreIncrement(&queue->wait_for_completion_semaphore,
|
||||
queue->threads_waiting_for_completion);
|
||||
queue->threads_waiting_for_completion = 0;
|
||||
}
|
||||
Dqn_OS_MutexUnlock(&queue->mutex);
|
||||
}
|
||||
|
||||
return job_queue->quit_exit_code;
|
||||
return queue->quit_exit_code;
|
||||
}
|
||||
|
||||
DQN_API void Dqn_OS_JobQueueSPMCWaitForCompletion(Dqn_JobQueueSPMC *job_queue)
|
||||
DQN_API void Dqn_OS_JobQueueSPMCWaitForCompletion(Dqn_JobQueueSPMC *queue)
|
||||
{
|
||||
Dqn_OS_MutexLock(&job_queue->mutex);
|
||||
if (job_queue->read_index == job_queue->write_index) {
|
||||
Dqn_OS_MutexUnlock(&job_queue->mutex);
|
||||
Dqn_OS_MutexLock(&queue->mutex);
|
||||
if (queue->read_index == queue->write_index) {
|
||||
Dqn_OS_MutexUnlock(&queue->mutex);
|
||||
return;
|
||||
}
|
||||
job_queue->threads_waiting_for_completion++;
|
||||
Dqn_OS_MutexUnlock(&job_queue->mutex);
|
||||
queue->threads_waiting_for_completion++;
|
||||
Dqn_OS_MutexUnlock(&queue->mutex);
|
||||
|
||||
Dqn_OS_SemaphoreWait(&job_queue->wait_for_completion_semaphore, DQN_OS_SEMAPHORE_INFINITE_TIMEOUT);
|
||||
Dqn_OS_SemaphoreWait(&queue->wait_for_completion_semaphore, DQN_OS_SEMAPHORE_INFINITE_TIMEOUT);
|
||||
}
|
||||
|
||||
DQN_API Dqn_usize Dqn_OS_JobQueueSPMCGetFinishedJobs(Dqn_JobQueueSPMC *queue, Dqn_Job *jobs, Dqn_usize jobs_size)
|
||||
{
|
||||
Dqn_usize result = 0;
|
||||
if (!queue || !jobs || jobs_size <= 0)
|
||||
return result;
|
||||
|
||||
uint32_t const pot_mask = DQN_ARRAY_UCOUNT(queue->jobs) - 1;
|
||||
Dqn_OS_MutexLock(&queue->mutex);
|
||||
while (queue->complete_read_index < queue->complete_write_index && result < jobs_size) {
|
||||
jobs[result++] = queue->complete_queue[(queue->complete_read_index++ & pot_mask)];
|
||||
}
|
||||
Dqn_OS_MutexUnlock(&queue->mutex);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -202,8 +202,10 @@ struct Dqn_Profiler
|
||||
typedef void (Dqn_JobQueueFunc)(void *user_context);
|
||||
struct Dqn_Job
|
||||
{
|
||||
bool add_to_completion_queue;
|
||||
Dqn_Arena *arena;
|
||||
Dqn_JobQueueFunc *func;
|
||||
uint32_t user_tag;
|
||||
void *user_context;
|
||||
};
|
||||
|
||||
@ -214,12 +216,17 @@ struct Dqn_JobQueueSPMC
|
||||
Dqn_OSSemaphore wait_for_completion_semaphore;
|
||||
uint32_t threads_waiting_for_completion;
|
||||
|
||||
Dqn_Job jobs[32];
|
||||
Dqn_Job jobs[64];
|
||||
Dqn_b32 quit;
|
||||
uint32_t quit_exit_code;
|
||||
uint32_t volatile read_index;
|
||||
uint32_t volatile complete_index;
|
||||
uint32_t volatile finish_index;
|
||||
uint32_t volatile write_index;
|
||||
|
||||
Dqn_OSSemaphore complete_queue_write_semaphore;
|
||||
Dqn_Job complete_queue[64];
|
||||
uint32_t volatile complete_read_index;
|
||||
uint32_t volatile complete_write_index;
|
||||
};
|
||||
|
||||
// NOTE: [$DLIB] Dqn_Library ///////////////////////////////////////////////////////////////////////
|
||||
@ -408,6 +415,13 @@ DQN_API int8_t Dqn_Safe_SaturateCastI64ToI8 (int64_t va
|
||||
DQN_API int16_t Dqn_Safe_SaturateCastI64ToI16 (int64_t val);
|
||||
DQN_API int32_t Dqn_Safe_SaturateCastI64ToI32 (int64_t val);
|
||||
|
||||
DQN_API unsigned int Dqn_Safe_SaturateCastI64ToUInt (int64_t val);
|
||||
DQN_API Dqn_isize Dqn_Safe_SaturateCastI64ToUSize (int64_t val);
|
||||
DQN_API uint8_t Dqn_Safe_SaturateCastI64ToU8 (int64_t val);
|
||||
DQN_API uint16_t Dqn_Safe_SaturateCastI64ToU16 (int64_t val);
|
||||
DQN_API uint32_t Dqn_Safe_SaturateCastI64ToU32 (int64_t val);
|
||||
DQN_API uint64_t Dqn_Safe_SaturateCastI64ToU64 (int64_t val);
|
||||
|
||||
DQN_API int8_t Dqn_Safe_SaturateCastIntToI8 (int val);
|
||||
DQN_API int16_t Dqn_Safe_SaturateCastIntToI16 (int val);
|
||||
DQN_API uint8_t Dqn_Safe_SaturateCastIntToU8 (int val);
|
||||
@ -433,10 +447,11 @@ DQN_API void Dqn_Profiler_Dump (uint64_t t
|
||||
|
||||
// NOTE: [$JOBQ] Dqn_JobQueue ///////////////////////////////////////////////////////////////////////
|
||||
DQN_API Dqn_JobQueueSPMC Dqn_OS_JobQueueSPMCInit ();
|
||||
DQN_API bool Dqn_OS_JobQueueSPMCAddArray (Dqn_JobQueueSPMC *job_queue, Dqn_Job *jobs, uint32_t count);
|
||||
DQN_API bool Dqn_OS_JobQueueSPMCAdd (Dqn_JobQueueSPMC *job_queue, Dqn_Job job);
|
||||
DQN_API void Dqn_OS_JobQueueSPMCWaitForCompletion (Dqn_JobQueueSPMC *job_queue);
|
||||
DQN_API bool Dqn_OS_JobQueueSPMCAddArray (Dqn_JobQueueSPMC *queue, Dqn_Job *jobs, uint32_t count);
|
||||
DQN_API bool Dqn_OS_JobQueueSPMCAdd (Dqn_JobQueueSPMC *queue, Dqn_Job job);
|
||||
DQN_API void Dqn_OS_JobQueueSPMCWaitForCompletion (Dqn_JobQueueSPMC *queue);
|
||||
DQN_API int32_t Dqn_OS_JobQueueSPMCThread (Dqn_OSThread *thread);
|
||||
DQN_API Dqn_usize Dqn_OS_JobQueueSPMCGetFinishedJobs (Dqn_JobQueueSPMC *queue, Dqn_Job *jobs, Dqn_usize jobs_size);
|
||||
|
||||
// NOTE: Dqn_Library ///////////////////////////////////////////////////////////////////////////////
|
||||
DQN_API Dqn_Library * Dqn_Library_Init (Dqn_LibraryOnInit on_init);
|
||||
|
3
dqn_os.h
3
dqn_os.h
@ -285,7 +285,6 @@ DQN_API bool Dqn_OS_SecureRNGBytes (void *buffer, uint
|
||||
DQN_API Dqn_Str8 Dqn_OS_EXEPath (Dqn_Arena *arena);
|
||||
DQN_API Dqn_Str8 Dqn_OS_EXEDir (Dqn_Arena *arena);
|
||||
DQN_API void Dqn_OS_SleepMs (Dqn_uint milliseconds);
|
||||
|
||||
// NOTE: Counters //////////////////////////////////////////////////////////////////////////////////
|
||||
DQN_API uint64_t Dqn_OS_PerfCounterNow ();
|
||||
DQN_API uint64_t Dqn_OS_PerfCounterFrequency();
|
||||
@ -345,7 +344,7 @@ DQN_API Dqn_Str8 Dqn_OS_PathConvertF (Dqn_Arena *arena
|
||||
#define Dqn_OS_PathBuild(allocator, fs_path) Dqn_OS_PathBuildWithSeparator(allocator, fs_path, Dqn_OSPathSeparatorString)
|
||||
|
||||
// NOTE: [$EXEC] Dqn_OSExec ////////////////////////////////////////////////////////////////////////
|
||||
DQN_API void Dqn_OS_Exit (uint32_t exit_code);
|
||||
DQN_API void Dqn_OS_Exit (int32_t exit_code);
|
||||
DQN_API Dqn_OSExecResult Dqn_OS_ExecWait (Dqn_OSExecAsyncHandle handle);
|
||||
DQN_API Dqn_OSExecAsyncHandle Dqn_OS_ExecAsync (Dqn_Slice<Dqn_Str8> cmd_line, Dqn_Str8 working_dir);
|
||||
DQN_API Dqn_OSExecResult Dqn_OS_Exec (Dqn_Slice<Dqn_Str8> cmd_line, Dqn_Str8 working_dir);
|
||||
|
@ -526,9 +526,9 @@ DQN_API void Dqn_OS_FileClose(Dqn_OSFile *file)
|
||||
#endif // !defined(DQN_NO_OS_FILE_API)
|
||||
|
||||
// NOTE: [$EXEC] Dqn_OSExec ////////////////////////////////////////////////////////////////////////
|
||||
DQN_API void Dqn_OS_Exit(uint32_t exit_code)
|
||||
DQN_API void Dqn_OS_Exit(int32_t exit_code)
|
||||
{
|
||||
exit(exit_code);
|
||||
exit(DQN_CAST(int)exit_code);
|
||||
}
|
||||
|
||||
DQN_API Dqn_OSExecResult Dqn_OS_ExecWait(Dqn_OSExecAsyncHandle handle)
|
||||
|
@ -545,9 +545,9 @@ DQN_API void Dqn_OS_FileClose(Dqn_OSFile *file)
|
||||
#endif // !defined(DQN_NO_OS_FILE_API)
|
||||
|
||||
// NOTE: [$EXEC] Dqn_OSExec ////////////////////////////////////////////////////////////////////////
|
||||
DQN_API void Dqn_OS_Exit(uint32_t exit_code)
|
||||
DQN_API void Dqn_OS_Exit(int32_t exit_code)
|
||||
{
|
||||
ExitProcess(exit_code);
|
||||
ExitProcess(DQN_CAST(UINT)exit_code);
|
||||
}
|
||||
|
||||
DQN_API Dqn_OSExecResult Dqn_OS_ExecWait(Dqn_OSExecAsyncHandle handle)
|
||||
|
@ -119,6 +119,12 @@ DQN_API Dqn_Str8 Dqn_Str8_Advance(Dqn_Str8 string, Dqn_usize amount)
|
||||
return result;
|
||||
}
|
||||
|
||||
DQN_API Dqn_Str8 Dqn_Str8_NextLine(Dqn_Str8 string)
|
||||
{
|
||||
Dqn_Str8 result = Dqn_Str8_BinarySplit(string, DQN_STR8("\n")).rhs;
|
||||
return result;
|
||||
}
|
||||
|
||||
DQN_API Dqn_Str8BinarySplitResult Dqn_Str8_BinarySplitArray(Dqn_Str8 string, Dqn_Str8 const *find, Dqn_usize find_size)
|
||||
{
|
||||
Dqn_Str8BinarySplitResult result = {};
|
||||
@ -839,6 +845,22 @@ DQN_API Dqn_Slice<Dqn_Str8> Dqn_Str8Builder_BuildSlice(Dqn_Str8Builder const *bu
|
||||
return result;
|
||||
}
|
||||
|
||||
DQN_API void Dqn_Str8Builder_PrintF(Dqn_Str8Builder const *builder)
|
||||
{
|
||||
for (Dqn_Str8Link *link = builder ? builder->head : nullptr; link; link = link->next)
|
||||
Dqn_Print(link->string);
|
||||
}
|
||||
|
||||
DQN_API void Dqn_Str8Builder_PrintLnF(Dqn_Str8Builder const *builder)
|
||||
{
|
||||
for (Dqn_Str8Link *link = builder ? builder->head : nullptr; link; link = link->next) {
|
||||
if (link->next) {
|
||||
Dqn_Print(link->string);
|
||||
} else {
|
||||
Dqn_Print_Ln(link->string);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: [$CHAR] Dqn_Char //////////////////////////////////////////////////////////////////////////
|
||||
DQN_API bool Dqn_Char_IsAlphabet(char ch)
|
||||
|
@ -152,6 +152,7 @@ DQN_API Dqn_Str8 Dqn_Str8_Copy
|
||||
|
||||
DQN_API Dqn_Str8 Dqn_Str8_Slice (Dqn_Str8 string, Dqn_usize offset, Dqn_usize size);
|
||||
DQN_API Dqn_Str8 Dqn_Str8_Advance (Dqn_Str8 string, Dqn_usize amount);
|
||||
DQN_API Dqn_Str8 Dqn_Str8_NextLine (Dqn_Str8 string);
|
||||
DQN_API Dqn_Str8BinarySplitResult Dqn_Str8_BinarySplitArray (Dqn_Str8 string, Dqn_Str8 const *find, Dqn_usize find_size);
|
||||
DQN_API Dqn_Str8BinarySplitResult Dqn_Str8_BinarySplit (Dqn_Str8 string, Dqn_Str8 find);
|
||||
DQN_API Dqn_Str8BinarySplitResult Dqn_Str8_BinarySplitReverseArray(Dqn_Str8 string, Dqn_Str8 const *find, Dqn_usize find_size);
|
||||
@ -206,6 +207,7 @@ DQN_API bool Dqn_Str8Builder_Ap
|
||||
DQN_API Dqn_Str8 Dqn_Str8Builder_Build (Dqn_Str8Builder const *builder, Dqn_Arena *arena);
|
||||
DQN_API Dqn_Str8 Dqn_Str8Builder_BuildCRT (Dqn_Str8Builder const *builder);
|
||||
DQN_API Dqn_Slice<Dqn_Str8> Dqn_Str8Builder_BuildSlice (Dqn_Str8Builder const *builder, Dqn_Arena *arena);
|
||||
DQN_API void Dqn_Str8Builder_PrintF (Dqn_Str8Builder const *builder);
|
||||
|
||||
// NOTE: [$FSTR] Dqn_FStr8 //////////////////////////////////////////////////////////////////////
|
||||
#if !defined(DQN_NO_FSTR8)
|
||||
|
@ -39,6 +39,7 @@ struct Dqn_TypeInfo
|
||||
{
|
||||
Dqn_Str8 name;
|
||||
Dqn_TypeKind kind;
|
||||
Dqn_usize size_of;
|
||||
Dqn_TypeField const *fields;
|
||||
uint16_t fields_count;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user