dqn: Add tests for perf counter, implement unix version

This commit is contained in:
doyle 2021-08-09 17:47:13 +10:00
parent 3f7ed280c7
commit 1651d7af4f
3 changed files with 69 additions and 15 deletions

40
Dqn.h
View File

@ -119,6 +119,8 @@
#if defined(_WIN32) #if defined(_WIN32)
#define DQN_OS_WIN32 #define DQN_OS_WIN32
#else
#define DQN_OS_UNIX
#endif #endif
#if defined(DQN_COMPILER_W32_MSVC) || defined(DQN_COMPILER_W32_CLANG) #if defined(DQN_COMPILER_W32_MSVC) || defined(DQN_COMPILER_W32_CLANG)
@ -1841,6 +1843,7 @@ DQN_API void Dqn_JsonWriter_U64(Dqn_JsonWriter *writer, Dqn_u64 value);
DQN_API void Dqn_JsonWriter_NamedF64(Dqn_JsonWriter *writer, Dqn_String key, Dqn_f64 value, int decimal_places = -1); DQN_API void Dqn_JsonWriter_NamedF64(Dqn_JsonWriter *writer, Dqn_String key, Dqn_f64 value, int decimal_places = -1);
DQN_API void Dqn_JsonWriter_F64(Dqn_JsonWriter *writer, Dqn_f64 value, int decimal_places = -1); DQN_API void Dqn_JsonWriter_F64(Dqn_JsonWriter *writer, Dqn_f64 value, int decimal_places = -1);
#if defined(DQN_OS_WIN32)
// ------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------------
// NOTE: Dqn_Win // NOTE: Dqn_Win
// ------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------------
@ -1863,6 +1866,7 @@ DQN_API Dqn_String Dqn_Win_CurrentDir (Dqn_ArenaAllocator *arena, D
DQN_API Dqn_StringW Dqn_Win_CurrentDirW (Dqn_ArenaAllocator *arena, Dqn_StringW suffix); DQN_API Dqn_StringW Dqn_Win_CurrentDirW (Dqn_ArenaAllocator *arena, Dqn_StringW suffix);
DQN_API Dqn_Array<Dqn_String> Dqn_Win_FolderFiles (Dqn_String path, Dqn_ArenaAllocator *arena, Dqn_ArenaAllocator *tmp_arena); DQN_API Dqn_Array<Dqn_String> Dqn_Win_FolderFiles (Dqn_String path, Dqn_ArenaAllocator *arena, Dqn_ArenaAllocator *tmp_arena);
DQN_API Dqn_Array<Dqn_StringW> Dqn_Win_FolderFilesW(Dqn_StringW path, Dqn_ArenaAllocator *arena); DQN_API Dqn_Array<Dqn_StringW> Dqn_Win_FolderFilesW(Dqn_StringW path, Dqn_ArenaAllocator *arena);
#endif // DQN_OS_WIN32
// ------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------------
// NOTE: Dqn_TimedBlock // NOTE: Dqn_TimedBlock
@ -3195,9 +3199,9 @@ DQN_API void Dqn_LogV(Dqn_LogType type,
func); func);
#else #else
fprintf(handle, fprintf(handle,
"[%s|%.*s|%05I64u|%.*s] ", "[%s|%.*s|%05llu|%.*s] ",
Dqn_LogTypeString[DQN_CAST(int) type], Dqn_LogTypeString[DQN_CAST(int) type],
file_name_len, DQN_CAST(int)file_name_len,
file_name, file_name,
line, line,
DQN_CAST(int)func_len, DQN_CAST(int)func_len,
@ -3295,18 +3299,18 @@ DQN_API char *Dqn_PointerMetadata_Init(void *ptr, Dqn_isize size, Dqn_u8 alignme
// [Raw Pointer] -> [Metadata Storage] [Aligned Pointer] // [Raw Pointer] -> [Metadata Storage] [Aligned Pointer]
// Offset is [0->Alignment-1] bytes from the Unaligned ptr. // Offset is [0->Alignment-1] bytes from the Unaligned ptr.
auto raw_ptr = DQN_CAST(uintptr_t) ptr; auto raw_ptr = DQN_CAST(Dqn_uintptr) ptr;
auto unaligned_ptr = raw_ptr + sizeof(Dqn_PointerMetadata); auto unaligned_ptr = raw_ptr + sizeof(Dqn_PointerMetadata);
auto result = DQN_CAST(uintptr_t) unaligned_ptr; auto result = DQN_CAST(Dqn_uintptr) unaligned_ptr;
if ((unaligned_ptr % alignment) > 0) if ((unaligned_ptr % alignment) > 0)
{ {
uintptr_t unaligned_to_aligned_offset = alignment - (unaligned_ptr % alignment); Dqn_uintptr unaligned_to_aligned_offset = alignment - (unaligned_ptr % alignment);
result += unaligned_to_aligned_offset; result += unaligned_to_aligned_offset;
} }
DQN_ASSERT(result % alignment == 0); DQN_ASSERT(result % alignment == 0);
DQN_ASSERT(result >= raw_ptr); DQN_ASSERT(result >= raw_ptr);
ptrdiff_t difference = DQN_CAST(ptrdiff_t)result - DQN_CAST(ptrdiff_t)raw_ptr; Dqn_intptr difference = DQN_CAST(Dqn_intptr)result - DQN_CAST(Dqn_intptr)raw_ptr;
DQN_ASSERT(difference <= DQN_CAST(Dqn_u8)-1); DQN_ASSERT(difference <= DQN_CAST(Dqn_u8)-1);
auto *metadata_ptr = DQN_CAST(Dqn_PointerMetadata *)(result - sizeof(Dqn_PointerMetadata)); auto *metadata_ptr = DQN_CAST(Dqn_PointerMetadata *)(result - sizeof(Dqn_PointerMetadata));
@ -5267,9 +5271,11 @@ DQN_FILE_SCOPE void Dqn_PerfCounter__Init()
DQN_API Dqn_f64 Dqn_PerfCounter_S(Dqn_u64 begin, Dqn_u64 end) DQN_API Dqn_f64 Dqn_PerfCounter_S(Dqn_u64 begin, Dqn_u64 end)
{ {
Dqn_PerfCounter__Init(); Dqn_PerfCounter__Init();
#if defined(DQN_OS_WIN32)
Dqn_u64 ticks = end - begin; Dqn_u64 ticks = end - begin;
#if defined(DQN_OS_WIN32)
Dqn_f64 result = ticks / DQN_CAST(Dqn_f64)dqn__lib.win32_qpc_frequency.QuadPart; Dqn_f64 result = ticks / DQN_CAST(Dqn_f64)dqn__lib.win32_qpc_frequency.QuadPart;
#else
Dqn_f64 result = ticks / 1'000'000'000;
#endif #endif
return result; return result;
} }
@ -5277,9 +5283,11 @@ DQN_API Dqn_f64 Dqn_PerfCounter_S(Dqn_u64 begin, Dqn_u64 end)
DQN_API Dqn_f64 Dqn_PerfCounter_Ms(Dqn_u64 begin, Dqn_u64 end) DQN_API Dqn_f64 Dqn_PerfCounter_Ms(Dqn_u64 begin, Dqn_u64 end)
{ {
Dqn_PerfCounter__Init(); Dqn_PerfCounter__Init();
#if defined(DQN_OS_WIN32)
Dqn_u64 ticks = end - begin; Dqn_u64 ticks = end - begin;
#if defined(DQN_OS_WIN32)
Dqn_f64 result = (ticks * 1'000) / DQN_CAST(Dqn_f64)dqn__lib.win32_qpc_frequency.QuadPart; Dqn_f64 result = (ticks * 1'000) / DQN_CAST(Dqn_f64)dqn__lib.win32_qpc_frequency.QuadPart;
#else
Dqn_f64 result = ticks / DQN_CAST(Dqn_f64)1'000'000;
#endif #endif
return result; return result;
} }
@ -5287,9 +5295,11 @@ DQN_API Dqn_f64 Dqn_PerfCounter_Ms(Dqn_u64 begin, Dqn_u64 end)
DQN_API Dqn_f64 Dqn_PerfCounter_MicroS(Dqn_u64 begin, Dqn_u64 end) DQN_API Dqn_f64 Dqn_PerfCounter_MicroS(Dqn_u64 begin, Dqn_u64 end)
{ {
Dqn_PerfCounter__Init(); Dqn_PerfCounter__Init();
#if defined(DQN_OS_WIN32)
Dqn_u64 ticks = end - begin; Dqn_u64 ticks = end - begin;
#if defined(DQN_OS_WIN32)
Dqn_f64 result = (ticks * 1'000'000) / DQN_CAST(Dqn_f64)dqn__lib.win32_qpc_frequency.QuadPart; Dqn_f64 result = (ticks * 1'000'000) / DQN_CAST(Dqn_f64)dqn__lib.win32_qpc_frequency.QuadPart;
#else
Dqn_f64 result = ticks / DQN_CAST(Dqn_f64)1'000;
#endif #endif
return result; return result;
} }
@ -5297,9 +5307,11 @@ DQN_API Dqn_f64 Dqn_PerfCounter_MicroS(Dqn_u64 begin, Dqn_u64 end)
DQN_API Dqn_f64 Dqn_PerfCounter_Ns(Dqn_u64 begin, Dqn_u64 end) DQN_API Dqn_f64 Dqn_PerfCounter_Ns(Dqn_u64 begin, Dqn_u64 end)
{ {
Dqn_PerfCounter__Init(); Dqn_PerfCounter__Init();
#if defined(DQN_OS_WIN32)
Dqn_u64 ticks = end - begin; Dqn_u64 ticks = end - begin;
#if defined(DQN_OS_WIN32)
Dqn_f64 result = (ticks * 1'000'000'000) / DQN_CAST(Dqn_f64)dqn__lib.win32_qpc_frequency.QuadPart; Dqn_f64 result = (ticks * 1'000'000'000) / DQN_CAST(Dqn_f64)dqn__lib.win32_qpc_frequency.QuadPart;
#else
Dqn_f64 result = ticks;
#endif #endif
return result; return result;
} }
@ -5313,9 +5325,12 @@ DQN_API Dqn_u64 Dqn_PerfCounter_Now()
(void)qpc_result; (void)qpc_result;
DQN_ASSERT_MSG(qpc_result, "MSDN says this can only fail when running on a version older than Windows XP"); DQN_ASSERT_MSG(qpc_result, "MSDN says this can only fail when running on a version older than Windows XP");
result = integer.QuadPart; result = integer.QuadPart;
#else
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC_RAW, &ts);
result = DQN_CAST(Dqn_u64)ts.tv_sec * 1'000'000'000 + DQN_CAST(Dqn_u64)ts.tv_nsec;
#endif #endif
DQN_ASSERT_MSG(result != 0, "Function not implemented");
return result; return result;
} }
@ -5566,7 +5581,7 @@ DQN_API void Dqn_JsonWriter_F64(Dqn_JsonWriter *writer, Dqn_f64 value, int decim
Dqn_JsonWriter_NamedF64(writer, DQN_STRING("") /*key*/, value, decimal_places); Dqn_JsonWriter_NamedF64(writer, DQN_STRING("") /*key*/, value, decimal_places);
} }
#if defined(DQN_OS_WIN32)
// ------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------------
// NOTE: Dqn_Win Implementation // NOTE: Dqn_Win Implementation
// ------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------------
@ -5784,6 +5799,7 @@ DQN_API Dqn_Array<Dqn_String> Dqn_Win_FolderFiles(Dqn_String path, Dqn_ArenaAllo
return result; return result;
} }
#endif
// ------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------------
// NOTE: Hashing - Dqn_FNV1A[32|64] // NOTE: Hashing - Dqn_FNV1A[32|64]

