Fix minor bugs in dqn
This commit is contained in:
parent
e1545c7977
commit
08b2832436
@ -55,7 +55,7 @@ typedef bool PlatformAPI_QueueAddJob (PlatformJobQueue *const queue, c
|
|||||||
typedef bool PlatformAPI_QueueTryExecuteNextJob(PlatformJobQueue *const queue);
|
typedef bool PlatformAPI_QueueTryExecuteNextJob(PlatformJobQueue *const queue);
|
||||||
typedef bool PlatformAPI_QueueAllJobsComplete (PlatformJobQueue *const queue);
|
typedef bool PlatformAPI_QueueAllJobsComplete (PlatformJobQueue *const queue);
|
||||||
|
|
||||||
typedef u32 PlatformAPI_AtomicCompareSwap(u32 *volatile dest, u32 swapVal, u32 compareVal);
|
typedef u32 PlatformAPI_AtomicCompareSwap(u32 volatile *dest, u32 swapVal, u32 compareVal);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// Platform Locks
|
// Platform Locks
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
|
#define DQN_WIN32_IMPLEMENTATION
|
||||||
|
|
||||||
#include "DTRenderer.h"
|
#include "DTRenderer.h"
|
||||||
#include "DTRendererPlatform.h"
|
#include "DTRendererPlatform.h"
|
||||||
|
|
||||||
#define DQN_IMPLEMENTATION
|
#define DQN_IMPLEMENTATION
|
||||||
#define DQN_WIN32_IMPLEMENTATION
|
|
||||||
#include "dqn.h"
|
#include "dqn.h"
|
||||||
|
|
||||||
#define UNICODE
|
#define UNICODE
|
||||||
@ -16,7 +17,7 @@ void Platform_DieGracefully() { globalRunning = false; }
|
|||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// Platform Atomics
|
// Platform Atomics
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
u32 Platform_AtomicCompareSwap(u32 *volatile dest, u32 swapVal, u32 compareVal)
|
u32 Platform_AtomicCompareSwap(u32 volatile *dest, u32 swapVal, u32 compareVal)
|
||||||
{
|
{
|
||||||
// TODO(doyle): Compile time assert
|
// TODO(doyle): Compile time assert
|
||||||
DQN_ASSERT(sizeof(LONG) == sizeof(u32));
|
DQN_ASSERT(sizeof(LONG) == sizeof(u32));
|
||||||
@ -156,8 +157,6 @@ FILE_SCOPE void DebugWin32JobPrintNumber(PlatformJobQueue *const queue, void *co
|
|||||||
numberToPrint);
|
numberToPrint);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
DWORD WINAPI Win32ThreadCallback(void *lpParameter)
|
DWORD WINAPI Win32ThreadCallback(void *lpParameter)
|
||||||
{
|
{
|
||||||
PlatformJobQueue *queue = (PlatformJobQueue *)lpParameter;
|
PlatformJobQueue *queue = (PlatformJobQueue *)lpParameter;
|
||||||
|
90
src/dqn.h
90
src/dqn.h
@ -23,6 +23,12 @@
|
|||||||
#define DQN_CPP_MODE
|
#define DQN_CPP_MODE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if (defined(_WIN32) || defined(_WIN64)) && defined(DQN_WIN32_IMPLEMENTATION)
|
||||||
|
#define DQN_WIN32_PLATFORM
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#include <Windows.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <stdint.h> // For standard types
|
#include <stdint.h> // For standard types
|
||||||
#include <float.h>
|
#include <float.h>
|
||||||
#define LOCAL_PERSIST static
|
#define LOCAL_PERSIST static
|
||||||
@ -842,6 +848,23 @@ DQN_FILE_SCOPE f32 DqnRnd_PCGNextf(DqnRandPCGState *pcg);
|
|||||||
// Returns a random integer N between [min, max]
|
// Returns a random integer N between [min, max]
|
||||||
DQN_FILE_SCOPE i32 DqnRnd_PCGRange(DqnRandPCGState *pcg, i32 min, i32 max);
|
DQN_FILE_SCOPE i32 DqnRnd_PCGRange(DqnRandPCGState *pcg, i32 min, i32 max);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// DqnLock
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
typedef struct DqnLock
|
||||||
|
{
|
||||||
|
#ifdef DQN_WIN32_PLATFORM
|
||||||
|
CRITICAL_SECTION win32Handle;
|
||||||
|
#else
|
||||||
|
void *handle;
|
||||||
|
#endif
|
||||||
|
} DqnLock;
|
||||||
|
|
||||||
|
DQN_FILE_SCOPE bool DqnLock_Init (DqnLock *const lock, const u32 spinCount = 16000);
|
||||||
|
DQN_FILE_SCOPE void DqnLock_Acquire(DqnLock *const lock);
|
||||||
|
DQN_FILE_SCOPE void DqnLock_Release(DqnLock *const lock);
|
||||||
|
DQN_FILE_SCOPE void DqnLock_Delete (DqnLock *const lock);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// DqnAtomics
|
// DqnAtomics
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -853,7 +876,6 @@ DQN_FILE_SCOPE u32 DqnAtomic_Sub32 (u32 volatile *src);
|
|||||||
// DqnJobQueue - Multithreaded Job Queue
|
// DqnJobQueue - Multithreaded Job Queue
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// TODO(doyle): Only WIN32!!
|
// TODO(doyle): Only WIN32!!
|
||||||
|
|
||||||
// DqnJobQueue is a platform abstracted "lockless" multithreaded work queue. It
|
// DqnJobQueue is a platform abstracted "lockless" multithreaded work queue. It
|
||||||
// will create threads and assign threads to complete the job via the job
|
// will create threads and assign threads to complete the job via the job
|
||||||
// 'callback' using the 'userData' supplied.
|
// 'callback' using the 'userData' supplied.
|
||||||
@ -891,17 +913,10 @@ DQN_FILE_SCOPE bool DqnJobQueue_TryExecuteNextJob(DqnJobQueue *const queue);
|
|||||||
DQN_FILE_SCOPE bool DqnJobQueue_AllJobsComplete (DqnJobQueue *const queue);
|
DQN_FILE_SCOPE bool DqnJobQueue_AllJobsComplete (DqnJobQueue *const queue);
|
||||||
#endif /* DQN_H */
|
#endif /* DQN_H */
|
||||||
|
|
||||||
#if (defined(_WIN32) || defined(_WIN64)) && defined(DQN_WIN32_IMPLEMENTATION)
|
|
||||||
#define DQN_WIN32_PLATFORM
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef DQN_WIN32_PLATFORM
|
#ifdef DQN_WIN32_PLATFORM
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// Win32 Specific
|
// Win32 Specific
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
#define WIN32_LEAN_AND_MEAN
|
|
||||||
#include <Windows.h>
|
|
||||||
|
|
||||||
#define DQN_WIN32_ERROR_BOX(text, title) MessageBoxA(NULL, text, title, MB_OK);
|
#define DQN_WIN32_ERROR_BOX(text, title) MessageBoxA(NULL, text, title, MB_OK);
|
||||||
// Out is a pointer to the buffer to receive the characters.
|
// Out is a pointer to the buffer to receive the characters.
|
||||||
// outLen is the length/capacity of the out buffer
|
// outLen is the length/capacity of the out buffer
|
||||||
@ -3752,7 +3767,7 @@ FILE_SCOPE u64 DqnRnd_Murmur3Avalanche64Internal(u64 h)
|
|||||||
|
|
||||||
FILE_SCOPE u32 DqnRnd_MakeSeedInternal()
|
FILE_SCOPE u32 DqnRnd_MakeSeedInternal()
|
||||||
{
|
{
|
||||||
#ifdef DQN_WIN32_IMPLEMENTATION
|
#ifdef DQN_WIN32_PLATFORM
|
||||||
__int64 numClockCycles = __rdtsc();
|
__int64 numClockCycles = __rdtsc();
|
||||||
return (u32)numClockCycles;
|
return (u32)numClockCycles;
|
||||||
#elif __ANDROID__
|
#elif __ANDROID__
|
||||||
@ -3806,6 +3821,51 @@ DQN_FILE_SCOPE i32 DqnRnd_PCGRange(DqnRandPCGState *pcg, i32 min, i32 max)
|
|||||||
return min + value;
|
return min + value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// DqnLock
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
bool DqnLock_Init(DqnLock *const lock, const u32 spinCount)
|
||||||
|
{
|
||||||
|
if (!lock) return false;
|
||||||
|
|
||||||
|
#ifdef DQN_WIN32_PLATFORM
|
||||||
|
if (InitializeCriticalSectionEx(&lock->win32Handle, spinCount, 0))
|
||||||
|
return true;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DqnLock_Acquire(DqnLock *const lock)
|
||||||
|
{
|
||||||
|
if (!lock) return;
|
||||||
|
#ifdef DQN_WIN32_PLATFORM
|
||||||
|
EnterCriticalSection(&lock->win32Handle);
|
||||||
|
#else
|
||||||
|
DQN_ASSERT_HARD(DQN_INVALID_CODE_PATH);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void DqnLock_Release(DqnLock *const lock)
|
||||||
|
{
|
||||||
|
if (!lock) return;
|
||||||
|
#ifdef DQN_WIN32_PLATFORM
|
||||||
|
LeaveCriticalSection(&lock->win32Handle);
|
||||||
|
#else
|
||||||
|
DQN_ASSERT_HARD(DQN_INVALID_CODE_PATH);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void DqnLock_Delete(DqnLock *const lock)
|
||||||
|
{
|
||||||
|
if (!lock) return;
|
||||||
|
#ifdef DQN_WIN32_PLATFORM
|
||||||
|
DeleteCriticalSection(&lock->win32Handle);
|
||||||
|
#else
|
||||||
|
DQN_ASSERT_HARD(DQN_INVALID_CODE_PATH);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// DqnAtomics
|
// DqnAtomics
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -3872,21 +3932,20 @@ FILE_SCOPE u32 DqnJobQueueInternal_ThreadCreate(const size_t stackSize, void *th
|
|||||||
{
|
{
|
||||||
u32 numThreadsCreated = 0;
|
u32 numThreadsCreated = 0;
|
||||||
|
|
||||||
#ifdef DQN_WIN32_IMPLEMENTATION
|
#ifdef DQN_WIN32_PLATFORM
|
||||||
DQN_ASSERT_HARD(stackSize == 0 || !threadCallback);
|
DQN_ASSERT_HARD(stackSize == 0 || !threadCallback);
|
||||||
|
|
||||||
u32 threadsCreated = 0;
|
|
||||||
for (u32 i = 0; i < numThreads; i++)
|
for (u32 i = 0; i < numThreads; i++)
|
||||||
{
|
{
|
||||||
HANDLE handle = CreateThread(NULL, stackSize, (LPTHREAD_START_ROUTINE)threadCallback,
|
HANDLE handle = CreateThread(NULL, stackSize, (LPTHREAD_START_ROUTINE)threadCallback,
|
||||||
threadParam, 0, NULL);
|
threadParam, 0, NULL);
|
||||||
CloseHandle(handle);
|
CloseHandle(handle);
|
||||||
threadsCreated++;
|
numThreadsCreated++;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
DQN_ASSERT(DQN_INVALID_CODE_PATH);
|
DQN_ASSERT(DQN_INVALID_CODE_PATH);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
DQN_ASSERT(numThreadsCreated == numThreads);
|
DQN_ASSERT(numThreadsCreated == numThreads);
|
||||||
return numThreadsCreated;
|
return numThreadsCreated;
|
||||||
}
|
}
|
||||||
@ -3895,7 +3954,7 @@ FILE_SCOPE u32 DqnJobQueueInternal_ThreadCreate(const size_t stackSize, void *th
|
|||||||
FILE_SCOPE u32 DqnJobQueueInternal_ThreadCallback(void *threadParam)
|
FILE_SCOPE u32 DqnJobQueueInternal_ThreadCallback(void *threadParam)
|
||||||
{
|
{
|
||||||
DqnJobQueue *queue = (DqnJobQueue *)threadParam;
|
DqnJobQueue *queue = (DqnJobQueue *)threadParam;
|
||||||
#ifdef DQN_WIN32_IMPLEMENTATION
|
#ifdef DQN_WIN32_PLATFORM
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
if (!DqnJobQueue_TryExecuteNextJob(queue))
|
if (!DqnJobQueue_TryExecuteNextJob(queue))
|
||||||
@ -3930,6 +3989,7 @@ DQN_FILE_SCOPE DqnJobQueue *DqnJobQueue_InitWithMem(const void *const mem, size_
|
|||||||
// Sub-allocate Queue
|
// Sub-allocate Queue
|
||||||
DqnJobQueue *queue = (DqnJobQueue *)memPtr;
|
DqnJobQueue *queue = (DqnJobQueue *)memPtr;
|
||||||
*queue = emptyQueue;
|
*queue = emptyQueue;
|
||||||
|
queue->size = queueSize;
|
||||||
|
|
||||||
// Sub-allocate jobList
|
// Sub-allocate jobList
|
||||||
memPtr += reqStructSize;
|
memPtr += reqStructSize;
|
||||||
@ -3964,7 +4024,7 @@ DQN_FILE_SCOPE bool DqnJobQueue_AddJob(DqnJobQueue *const queue, const DqnJob jo
|
|||||||
|
|
||||||
DqnAtomic_Add32(&queue->numJobsToComplete);
|
DqnAtomic_Add32(&queue->numJobsToComplete);
|
||||||
|
|
||||||
#ifdef DQN_WIN32_IMPLEMENTATION
|
#ifdef DQN_WIN32_PLATFORM
|
||||||
ReleaseSemaphore(queue->semaphore, 1, NULL);
|
ReleaseSemaphore(queue->semaphore, 1, NULL);
|
||||||
#else
|
#else
|
||||||
DQN_ASSERT_HARD(DQN_INVALID_CODE_PATH);
|
DQN_ASSERT_HARD(DQN_INVALID_CODE_PATH);
|
||||||
|
Loading…
Reference in New Issue
Block a user