DqnTimer unix implementation

This commit is contained in:
Doyle Thai 2017-06-22 18:10:44 +10:00
parent f464e869ec
commit 187fc14d02
2 changed files with 462 additions and 369 deletions

175
dqn.h
View File

@ -18,7 +18,7 @@
// You can search by #<entry> to jump straight to the section.
// The first match is the public API, the next matche(s) are the implementation
// API > Portable Code
// #Portable Code
// #DqnAssert Assertions
// #DqnMem Memory Allocation
// #DqnMemStack Memory Allocator, Push, Pop Style
@ -36,18 +36,19 @@
// #DqnWStr WStr Operations (WStr_Len() etc)
// #DqnRnd Random Number Generator (ints and floats)
// API > Cross Platform Code
// #XPlatform (Win32 & Unix)
// #DqnFile File I/O (Read, Write, Delete)
// #DqnDir Directory Querying
// #DqnTimer High Resolution Timer
// API > Win32 Only
// #DqnTime Platform High Resolution Timer
// #DqnLock Mutex Synchronisation
// #DqnAtomic Interlocks/Atomic Operations
// #DqnJobQueue Multithreaded Job Queue
// #DqnWin32 Common Win32 API Helpers
// #Platform
// - #Win32Platform
// - #DqnLock Mutex Synchronisation
// - #DqnAtomic Interlocks/Atomic Operations
// - #DqnJobQueue Multithreaded Job Queue
// - #DqnWin32 Common Win32 API Helpers
// API > External Code
// #External Code
// #DqnIni Simple INI Config File API (Public Domain lib by Mattias Gustavsson)
// #DqnSprintf Cross-platform Sprintf Implementation (Public Domain lib stb_sprintf)
@ -58,15 +59,15 @@
// a platform implementation, platform specific implementations in the portable
// layer will get activated.
#if (defined(_WIN32) || defined(_WIN64)) && defined(DQN_WIN32_IMPLEMENTATION)
#define DQN_PLATFORM_LAYER
#define DQN_XPLATFORM_LAYER
#define DQN_WIN32_PLATFORM
#elif defined(__linux__) && defined(DQN_UNIX_IMPLEMENTATION)
#define DQN_PLATFORM_LAYER
#define DQN_XPLATFORM_LAYER
#define DQN_UNIX_PLATFORM
#endif
////////////////////////////////////////////////////////////////////////////////
// Portable Layer
// #Portable Code
////////////////////////////////////////////////////////////////////////////////
#ifndef DQN_H
#define DQN_H
@ -893,26 +894,13 @@ DQN_FILE_SCOPE i32 DqnRnd_PCGRange(DqnRandPCGState *pcg, i32 min, i32 max);
#endif /* DQN_H */
////////////////////////////////////////////////////////////////////////////////
// Cross-Platform Layer
// #XPlatform (Win32 & Unix) Public API
////////////////////////////////////////////////////////////////////////////////
// Functions in the Cross Platform are guaranteed to be supported in both Unix
// and Win32
#ifdef DQN_PLATFORM_LAYER
#ifdef DQN_WIN32_PLATFORM
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#endif
#ifdef DQN_UNIX_PLATFORM
#include <sys/stat.h>
#include <stdio.h> // Basic File I/O // TODO(doyle): Syscall versions
#include <unistd.h> // unlink()
#include <dirent.h> // readdir()/opendir()/closedir()
#endif
#ifdef DQN_XPLATFORM_LAYER
////////////////////////////////////////////////////////////////////////////////
// Cross-Platform > #DqnFile Public API - File I/O
// XPlatform > #DqnFile Public API - File I/O
////////////////////////////////////////////////////////////////////////////////
enum DqnFilePermissionFlag
{
@ -964,6 +952,9 @@ DQN_FILE_SCOPE void DqnFile_Close(DqnFile *const file);
DQN_FILE_SCOPE bool DqnFile_Delete (const char *const path);
DQN_FILE_SCOPE bool DqnFile_DeleteW(const wchar_t *const path);
////////////////////////////////////////////////////////////////////////////////
// XPlatform > #DqnDir Public API - Directory Querying
////////////////////////////////////////////////////////////////////////////////
// numFiles: Pass in a pointer to a u32. The function fills it out with the number of entries.
// return: An array of strings of the files in the directory in UTF-8. The directory lisiting is
// allocated with malloc and must be freed using free() or the helper function DqnDir_ReadFree()
@ -971,20 +962,27 @@ DQN_FILE_SCOPE char **DqnDir_Read (const char *const dir, u32 *const numFiles
DQN_FILE_SCOPE void DqnDir_ReadFree(char **fileList, u32 numFiles);
////////////////////////////////////////////////////////////////////////////////
// Platform Layer
// XPlatform > #DqnTimer Public API - High Resolution Timer
////////////////////////////////////////////////////////////////////////////////
DQN_FILE_SCOPE f64 DqnTimer_NowInMs();
DQN_FILE_SCOPE f64 DqnTimer_NowInS ();
#endif // DQN_XPLATFORM_LAYER
////////////////////////////////////////////////////////////////////////////////
// #Platform Public API
////////////////////////////////////////////////////////////////////////////////
// Functions here are only available for the #defined sections (i.e. all functions in
// DQN_WIN32_PLATFORM only have a valid implementation in Win32.
////////////////////////////////////////////////////////////////////////////////
// #Win32Platform Public API
////////////////////////////////////////////////////////////////////////////////
#ifdef DQN_WIN32_PLATFORM
////////////////////////////////////////////////////////////////////////////////
// Platform > Win32 > #DqnTimer Public API - High Resolution Timer
////////////////////////////////////////////////////////////////////////////////
DQN_FILE_SCOPE f64 DqnTime_NowInS();
DQN_FILE_SCOPE f64 DqnTime_NowInMs();
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
////////////////////////////////////////////////////////////////////////////////
// Platform > Win32 > #DqnLock Public API - Mutex Synchronisation
// Win32Platform > #DqnLock Public API - Mutex Synchronisation
////////////////////////////////////////////////////////////////////////////////
typedef struct DqnLock
{
@ -997,14 +995,14 @@ DQN_FILE_SCOPE void DqnLock_Release(DqnLock *const lock);
DQN_FILE_SCOPE void DqnLock_Delete (DqnLock *const lock);
////////////////////////////////////////////////////////////////////////////////
// Platform > Win32 > #DqnAtomic Public API - Interlocks/Atomic Operations
// Win32Platform > #DqnAtomic Public API - Interlocks/Atomic Operations
////////////////////////////////////////////////////////////////////////////////
DQN_FILE_SCOPE u32 DqnAtomic_CompareSwap32(u32 volatile *dest, u32 swapVal, u32 compareVal);
DQN_FILE_SCOPE u32 DqnAtomic_Add32 (u32 volatile *src);
DQN_FILE_SCOPE u32 DqnAtomic_Sub32 (u32 volatile *src);
////////////////////////////////////////////////////////////////////////////////
// Platform > Win32 > #DqnJobQueue Public API - Multithreaded Job Queue
// Win32Platform > #DqnJobQueue Public API - Multithreaded Job Queue
////////////////////////////////////////////////////////////////////////////////
// DqnJobQueue is a platform abstracted "lockless" multithreaded work queue. It will create threads
// and assign threads to complete the job via the job "callback" using the "userData" supplied.
@ -1082,14 +1080,9 @@ DQN_FILE_SCOPE i32 DqnWin32_GetEXEDirectory(char *const buf, const u32 bufLen);
DQN_FILE_SCOPE void DqnWin32_GetNumThreadsAndCores(i32 *const numCores, i32 *const numThreadsPerCore);
#endif // DQN_WIN32_PLATFORM
#ifdef DQN_UNIX_PLATFORM
////////////////////////////////////////////////////////////////////////////////
// Platform > Unix
// #External Code
////////////////////////////////////////////////////////////////////////////////
#endif
#endif // DQN_PLATFORM_LAYER
#ifndef DQN_INI_H
#define DQN_INI_H
////////////////////////////////////////////////////////////////////////////////
@ -3657,6 +3650,9 @@ DQN_FILE_SCOPE i32 DqnRnd_PCGRange(DqnRandPCGState *pcg, i32 min, i32 max)
return min + value;
}
////////////////////////////////////////////////////////////////////////////////
// #External Code
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// #DqnSprintf Implementation - STB_Sprintf
////////////////////////////////////////////////////////////////////////////////
@ -5349,14 +5345,24 @@ void DqnIni_PropertyValueSet(DqnIni *ini, int section, int property,
#endif
#endif // DQN_IMPLEMENTATION
#if defined(DQN_XPLATFORM_LAYER)
////////////////////////////////////////////////////////////////////////////////
// Cross-Platform Layer
// #XPlatform (Win32 & Unix) Implementation
////////////////////////////////////////////////////////////////////////////////
// Functions in the Cross Platform are guaranteed to be supported in both Unix
// and Win32
#ifdef DQN_UNIX_PLATFORM
#include <sys/stat.h>
#include <sys/time.h>
#include <time.h>
#include <stdio.h> // Basic File I/O // TODO(doyle): Syscall versions
#include <unistd.h> // unlink()
#include <dirent.h> // readdir()/opendir()/closedir()
#endif
////////////////////////////////////////////////////////////////////////////////
// Cross-Platform > #DqnFileInternal Implementation
// XPlatform > #DqnFileInternal Implementation
////////////////////////////////////////////////////////////////////////////////
#ifdef DQN_WIN32_PLATFORM
FILE_SCOPE bool DqnFileInternal_Win32OpenW(const wchar_t *const path,
@ -5645,7 +5651,7 @@ DQN_FILE_SCOPE char **DqnDirInternal_PlatformRead(const char *const dir,
#endif // DQN_UNIX_PLATFORM
////////////////////////////////////////////////////////////////////////////////
// Cross-Platform > #DqnFile Implementation
// XPlatform > #DqnFile Implementation
////////////////////////////////////////////////////////////////////////////////
DQN_FILE_SCOPE
bool DqnFile_Open(const char *const path, DqnFile *const file,
@ -5674,7 +5680,7 @@ bool DqnFile_OpenW(const wchar_t *const path, DqnFile *const file, const u32 per
{
if (!file || !path) return false;
#ifdef DQN_WIN32_PLATFORM
#if defined(DQN_WIN32_PLATFORM)
return DqnFileInternal_Win32OpenW(path, file, permissionFlags, action);
#else
DQN_ASSERT(DQN_INVALID_CODE_PATH);
@ -5780,7 +5786,7 @@ DQN_FILE_SCOPE bool DqnFile_Delete(const char *const path)
// TODO(doyle): Logging
#if defined(DQN_WIN32_PLATFORM)
return DeleteFile(path);
return DeleteFileA(path);
#elif defined(DQN_UNIX_PLATFORM)
i32 result = unlink(path);
@ -5791,6 +5797,9 @@ DQN_FILE_SCOPE bool DqnFile_Delete(const char *const path)
#endif
}
////////////////////////////////////////////////////////////////////////////////
// XPlatform > #DqnDir Implementation
////////////////////////////////////////////////////////////////////////////////
DQN_FILE_SCOPE char **DqnDir_Read(const char *const dir, u32 *const numFiles)
{
char **result = DqnDirInternal_PlatformRead(dir, numFiles);
@ -5812,13 +5821,10 @@ DQN_FILE_SCOPE void DqnDir_ReadFree(char **fileList, u32 numFiles)
}
////////////////////////////////////////////////////////////////////////////////
// Platform Layer
// XPlatform > #DqnTimer Implementation
////////////////////////////////////////////////////////////////////////////////
#ifdef DQN_WIN32_PLATFORM
////////////////////////////////////////////////////////////////////////////////
// Platform > Win32 > #DqnTimer Implementation
////////////////////////////////////////////////////////////////////////////////
FILE_SCOPE f64 DqnTimeInternal_Win32QueryPerfCounterTimeInS()
#if defined (DQN_WIN32_PLATFORM)
FILE_SCOPE f64 DqnTimerInternal_Win32QueryPerfCounterTimeInMs()
{
LOCAL_PERSIST LARGE_INTEGER queryPerformanceFrequency = {0};
if (queryPerformanceFrequency.QuadPart == 0)
@ -5830,28 +5836,53 @@ FILE_SCOPE f64 DqnTimeInternal_Win32QueryPerfCounterTimeInS()
LARGE_INTEGER qpcResult;
QueryPerformanceCounter(&qpcResult);
// Convert to ms
f64 timestamp =
qpcResult.QuadPart / (f64)queryPerformanceFrequency.QuadPart;
// Convert to microseconds first then divide by ticks per second then to milliseconds
qpcResult.QuadPart *= 1000000;
f64 timestamp = qpcResult.QuadPart / (f64)queryPerformanceFrequency.QuadPart;
timestamp /= 1000.0f;
return timestamp;
}
#endif
f64 DqnTime_NowInS()
DQN_FILE_SCOPE f64 DqnTimer_NowInMs()
{
f64 result;
#ifdef DQN_WIN32_PLATFORM
result = DQN_MAX(DqnTimeInternal_Win32QueryPerfCounterTimeInS(), 0);
f64 result = 0;
#if defined(DQN_WIN32_PLATFORM)
result = DQN_MAX(DqnTimerInternal_Win32QueryPerfCounterTimeInMs(), 0);
#elif defined(DQN_UNIX_PLATFORM)
struct timespec timeSpec = {0};
if (clock_gettime(CLOCK_MONOTONIC, &timeSpec))
{
// TODO(doyle): Failed logging
DQN_ASSERT_HARD(DQN_INVALID_CODE_PATH);
}
else
{
printf("tv_nsec: %ld\n", timeSpec.tv_nsec);
result = ((f64)timeSpec.tv_sec * 1000.0f) + ((f64)timeSpec.tv_nsec / 100000.0f);
}
#else
result = 0;
DQN_ASSERT_MSG(DQN_INVALID_CODE_PATH, "Non Win32 path not implemented yet");
DQN_ASSERT_MSG(DQN_INVALID_CODE_PATH, "Non Unix/Win32 path not implemented yet");
#endif
return result;
};
f64 DqnTime_NowInMs() { return DqnTime_NowInS() * 1000.0f; }
DQN_FILE_SCOPE f64 DqnTimer_NowInS() { return DqnTimer_NowInMs() / 1000.0f; }
#endif // DQN_XPLATFORM_LAYER
////////////////////////////////////////////////////////////////////////////////
// Platform > Win32 > #DqnLock Implementation
// #Platform Implementation
////////////////////////////////////////////////////////////////////////////////
#ifdef DQN_WIN32_PLATFORM
////////////////////////////////////////////////////////////////////////////////
// #Win32Platform Implementation
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// Win32Platform > #DqnLock Implementation
////////////////////////////////////////////////////////////////////////////////
bool DqnLock_Init(DqnLock *const lock, const u32 spinCount)
{
@ -5896,7 +5927,7 @@ void DqnLock_Delete(DqnLock *const lock)
}
////////////////////////////////////////////////////////////////////////////////
// Platform > Win32 > #DqnAtomic Implementation
// Win32Platform > #DqnAtomic Implementation
////////////////////////////////////////////////////////////////////////////////
DQN_FILE_SCOPE u32 DqnAtomic_CompareSwap32(u32 volatile *dest, u32 swapVal, u32 compareVal)
{
@ -5936,7 +5967,7 @@ DQN_FILE_SCOPE u32 DqnAtomic_Sub32(u32 volatile *src)
}
////////////////////////////////////////////////////////////////////////////////
// Platform > Win32 > #DqnJobQueue Implementation
// Win32Platform > #DqnJobQueue Implementation
////////////////////////////////////////////////////////////////////////////////
typedef struct DqnJobQueue
{
@ -5953,7 +5984,7 @@ typedef struct DqnJobQueue
} DqnJobQueue;
////////////////////////////////////////////////////////////////////////////////
// Platform > Win32 > #DqnJobQueueInternal Implementation
// Win32Platform > #DqnJobQueueInternal Implementation
////////////////////////////////////////////////////////////////////////////////
size_t DQN_JOB_QUEUE_INTERNAL_THREAD_DEFAULT_STACK_SIZE = 0;
FILE_SCOPE u32 DqnJobQueueInternal_ThreadCreate(const size_t stackSize, void *threadCallback,
@ -5998,7 +6029,7 @@ FILE_SCOPE u32 DqnJobQueueInternal_ThreadCallback(void *threadParam)
}
////////////////////////////////////////////////////////////////////////////////
// Platform > Win32 > #DqnJobQueue Implementation
// Win32Platform > #DqnJobQueue Implementation
////////////////////////////////////////////////////////////////////////////////
DQN_FILE_SCOPE DqnJobQueue *DqnJobQueue_InitWithMem(const void *const mem, size_t *const memSize,
const u32 queueSize, const u32 numThreads)
@ -6095,7 +6126,7 @@ DQN_FILE_SCOPE bool DqnJobQueue_AllJobsComplete(DqnJobQueue *const queue)
}
////////////////////////////////////////////////////////////////////////////////
// Platform > Win32 > #DqnWin32 Implementation
// Win32Platform > #DqnWin32 Implementation
////////////////////////////////////////////////////////////////////////////////
DQN_FILE_SCOPE bool DqnWin32_UTF8ToWChar(const char *const in,
wchar_t *const out, const i32 outLen)
@ -6182,13 +6213,13 @@ DQN_FILE_SCOPE void DqnWin32_OutputDebugString(const char *const formatStr, ...)
}
va_end(argList);
OutputDebugString(str);
OutputDebugStringA(str);
}
DQN_FILE_SCOPE i32 DqnWin32_GetEXEDirectory(char *const buf, const u32 bufLen)
{
if (!buf || bufLen == 0) return 0;
u32 copiedLen = GetModuleFileName(NULL, buf, bufLen);
u32 copiedLen = GetModuleFileNameA(NULL, buf, bufLen);
if (copiedLen == bufLen) return -1;
// NOTE: Should always work if GetModuleFileName works and we're running an

View File

@ -15,8 +15,8 @@
#define HANDMADE_MATH_CPP_MODE
#include "tests/HandmadeMath.h"
#include <stdio.h>
#include <limits.h>
#include <stdio.h>
void HandmadeMathVerifyMat4(DqnMat4 dqnMat, hmm_mat4 hmmMat)
{
f32 *hmmMatf = (f32 *)&hmmMat;
@ -25,21 +25,23 @@ void HandmadeMathVerifyMat4(DqnMat4 dqnMat, hmm_mat4 hmmMat)
const u32 EXPECTED_SIZE = 16;
u32 totalSize = DQN_ARRAY_COUNT(dqnMat.e) * DQN_ARRAY_COUNT(dqnMat.e[0]);
DQN_ASSERT(totalSize == EXPECTED_SIZE);
DQN_ASSERT(totalSize == (DQN_ARRAY_COUNT(hmmMat.Elements) * DQN_ARRAY_COUNT(hmmMat.Elements[0])));
DQN_ASSERT(totalSize ==
(DQN_ARRAY_COUNT(hmmMat.Elements) * DQN_ARRAY_COUNT(hmmMat.Elements[0])));
for (u32 i = 0; i < EXPECTED_SIZE; i++)
{
const f32 EPSILON = 0.001f;
f32 diff = hmmMatf[i] - dqnMatf[i];
diff = DQN_ABS(diff);
DQN_ASSERT_MSG(diff < EPSILON, "hmmMatf[%d]: %f, dqnMatf[%d]: %f\n", i,
hmmMatf[i], i, dqnMatf[i]);
DQN_ASSERT_MSG(diff < EPSILON, "hmmMatf[%d]: %f, dqnMatf[%d]: %f\n", i, hmmMatf[i], i,
dqnMatf[i]);
}
}
void HandmadeMathTest()
{
// Test Perspective/Projection matrix values
if (1)
{
f32 aspectRatio = 1;
DqnMat4 dqnPerspective = DqnMat4_Perspective(90, aspectRatio, 100, 1000);
@ -50,6 +52,7 @@ void HandmadeMathTest()
}
// Test Mat4 translate * scale
if (1)
{
hmm_vec3 hmmVec = HMM_Vec3i(1, 2, 3);
DqnV3 dqnVec = DqnV3_3i(1, 2, 3);
@ -77,8 +80,8 @@ void HandmadeMathTest()
hmm_mat4 hmmTSMatrix = HMM_MultiplyMat4(hmmTranslate, hmmScale);
HandmadeMathVerifyMat4(dqnTSMatrix, hmmTSMatrix);
// Test Mat4 * MulV4
if (1)
{
DqnV4 dqnV4 = DqnV4_4f(1, 2, 3, 4);
hmm_vec4 hmmV4 = HMM_Vec4(1, 2, 3, 4);
@ -91,14 +94,14 @@ void HandmadeMathTest()
DQN_ASSERT(dqnResult.z == hmmResult.Z);
DQN_ASSERT(dqnResult.w == hmmResult.W);
printf(
"HandmadeMathTest(): Mat4 * MulV4: Completed successfully\n");
printf("HandmadeMathTest(): Mat4 * MulV4: Completed successfully\n");
}
printf("HandmadeMathTest(): Translate/Scale/Rotate Mat4_Mul: Completed successfully\n");
}
// Test LookAt/Camera/View matrix returns same results
if (1)
{
DqnMat4 dqnViewMatrix = DqnMat4_LookAt(DqnV3_3f(4, 3, 3), DqnV3_1f(0), DqnV3_3f(0, 1, 0));
hmm_mat4 hmmViewMatrix =
@ -107,12 +110,13 @@ void HandmadeMathTest()
HandmadeMathVerifyMat4(dqnViewMatrix, hmmViewMatrix);
printf("HandmadeMathTest(): LookAt: Completed successfully\n");
}
}
void StringsTest()
{
{ // Char Checks
// Char Checks
if (1)
{
DQN_ASSERT(DqnChar_IsAlpha('a') == true);
DQN_ASSERT(DqnChar_IsAlpha('A') == true);
DQN_ASSERT(DqnChar_IsAlpha('0') == false);
@ -146,12 +150,15 @@ void StringsTest()
}
// String Checks
if (1)
{
// strcmp
if (1)
{
const char *const a = "str_a";
// Check simple compares
if (1)
{
DQN_ASSERT(DqnStr_Cmp(a, "str_a") == +0);
DQN_ASSERT(DqnStr_Cmp(a, "str_b") == -1);
@ -164,6 +171,7 @@ void StringsTest()
}
// Check ops against null
if (1)
{
DQN_ASSERT(DqnStr_Cmp(NULL, NULL) != +0);
DQN_ASSERT(DqnStr_Cmp(a, NULL) != +0);
@ -174,6 +182,7 @@ void StringsTest()
}
// strlen
if (1)
{
const char *const a = "str_a";
DQN_ASSERT(DqnStr_Len(a) == 5);
@ -190,11 +199,14 @@ void StringsTest()
}
// strncpy
if (1)
{
if (1)
{
const char *const a = "str_a";
char b[10] = {};
// Check copy into empty array
if (1)
{
char *result = DqnStr_Copy(b, a, DqnStr_Len(a));
DQN_ASSERT(DqnStr_Cmp(b, "str_a") == 0);
@ -204,6 +216,7 @@ void StringsTest()
}
// Check copy into array offset, overlap with old results
if (1)
{
char *newResult = DqnStr_Copy(&b[1], a, DqnStr_Len(a));
DQN_ASSERT(DqnStr_Cmp(newResult, "str_a") == 0);
@ -219,8 +232,10 @@ void StringsTest()
}
// StrReverse
if (1)
{
// Basic reverse operations
if (1)
{
char a[] = "aba";
DQN_ASSERT(DqnStr_Reverse(a, DqnStr_Len(a)) == true);
@ -240,6 +255,7 @@ void StringsTest()
}
// Try reverse empty string
if (1)
{
char a[] = "";
DQN_ASSERT(DqnStr_Reverse(a, DqnStr_Len(a)) == true);
@ -247,6 +263,7 @@ void StringsTest()
}
// Try reverse single char string
if (1)
{
char a[] = "a";
DQN_ASSERT(DqnStr_Reverse(a, DqnStr_Len(a)) == true);
@ -256,13 +273,13 @@ void StringsTest()
DQN_ASSERT(DqnStr_Cmp(a, "a") == 0);
}
printf(
"StringsTest(): StrReverse: Completed successfully\n");
printf("StringsTest(): StrReverse: Completed successfully\n");
}
// const u64 LARGEST_NUM = (u64)-1;
const i64 SMALLEST_NUM = LLONG_MIN;
// StrToI64
if (1)
{
const char *const a = "123";
DQN_ASSERT(Dqn_StrToI64(a, DqnStr_Len(a)) == 123);
@ -290,6 +307,7 @@ void StringsTest()
}
// i64 to str
if (1)
{
char a[DQN_64BIT_NUM_MAX_STR_SIZE] = {};
Dqn_I64ToStr(+100, a, DQN_ARRAY_COUNT(a));
@ -318,6 +336,7 @@ void StringsTest()
}
// StrToF32
if (1)
{
const f32 EPSILON = 0.001f;
const char a[] = "-0.66248";
@ -394,24 +413,25 @@ void StringsTest()
printf("StringsTest(): StrToF32: Completed successfully\n");
}
if (1)
{
if (1)
{
const char *const a = "Microsoft";
const char *const b = "icro";
i32 lenA = DqnStr_Len(a);
i32 lenB = DqnStr_Len(b);
DQN_ASSERT(DqnStr_HasSubstring(a, lenA, b, lenB) == true);
DQN_ASSERT(DqnStr_HasSubstring(a, lenA, "iro",
DqnStr_Len("iro")) == false);
DQN_ASSERT(DqnStr_HasSubstring(a, lenA, "iro", DqnStr_Len("iro")) == false);
DQN_ASSERT(DqnStr_HasSubstring(b, lenB, a, lenA) == false);
DQN_ASSERT(DqnStr_HasSubstring("iro", DqnStr_Len("iro"), a,
lenA) == false);
DQN_ASSERT(DqnStr_HasSubstring("iro", DqnStr_Len("iro"), a, lenA) == false);
DQN_ASSERT(DqnStr_HasSubstring("", 0, "iro", 4) == false);
DQN_ASSERT(DqnStr_HasSubstring("", 0, "", 0) == false);
DQN_ASSERT(DqnStr_HasSubstring(NULL, 0, NULL, 0) == false);
}
if (1)
{
const char *const a = "Micro";
const char *const b = "irob";
@ -425,8 +445,10 @@ void StringsTest()
}
// UCS <-> UTF8 Checks
if (1)
{
// Test ascii characters
if (1)
{
u32 codepoint = '@';
u32 string[1] = {};
@ -441,6 +463,7 @@ void StringsTest()
}
// Test 2 byte characters
if (1)
{
u32 codepoint = 0x278;
u32 string[1] = {};
@ -455,6 +478,7 @@ void StringsTest()
}
// Test 3 byte characters
if (1)
{
u32 codepoint = 0x0A0A;
u32 string[1] = {};
@ -469,6 +493,7 @@ void StringsTest()
}
// Test 4 byte characters
if (1)
{
u32 codepoint = 0x10912;
u32 string[1] = {};
@ -482,6 +507,7 @@ void StringsTest()
DQN_ASSERT(bytesUsed == 4);
}
if (1)
{
u32 codepoint = 0x10912;
u32 bytesUsed = Dqn_UCSToUTF8(NULL, codepoint);
@ -497,26 +523,35 @@ void StringsTest()
printf("StringsTest(): Completed successfully\n");
}
#ifdef DQN_WIN32_IMPLEMENTATION
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
void OtherTest()
{
{ // Test Win32 Sleep
// NOTE: Win32 Sleep is not granular to a certain point so sleep excessively
u32 sleepInMs = 1000;
f64 startInMs = DqnTime_NowInMs();
Sleep(sleepInMs);
f64 endInMs = DqnTime_NowInMs();
DQN_ASSERT(startInMs < endInMs);
if (1)
{
#if defined(DQN_UNIX_PLATFORM)
f64 startInS = DqnTimer_NowInS();
u32 sleepTimeInS = 1;
sleep(sleepTimeInS);
f64 endInS = DqnTimer_NowInS();
printf("start: %f, end: %f\n", startInS, endInS);
DQN_ASSERT((startInS + sleepTimeInS) <= endInS);
#elif defined(DQN_WIN32_PLATFORM)
f64 startInMs = DqnTimer_NowInMs();
u32 sleepTimeInMs = 1000;
Sleep(sleepTimeInMs);
f64 endInMs = DqnTimer_NowInMs();
printf("start: %f, end: %f\n", startInMs, endInMs);
DQN_ASSERT((startInMs + sleepTimeInMs) <= endInMs);
#endif
printf("OtherTest(): TimeNow: Completed successfully\n");
}
printf("OtherTest(): Completed successfully\n");
}
#endif
void RandomTest() {
void RandomTest()
{
DqnRandPCGState pcg;
DqnRnd_PCGInit(&pcg);
@ -537,7 +572,9 @@ void RandomTest() {
void MathTest()
{
if (1)
{ // Lerp
if (1)
{
f32 start = 10;
f32 t = 0.5f;
@ -545,6 +582,7 @@ void MathTest()
DQN_ASSERT(DqnMath_Lerp(start, t, end) == 15);
}
if (1)
{
f32 start = 10;
f32 t = 2.0f;
@ -555,6 +593,7 @@ void MathTest()
printf("MathTest(): Lerp: Completed successfully\n");
}
if (1)
{ // sqrtf
DQN_ASSERT(DqnMath_Sqrtf(4.0f) == 2.0f);
printf("MathTest(): Sqrtf: Completed successfully\n");
@ -565,9 +604,11 @@ void MathTest()
void VecTest()
{
if (1)
{ // V2
// V2 Creating
if (1)
{
DqnV2 vec = DqnV2_2f(5.5f, 5.0f);
DQN_ASSERT(vec.x == 5.5f && vec.y == 5.0f);
@ -575,6 +616,7 @@ void VecTest()
}
// V2 with 2 integers
if (1)
{
DqnV2 vec = DqnV2_2i(3, 5);
DQN_ASSERT(vec.x == 3 && vec.y == 5.0f);
@ -582,6 +624,7 @@ void VecTest()
}
// V2 Arithmetic
if (1)
{
DqnV2 vecA = DqnV2_2f(5, 10);
DqnV2 vecB = DqnV2_2i(2, 3);
@ -606,6 +649,7 @@ void VecTest()
}
// Test operator overloading
if (1)
{
DqnV2 vecA = DqnV2_2f(5, 10);
DqnV2 vecB = DqnV2_2i(2, 3);
@ -633,6 +677,7 @@ void VecTest()
}
// V2 Properties
if (1)
{
const f32 EPSILON = 0.001f;
DqnV2 a = DqnV2_2f(0, 0);
@ -649,8 +694,10 @@ void VecTest()
f32 normY = b.y / 5.0f;
f32 diffNormX = normalised.x - normX;
f32 diffNormY = normalised.y - normY;
DQN_ASSERT_MSG(diffNormX < EPSILON, "normalised.x: %f, normX: %f\n", normalised.x, normX);
DQN_ASSERT_MSG(diffNormY < EPSILON, "normalised.y: %f, normY: %f\n", normalised.y, normY);
DQN_ASSERT_MSG(diffNormX < EPSILON, "normalised.x: %f, normX: %f\n", normalised.x,
normX);
DQN_ASSERT_MSG(diffNormY < EPSILON, "normalised.y: %f, normY: %f\n", normalised.y,
normY);
DqnV2 c = DqnV2_2f(3.5f, 8.0f);
DQN_ASSERT(DqnV2_Overlaps(b, c) == true);
@ -660,6 +707,7 @@ void VecTest()
DQN_ASSERT(DqnV2_Dot(c, d) == 0);
}
if (1)
{ // constrain_to_ratio
DqnV2 ratio = DqnV2_2f(16, 9);
DqnV2 dim = DqnV2_2f(2000, 1080);
@ -670,9 +718,11 @@ void VecTest()
printf("VecTest(): Vec2: Completed successfully\n");
}
if (1)
{ // V3
// V3i Creating
if (1)
{
DqnV3 vec = DqnV3_3f(5.5f, 5.0f, 5.875f);
DQN_ASSERT(vec.x == 5.5f && vec.y == 5.0f && vec.z == 5.875f);
@ -680,6 +730,7 @@ void VecTest()
}
// V3i Creating
if (1)
{
DqnV3 vec = DqnV3_3i(3, 4, 5);
DQN_ASSERT(vec.x == 3 && vec.y == 4 && vec.z == 5);
@ -687,6 +738,7 @@ void VecTest()
}
// V3 Arithmetic
if (1)
{
DqnV3 vecA = DqnV3_3f(5, 10, 15);
DqnV3 vecB = DqnV3_3f(2, 3, 6);
@ -713,6 +765,7 @@ void VecTest()
DQN_ASSERT(DqnV3_Equals(cross, DqnV3_3f(15, 0, -5)) == true);
}
if (1)
{
DqnV3 vecA = DqnV3_3f(5, 10, 15);
DqnV3 vecB = DqnV3_3f(2, 3, 6);
@ -742,9 +795,11 @@ void VecTest()
printf("VecTest(): Vec3: Completed successfully\n");
}
if (1)
{ // V4
// V4 Creating
if (1)
{
DqnV4 vec = DqnV4_4f(5.5f, 5.0f, 5.875f, 5.928f);
DQN_ASSERT(vec.x == 5.5f && vec.y == 5.0f && vec.z == 5.875f && vec.w == 5.928f);
@ -752,6 +807,7 @@ void VecTest()
}
// V4i Creating
if (1)
{
DqnV4 vec = DqnV4_4i(3, 4, 5, 6);
DQN_ASSERT(vec.x == 3 && vec.y == 4 && vec.z == 5 && vec.w == 6);
@ -759,6 +815,7 @@ void VecTest()
}
// V4 Arithmetic
if (1)
{
DqnV4 vecA = DqnV4_4f(5, 10, 15, 20);
DqnV4 vecB = DqnV4_4i(2, 3, 6, 8);
@ -782,6 +839,7 @@ void VecTest()
DQN_ASSERT(dotResult == 107);
}
if (1)
{
DqnV4 vecA = DqnV4_4f(5, 10, 15, 20);
DqnV4 vecB = DqnV4_4i(2, 3, 6, 8);
@ -812,8 +870,10 @@ void VecTest()
}
// Rect
if (1)
{
// Test rect init functions
if (1)
{
DqnRect rect4f = DqnRect_4f(1.1f, 2.2f, 3.3f, 4.4f);
DqnRect rect4i = DqnRect_4i(1, 2, 3, 4);
@ -829,11 +889,12 @@ void VecTest()
}
// Test rect get size function
if (1)
{
// Test float rect
if (1)
{
DqnRect rect =
DqnRect_Init(DqnV2_2f(-10, -10), DqnV2_2f(20, 20));
DqnRect rect = DqnRect_Init(DqnV2_2f(-10, -10), DqnV2_2f(20, 20));
f32 width, height;
DqnRect_GetSize2f(rect, &width, &height);
@ -845,9 +906,9 @@ void VecTest()
}
// Test rect with float values and GetSize as 2 integers
if (1)
{
DqnRect rect = DqnRect_Init(DqnV2_2f(-10.5f, -10.5f),
DqnV2_2f(20.5f, 20.5f));
DqnRect rect = DqnRect_Init(DqnV2_2f(-10.5f, -10.5f), DqnV2_2f(20.5f, 20.5f));
i32 width, height;
DqnRect_GetSize2i(rect, &width, &height);
DQN_ASSERT(width == 20);
@ -867,12 +928,14 @@ void VecTest()
DQN_ASSERT(clipResult.max.x == 10 && clipResult.max.y == 10);
// Test shifting rect
if (1)
{
DqnRect shiftedRect = DqnRect_Move(rect, DqnV2_2f(10, 0));
DQN_ASSERT(DqnV2_Equals(shiftedRect.min, DqnV2_2f(0, -10)));
DQN_ASSERT(DqnV2_Equals(shiftedRect.max, DqnV2_2f(20, 10)));
// Ensure dimensions have remained the same
if (1)
{
f32 width, height;
DqnRect_GetSize2f(shiftedRect, &width, &height);
@ -884,6 +947,7 @@ void VecTest()
}
// Test rect contains p
if (1)
{
DqnV2 inP = DqnV2_2f(5, 5);
DqnV2 outP = DqnV2_2f(100, 100);
@ -900,12 +964,14 @@ void VecTest()
void ArrayTestMemAPIInternal(DqnArray<DqnV2> *array, DqnMemAPI memAPI)
{
if (1)
{
DQN_ASSERT(DqnArray_Init(array, 1, memAPI));
DQN_ASSERT(array->capacity == 1);
DQN_ASSERT(array->count == 0);
// Test basic insert
if (1)
{
DqnV2 va = DqnV2_2f(5, 10);
DQN_ASSERT(DqnArray_Push(array, va));
@ -918,6 +984,7 @@ void ArrayTestMemAPIInternal(DqnArray<DqnV2> *array, DqnMemAPI memAPI)
}
// Test array resizing and freeing
if (1)
{
DqnV2 va = DqnV2_2f(10, 15);
DQN_ASSERT(DqnArray_Push(array, va));
@ -976,6 +1043,7 @@ void ArrayTestMemAPIInternal(DqnArray<DqnV2> *array, DqnMemAPI memAPI)
}
DQN_ASSERT(DqnArray_Free(array));
if (1)
{
DQN_ASSERT(DqnArray_Init(array, 1, memAPI));
DQN_ASSERT(array->capacity == 1);
@ -983,6 +1051,7 @@ void ArrayTestMemAPIInternal(DqnArray<DqnV2> *array, DqnMemAPI memAPI)
}
DQN_ASSERT(DqnArray_Free(array));
if (1)
{
DqnV2 a = DqnV2_2f(1, 2);
DqnV2 b = DqnV2_2f(3, 4);
@ -1027,10 +1096,10 @@ void ArrayTestMemAPIInternal(DqnArray<DqnV2> *array, DqnMemAPI memAPI)
DQN_ASSERT(DqnArray_Clear(array));
DQN_ASSERT(array->capacity == 16);
DQN_ASSERT(array->count == 0);
}
DQN_ASSERT(DqnArray_Free(array));
if (1)
{
DqnV2 a = DqnV2_2f(1, 2);
DqnV2 b = DqnV2_2f(3, 4);
@ -1066,7 +1135,6 @@ void ArrayTestMemAPIInternal(DqnArray<DqnV2> *array, DqnMemAPI memAPI)
}
DQN_ASSERT(DqnArray_Free(array));
printf("ArrayTestMemAPIInternal(): Completed successfully\n");
}
void ArrayTest()
@ -1079,6 +1147,7 @@ void ArrayTest()
void MemStackTest()
{
// Test over allocation, alignments, temp regions
if (1)
{
size_t allocSize = DQN_KILOBYTE(1);
DqnMemStack stack = {};
@ -1096,8 +1165,7 @@ void MemStackTest()
DQN_ASSERT(resultAddrA % ALIGNMENT == 0);
DQN_ASSERT(stack.block && stack.block->memory);
DQN_ASSERT(stack.block->size == allocSize);
DQN_ASSERT(stack.block->used >= sizeA + 0 &&
stack.block->used <= sizeA + 3);
DQN_ASSERT(stack.block->used >= sizeA + 0 && stack.block->used <= sizeA + 3);
DQN_ASSERT(stack.byteAlign == ALIGNMENT);
DQN_ASSERT(resultA);
u8 *ptrA = (u8 *)resultA;
@ -1116,8 +1184,7 @@ void MemStackTest()
// Since we alignment the pointers we return they can be within 0-3
// bytes of what we expect and since this is in a new block as well used
// will reflect just this allocation.
DQN_ASSERT(stack.block->used >= sizeB + 0 &&
stack.block->used <= sizeB + 3);
DQN_ASSERT(stack.block->used >= sizeB + 0 && stack.block->used <= sizeB + 3);
DQN_ASSERT(resultB);
u8 *ptrB = (u8 *)resultB;
for (u32 i = 0; i < sizeB; i++)
@ -1139,8 +1206,7 @@ void MemStackTest()
u64 resultAddrC = *((u64 *)resultC);
DQN_ASSERT(resultAddrC % ALIGNMENT == 0);
DQN_ASSERT(stack.block != blockB && stack.block != blockA);
DQN_ASSERT(stack.block->used >= sizeC + 0 &&
stack.block->used <= sizeC + 3);
DQN_ASSERT(stack.block->used >= sizeC + 0 && stack.block->used <= sizeC + 3);
DQN_ASSERT(stack.tempRegionCount == 1);
DQN_ASSERT(stack.byteAlign == ALIGNMENT);
@ -1166,8 +1232,7 @@ void MemStackTest()
DqnMemStackTempRegion_End(tempBuffer);
DQN_ASSERT(stack.block && stack.block->memory);
DQN_ASSERT(stack.block->size == sizeB);
DQN_ASSERT(stack.block->used >= sizeB + 0 &&
stack.block->used <= sizeB + 3);
DQN_ASSERT(stack.block->used >= sizeB + 0 && stack.block->used <= sizeB + 3);
DQN_ASSERT(stack.tempRegionCount == 0);
DQN_ASSERT(resultB);
@ -1194,15 +1259,14 @@ void MemStackTest()
}
// Test stack with fixed memory does not allocate more
if (1)
{
u8 memory[DQN_KILOBYTE(1)] = {};
DqnMemStack stack = {};
const u32 ALIGNMENT = 4;
DqnMemStack_InitWithFixedMem(&stack, memory, DQN_ARRAY_COUNT(memory),
ALIGNMENT);
DqnMemStack_InitWithFixedMem(&stack, memory, DQN_ARRAY_COUNT(memory), ALIGNMENT);
DQN_ASSERT(stack.block && stack.block->memory);
DQN_ASSERT(stack.block->size ==
DQN_ARRAY_COUNT(memory) - sizeof(DqnMemStackBlock));
DQN_ASSERT(stack.block->size == DQN_ARRAY_COUNT(memory) - sizeof(DqnMemStackBlock));
DQN_ASSERT(stack.block->used == 0);
DQN_ASSERT(stack.byteAlign == ALIGNMENT);
@ -1213,14 +1277,14 @@ void MemStackTest()
DqnMemStack_Free(&stack);
DqnMemStack_FreeLastBlock(&stack);
DQN_ASSERT(stack.block && stack.block->memory);
DQN_ASSERT(stack.block->size ==
DQN_ARRAY_COUNT(memory) - sizeof(DqnMemStackBlock));
DQN_ASSERT(stack.block->size == DQN_ARRAY_COUNT(memory) - sizeof(DqnMemStackBlock));
DQN_ASSERT(stack.block->used == 0);
DQN_ASSERT(stack.byteAlign == ALIGNMENT);
}
// Test stack with fixed size, allocates once from platform but does not
// grow further
if (1)
{
size_t allocSize = DQN_KILOBYTE(1);
DqnMemStack stack = {};
@ -1243,6 +1307,7 @@ void MemStackTest()
}
// Test freeing/clear block and alignment
if (1)
{
size_t firstBlockSize = DQN_KILOBYTE(1);
DqnMemStack stack = {};
@ -1320,7 +1385,8 @@ void MemStackTest()
for (u32 i = 0; i < fourthBlockSize; i++)
fourth[i] = 'f';
DQN_ASSERT((firstBlock != secondBlock) && (secondBlock != thirdBlock) && (thirdBlock != fourthBlock));
DQN_ASSERT((firstBlock != secondBlock) && (secondBlock != thirdBlock) &&
(thirdBlock != fourthBlock));
DQN_ASSERT(firstBlock->prevBlock == NULL);
DQN_ASSERT(secondBlock->prevBlock == firstBlock);
DQN_ASSERT(thirdBlock->prevBlock == secondBlock);
@ -1346,7 +1412,8 @@ void MemStackTest()
DQN_ASSERT(thirdBlock->used == thirdBlockSize);
DQN_ASSERT(fourthBlock->used == fourthBlockSize);
DQN_ASSERT((firstBlock != secondBlock) && (secondBlock != thirdBlock) && (thirdBlock != fourthBlock));
DQN_ASSERT((firstBlock != secondBlock) && (secondBlock != thirdBlock) &&
(thirdBlock != fourthBlock));
DQN_ASSERT(firstBlock->prevBlock == NULL);
DQN_ASSERT(secondBlock->prevBlock == firstBlock);
DQN_ASSERT(thirdBlock->prevBlock == secondBlock);
@ -1427,6 +1494,7 @@ void MemStackTest()
}
// Test pop
if (1)
{
DqnMemStack stack = {};
DqnMemStack_Init(&stack, DQN_KILOBYTE(1), true);
@ -1440,14 +1508,15 @@ void MemStackTest()
}
}
#ifdef DQN_PLATFORM_LAYER
#ifdef DQN_XPLATFORM_LAYER
void FileTest()
{
// File i/o
if (1)
{
// Test file open
if (1)
{
const char *const FILE_TO_OPEN = ".clang-format";
u32 expectedSize = 0;
@ -1460,9 +1529,8 @@ void FileTest()
#elif defined(DQN_WIN32_IMPLEMENTATION)
{
HANDLE handle =
CreateFile(FILE_TO_OPEN, GENERIC_READ, 0, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
HANDLE handle = CreateFile(FILE_TO_OPEN, GENERIC_READ, 0, NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, NULL);
if (handle == INVALID_HANDLE_VALUE)
{
DqnWin32_DisplayLastError("CreateFile() failed");
@ -1478,29 +1546,27 @@ void FileTest()
#endif
DqnFile file = {};
DQN_ASSERT(DqnFile_Open(
".clang-format", &file,
DQN_ASSERT(DqnFile_Open(".clang-format", &file,
(DqnFilePermissionFlag_Write | DqnFilePermissionFlag_Read),
DqnFileAction_OpenOnly));
DQN_ASSERT_MSG(file.size == expectedSize,
"DqnFileOpen() failed: file.size: %d, expected:%d\n",
file.size, expectedSize);
"DqnFileOpen() failed: file.size: %d, expected:%d\n", file.size,
expectedSize);
u8 *buffer = (u8 *)calloc(1, (size_t)file.size * sizeof(u8));
DQN_ASSERT(DqnFile_Read(file, buffer, (u32)file.size) == file.size);
free(buffer);
DqnFile_Close(&file);
DQN_ASSERT(!file.handle && file.size == 0 &&
file.permissionFlags == 0);
DQN_ASSERT(!file.handle && file.size == 0 && file.permissionFlags == 0);
}
// Test invalid file
if (1)
{
DqnFile file = {};
DQN_ASSERT(!DqnFile_Open(
"asdljasdnel;kajdf", &file,
DQN_ASSERT(!DqnFile_Open("asdljasdnel;kajdf", &file,
(DqnFilePermissionFlag_Write | DqnFilePermissionFlag_Read),
DqnFileAction_OpenOnly));
DQN_ASSERT(file.size == 0);
@ -1508,25 +1574,22 @@ void FileTest()
DQN_ASSERT(!file.handle);
printf("FileTest(): FileIO: Completed successfully\n");
}
}
////////////////////////////////////////////////////////////////////////////
// Write Test
////////////////////////////////////////////////////////////////////////////
if (1)
{
const char *fileNames[] = {"dqn_1", "dqn_2", "dqn_3", "dqn_4", "dqn_5"};
const char *writeData[] = {"1234", "2468", "36912", "481216",
"5101520"};
const char *writeData[] = {"1234", "2468", "36912", "481216", "5101520"};
DqnFile files[DQN_ARRAY_COUNT(fileNames)] = {};
// Write data out to some files
for (u32 i = 0; i < DQN_ARRAY_COUNT(fileNames); i++)
{
u32 permissions =
DqnFilePermissionFlag_Read | DqnFilePermissionFlag_Write;
if (!DqnFile_Open(fileNames[i], files + i, permissions,
DqnFileAction_ClearIfExist))
u32 permissions = DqnFilePermissionFlag_Read | DqnFilePermissionFlag_Write;
if (!DqnFile_Open(fileNames[i], files + i, permissions, DqnFileAction_ClearIfExist))
{
bool result = DqnFile_Open(fileNames[i], files + i, permissions,
DqnFileAction_CreateIfNotExist);
@ -1547,8 +1610,7 @@ void FileTest()
{
u32 permissions = DqnFilePermissionFlag_Read;
DqnFile *file = files + i;
bool result = DqnFile_Open(fileNames[i], file, permissions,
DqnFileAction_OpenOnly);
bool result = DqnFile_Open(fileNames[i], file, permissions, DqnFileAction_OpenOnly);
DQN_ASSERT(result);
u8 *buffer = (u8 *)DqnMemStack_Push(&memStack, file->size);
@ -1572,13 +1634,14 @@ void FileTest()
{
DqnFile dummy = {};
u32 permissions = DqnFilePermissionFlag_Read;
bool fileExists = DqnFile_Open(fileNames[i], &dummy, permissions,
DqnFileAction_OpenOnly);
bool fileExists =
DqnFile_Open(fileNames[i], &dummy, permissions, DqnFileAction_OpenOnly);
DQN_ASSERT(!fileExists);
}
DqnMemStack_Free(&memStack);
}
if (1)
{
u32 numFiles;
#if defined(DQN_UNIX_IMPLEMENTATION)
@ -1612,8 +1675,8 @@ FILE_SCOPE void JobQueueDebugCallbackIncrementCounter(DqnJobQueue *const queue,
u32 number = globalDebugCounter;
DqnLock_Release(&globalJobQueueLock);
printf("JobQueueDebugCallbackIncrementCounter(): Thread %d: Incrementing Number: %d\n", GetCurrentThreadId(),
number);
printf("JobQueueDebugCallbackIncrementCounter(): Thread %d: Incrementing Number: %d\n",
GetCurrentThreadId(), number);
}
FILE_SCOPE void JobQueueTest()
@ -1632,8 +1695,8 @@ FILE_SCOPE void JobQueueTest()
void *jobQueueMem = DqnMemStack_Push(&memStack, requiredSize);
DQN_ASSERT_HARD(jobQueueMem);
DqnJobQueue *jobQueue = DqnJobQueue_InitWithMem(jobQueueMem, &requiredSize,
QUEUE_SIZE, totalThreads);
DqnJobQueue *jobQueue =
DqnJobQueue_InitWithMem(jobQueueMem, &requiredSize, QUEUE_SIZE, totalThreads);
DQN_ASSERT_HARD(jobQueue);
DQN_ASSERT(DqnLock_Init(&globalJobQueueLock));
@ -1653,8 +1716,7 @@ FILE_SCOPE void JobQueueTest()
for (i32 i = 0; i < DQN_ARRAY_COUNT(globalDebugCounterMemoize); i++)
DQN_ASSERT(globalDebugCounterMemoize[i]);
while (DqnJobQueue_TryExecuteNextJob(jobQueue) &&
!DqnJobQueue_AllJobsComplete(jobQueue))
while (DqnJobQueue_TryExecuteNextJob(jobQueue) && !DqnJobQueue_AllJobsComplete(jobQueue))
;
printf("\nJobQueueTest(): Final incremented value: %d\n", globalDebugCounter);
@ -1672,12 +1734,12 @@ int main(void)
ArrayTest();
MemStackTest();
#ifdef DQN_PLATFORM_LAYER
#ifdef DQN_XPLATFORM_LAYER
FileTest();
OtherTest();
#endif
#ifdef DQN_WIN32_IMPLEMENTATION
OtherTest();
JobQueueTest();
#endif