View File

@ -865,6 +865,38 @@ void Dqn_Test_Rect()
} }
} }
void Dqn_Test_PerfCounter()
{
Dqn_TestingState testing_state = {};
DQN_TEST_DECLARE_GROUP_SCOPED(testing_state, "Dqn_PerfCounter");
{
DQN_TEST_START_SCOPE(testing_state, "Dqn_PerfCounter_Now");
Dqn_u64 result = Dqn_PerfCounter_Now();
DQN_TEST_EXPECT(testing_state, result != 0);
}
{
DQN_TEST_START_SCOPE(testing_state, "Consecutive ticks are ordered");
Dqn_u64 a = Dqn_PerfCounter_Now();
Dqn_u64 b = Dqn_PerfCounter_Now();
DQN_TEST_EXPECT(testing_state, b > a);
}
{
DQN_TEST_START_SCOPE(testing_state, "Ticks to time are a correct order of magnitude");
Dqn_u64 a = Dqn_PerfCounter_Now();
Dqn_u64 b = Dqn_PerfCounter_Now();
Dqn_f64 s = Dqn_PerfCounter_S(a, b);
Dqn_f64 ms = Dqn_PerfCounter_Ms(a, b);
Dqn_f64 micro_s = Dqn_PerfCounter_MicroS(a, b);
Dqn_f64 ns = Dqn_PerfCounter_Ns(a, b);
DQN_TEST_EXPECT(testing_state, s < ms);
DQN_TEST_EXPECT(testing_state, ms < micro_s);
DQN_TEST_EXPECT(testing_state, micro_s < ns);
}
}
void Dqn_Test_Str() void Dqn_Test_Str()
{ {
Dqn_TestingState testing_state = {}; Dqn_TestingState testing_state = {};
@ -1252,6 +1284,7 @@ void Dqn_Test_RunSuite()
Dqn_Test_DSMap(); Dqn_Test_DSMap();
Dqn_Test_Map(); Dqn_Test_Map();
Dqn_Test_Rect(); Dqn_Test_Rect();
Dqn_Test_PerfCounter();
Dqn_Test_Str(); Dqn_Test_Str();
Dqn_Test_String(); Dqn_Test_String();
Dqn_Test_StringBuilder(); Dqn_Test_StringBuilder();

11
build.sh Normal file → Executable file
View File

@ -1,3 +1,8 @@
mkdir -p ../Bin/ #!/bin/bash
pushd ../Bin/
g++ ../Code/Dqn_Tests.cpp -D DQN_TEST_WITH_MAIN -std=c++17 -o Dqn_UnitTests code_dir=${PWD}
mkdir -p Build
pushd Build
g++ ${code_dir}/Dqn_Tests.cpp -D DQN_TEST_WITH_MAIN -std=c++17 -o Dqn_UnitTests
popd