Expose job queue, update init function
This commit is contained in:
parent
f9de41b6c0
commit
45bc637773
139
dqn.h
139
dqn.h
@ -12,6 +12,13 @@
|
|||||||
#include "dqn.h"
|
#include "dqn.h"
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// Conventions
|
||||||
|
// All data structures fields are exposed by default, with exceptions here and there. The rationale
|
||||||
|
// is I rarely go into libraries and start changing values around in fields unless I know the
|
||||||
|
// implementation OR we're required to fill out a struct for some function.
|
||||||
|
|
||||||
|
// Just treat all struct fields to be internal and read-only unless explicitly stated otherwise.
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// Table Of Contents #TOC #TableOfContents
|
// Table Of Contents #TOC #TableOfContents
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -53,7 +60,7 @@
|
|||||||
// #DqnSprintf Cross-platform Sprintf Implementation (Public Domain lib stb_sprintf)
|
// #DqnSprintf Cross-platform Sprintf Implementation (Public Domain lib stb_sprintf)
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// Global Preprocessor Checks
|
// Preprocessor Checks
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// This needs to be above the portable layer so that, if the user requests
|
// This needs to be above the portable layer so that, if the user requests
|
||||||
// a platform implementation, platform specific implementations in the portable
|
// a platform implementation, platform specific implementations in the portable
|
||||||
@ -209,9 +216,14 @@ enum DqnMemStackFlag
|
|||||||
|
|
||||||
typedef struct DqnMemStack
|
typedef struct DqnMemStack
|
||||||
{
|
{
|
||||||
|
// The memory block allocated for the stack
|
||||||
struct DqnMemStackBlock *block;
|
struct DqnMemStackBlock *block;
|
||||||
|
|
||||||
|
// Bits set from enum DqnMemStackFlag
|
||||||
u32 flags;
|
u32 flags;
|
||||||
i32 tempRegionCount;
|
i32 tempRegionCount;
|
||||||
|
|
||||||
|
// Allocations are address aligned to this value. Not to be modified as popping allocations uses this to realign size
|
||||||
u32 byteAlign;
|
u32 byteAlign;
|
||||||
|
|
||||||
#if defined(DQN_CPP_MODE)
|
#if defined(DQN_CPP_MODE)
|
||||||
@ -262,7 +274,7 @@ DQN_FILE_SCOPE bool DqnMemStack_InitWithFixedSize(DqnMemStack *const stack, size
|
|||||||
// Dynamically expandable stack. Akin to DqnMemStack_InitWithFixedSize() except if the MemStack does
|
// Dynamically expandable stack. Akin to DqnMemStack_InitWithFixedSize() except if the MemStack does
|
||||||
// not have enough space for allocation it will automatically attach another MemBlock using
|
// not have enough space for allocation it will automatically attach another MemBlock using
|
||||||
// DqnMem_Alloc().
|
// DqnMem_Alloc().
|
||||||
DQN_FILE_SCOPE bool DqnMemStack_Init (DqnMemStack *const stack, size_t size, const bool zeroClear, const u32 byteAlign = 4);
|
DQN_FILE_SCOPE bool DqnMemStack_Init(DqnMemStack *const stack, size_t size, const bool zeroClear, const u32 byteAlign = 4);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// DqnMemStack Memory Operations
|
// DqnMemStack Memory Operations
|
||||||
@ -270,13 +282,13 @@ DQN_FILE_SCOPE bool DqnMemStack_Init (DqnMemStack *const stack, size_t size, con
|
|||||||
// Allocate memory from the MemStack.
|
// Allocate memory from the MemStack.
|
||||||
// size: "size" gets aligned to the byte alignment of the stack.
|
// size: "size" gets aligned to the byte alignment of the stack.
|
||||||
// return: NULL if out of space OR stack is using fixed memory/size OR stack full and platform malloc fails.
|
// return: NULL if out of space OR stack is using fixed memory/size OR stack full and platform malloc fails.
|
||||||
DQN_FILE_SCOPE void *DqnMemStack_Push (DqnMemStack *const stack, size_t size);
|
DQN_FILE_SCOPE void *DqnMemStack_Push(DqnMemStack *const stack, size_t size);
|
||||||
|
|
||||||
// Frees the given ptr. It MUST be the last allocated item in the stack, fails otherwise.
|
// Frees the given ptr. It MUST be the last allocated item in the stack, fails otherwise.
|
||||||
DQN_FILE_SCOPE bool DqnMemStack_Pop (DqnMemStack *const stack, void *ptr, size_t size);
|
DQN_FILE_SCOPE bool DqnMemStack_Pop(DqnMemStack *const stack, void *ptr, size_t size);
|
||||||
|
|
||||||
// Frees all blocks belonging to this stack.
|
// Frees all blocks belonging to this stack.
|
||||||
DQN_FILE_SCOPE void DqnMemStack_Free (DqnMemStack *const stack);
|
DQN_FILE_SCOPE void DqnMemStack_Free(DqnMemStack *const stack);
|
||||||
|
|
||||||
// Frees the specified block belonging to the stack.
|
// Frees the specified block belonging to the stack.
|
||||||
// return: FALSE if block doesn't belong this into calls DqnMem_Free() or invalid args.
|
// return: FALSE if block doesn't belong this into calls DqnMem_Free() or invalid args.
|
||||||
@ -284,7 +296,7 @@ DQN_FILE_SCOPE bool DqnMemStack_FreeMemBlock(DqnMemStack *const stack, DqnMemSt
|
|||||||
|
|
||||||
// Frees the last-most memory block. If last block, free that block making the MemStack blockless.
|
// Frees the last-most memory block. If last block, free that block making the MemStack blockless.
|
||||||
// Next allocate will attach a block.
|
// Next allocate will attach a block.
|
||||||
DQN_FILE_SCOPE bool DqnMemStack_FreeLastBlock (DqnMemStack *const stack);
|
DQN_FILE_SCOPE bool DqnMemStack_FreeLastBlock(DqnMemStack *const stack);
|
||||||
|
|
||||||
// Reset the current memory block usage to 0.
|
// Reset the current memory block usage to 0.
|
||||||
DQN_FILE_SCOPE void DqnMemStack_ClearCurrBlock(DqnMemStack *const stack, const bool zeroClear);
|
DQN_FILE_SCOPE void DqnMemStack_ClearCurrBlock(DqnMemStack *const stack, const bool zeroClear);
|
||||||
@ -300,7 +312,10 @@ DQN_FILE_SCOPE void DqnMemStack_ClearCurrBlock(DqnMemStack *const stack, const
|
|||||||
// regions
|
// regions
|
||||||
typedef struct DqnMemStackTempRegion
|
typedef struct DqnMemStackTempRegion
|
||||||
{
|
{
|
||||||
|
// The stack associated with this TempRegion
|
||||||
DqnMemStack *stack;
|
DqnMemStack *stack;
|
||||||
|
|
||||||
|
// Store memBlock state to revert back to on DqnMemStackTempRegion_End()
|
||||||
struct DqnMemStackBlock *startingBlock;
|
struct DqnMemStackBlock *startingBlock;
|
||||||
size_t used;
|
size_t used;
|
||||||
} DqnMemStackTempRegion;
|
} DqnMemStackTempRegion;
|
||||||
@ -330,10 +345,12 @@ private:
|
|||||||
// NOT be modified directly, only indirectly through the regular API.
|
// NOT be modified directly, only indirectly through the regular API.
|
||||||
typedef struct DqnMemStackBlock
|
typedef struct DqnMemStackBlock
|
||||||
{
|
{
|
||||||
|
// The raw memory block, size and used count
|
||||||
u8 *memory;
|
u8 *memory;
|
||||||
size_t size;
|
size_t size;
|
||||||
size_t used;
|
size_t used;
|
||||||
|
|
||||||
|
// The allocator uses a linked list approach for additional blocks beyond capacity
|
||||||
DqnMemStackBlock *prevBlock;
|
DqnMemStackBlock *prevBlock;
|
||||||
} DqnMemStackBlock;
|
} DqnMemStackBlock;
|
||||||
|
|
||||||
@ -404,7 +421,7 @@ typedef struct DqnMemAPICallbackResult
|
|||||||
enum DqnMemAPICallbackType type;
|
enum DqnMemAPICallbackType type;
|
||||||
} DqnMemAPICallbackResult;
|
} DqnMemAPICallbackResult;
|
||||||
|
|
||||||
// Function prototype for implementing a DqnMemAPI_Callback. You must fill out the result structure.
|
// Function prototype for implementing a DqnMemAPI_Callback. You must fill out the "result" structure.
|
||||||
// result: Is always guaranteed to be a valid pointer.
|
// result: Is always guaranteed to be a valid pointer.
|
||||||
typedef void DqnMemAPI_Callback(DqnMemAPICallbackInfo info, DqnMemAPICallbackResult *result);
|
typedef void DqnMemAPI_Callback(DqnMemAPICallbackInfo info, DqnMemAPICallbackResult *result);
|
||||||
|
|
||||||
@ -424,12 +441,15 @@ DQN_FILE_SCOPE DqnMemAPI DqnMemAPI_DefaultUseCalloc();
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
struct DqnArray
|
struct DqnArray
|
||||||
{
|
{
|
||||||
|
// Function pointers to custom allocators
|
||||||
DqnMemAPI memAPI;
|
DqnMemAPI memAPI;
|
||||||
|
|
||||||
|
// Array state
|
||||||
u64 count;
|
u64 count;
|
||||||
u64 capacity;
|
u64 capacity;
|
||||||
T *data;
|
T *data;
|
||||||
|
|
||||||
|
// API
|
||||||
void Init (const size_t capacity, DqnMemAPI memAPI = DqnMemAPI_DefaultUseCalloc());
|
void Init (const size_t capacity, DqnMemAPI memAPI = DqnMemAPI_DefaultUseCalloc());
|
||||||
bool Free ();
|
bool Free ();
|
||||||
bool Grow ();
|
bool Grow ();
|
||||||
@ -1065,6 +1085,7 @@ DQN_FILE_SCOPE u32 DqnAtomic_Sub32 (u32 volatile *src);
|
|||||||
// wait for all jobs to complete using DqnJobQueue_TryExecuteNextJob() or spinlock on
|
// wait for all jobs to complete using DqnJobQueue_TryExecuteNextJob() or spinlock on
|
||||||
// DqnJobQueue_AllJobsComplete(). Alternatively you can combine both for the main thread to help
|
// DqnJobQueue_AllJobsComplete(). Alternatively you can combine both for the main thread to help
|
||||||
// complete work and not move on until all tasks are complete.
|
// complete work and not move on until all tasks are complete.
|
||||||
|
|
||||||
typedef struct DqnJobQueue DqnJobQueue;
|
typedef struct DqnJobQueue DqnJobQueue;
|
||||||
|
|
||||||
typedef void DqnJob_Callback(DqnJobQueue *const queue, void *const userData);
|
typedef void DqnJob_Callback(DqnJobQueue *const queue, void *const userData);
|
||||||
@ -1074,10 +1095,35 @@ typedef struct DqnJob
|
|||||||
void *userData;
|
void *userData;
|
||||||
} DqnJob;
|
} DqnJob;
|
||||||
|
|
||||||
// memSize: The size of the supplied memory. If "mem" is NULL OR "memsize" is NULL/0 OR "queueSize"
|
typedef struct DqnJobQueue
|
||||||
// is 0, the function puts required size it needs into "memSize".
|
{
|
||||||
// return: The JobQueue or NULL if args invalid.
|
// JobList Circular Array, is setup in Init()
|
||||||
DQN_FILE_SCOPE DqnJobQueue *DqnJobQueue_InitWithMem(const void *const mem, size_t *const memSize, const u32 queueSize, const u32 numThreads);
|
DqnJob *jobList;
|
||||||
|
u32 size;
|
||||||
|
|
||||||
|
// NOTE(doyle): Modified by main+worker threads
|
||||||
|
u32 volatile jobToExecuteIndex;
|
||||||
|
u32 volatile numJobsToComplete;
|
||||||
|
void *semaphore;
|
||||||
|
|
||||||
|
// NOTE: Modified by main thread ONLY
|
||||||
|
u32 volatile jobInsertIndex;
|
||||||
|
|
||||||
|
#if defined(DQN_CPP_MODE)
|
||||||
|
bool Init (DqnJob const *const jobList_, const u32 jobListSize, const u32 numThreads);
|
||||||
|
bool AddJob (const DqnJob job);
|
||||||
|
bool TryExecuteNextJob();
|
||||||
|
bool AllJobsComplete ();
|
||||||
|
#endif
|
||||||
|
} DqnJobQueue;
|
||||||
|
|
||||||
|
// queue: Pass a pointer to a zero cleared DqnJobQueue struct
|
||||||
|
// jobList: Pass in a pointer to an array of DqnJob's
|
||||||
|
// jobListSize: The number of elements in the jobList array
|
||||||
|
// numThreads: The number of threads the queue should request from the OS for working on the queue
|
||||||
|
// return: FALSE if invalid args.
|
||||||
|
DQN_FILE_SCOPE bool DqnJobQueue_Init(DqnJobQueue *const queue, DqnJob const *const jobList,
|
||||||
|
const u32 jobListSize, const u32 numThreads);
|
||||||
|
|
||||||
// return: FALSE if the job is not able to be added, this occurs if the queue is full.
|
// return: FALSE if the job is not able to be added, this occurs if the queue is full.
|
||||||
DQN_FILE_SCOPE bool DqnJobQueue_AddJob(DqnJobQueue *const queue, const DqnJob job);
|
DQN_FILE_SCOPE bool DqnJobQueue_AddJob(DqnJobQueue *const queue, const DqnJob job);
|
||||||
@ -1734,9 +1780,9 @@ DqnMemStackInternal_AllocateBlock(u32 byteAlign, size_t size)
|
|||||||
// #DqnMemStack CPP Implementation
|
// #DqnMemStack CPP Implementation
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
#if defined(DQN_CPP_MODE)
|
#if defined(DQN_CPP_MODE)
|
||||||
bool DqnMemStack::InitWithFixedMem (u8 *const mem, const size_t memSize, const u32 byteAlignment) { return DqnMemStack_InitWithFixedMem (this, mem, memSize, byteAlign); }
|
bool DqnMemStack::InitWithFixedMem (u8 *const mem, const size_t memSize, const u32 byteAlignment) { return DqnMemStack_InitWithFixedMem (this, mem, memSize, byteAlignment); }
|
||||||
bool DqnMemStack::InitWithFixedSize(const size_t size, const bool zeroClear, const u32 byteAlignment) { return DqnMemStack_InitWithFixedSize(this, size, zeroClear, byteAlign); }
|
bool DqnMemStack::InitWithFixedSize(const size_t size, const bool zeroClear, const u32 byteAlignment) { return DqnMemStack_InitWithFixedSize(this, size, zeroClear, byteAlignment); }
|
||||||
bool DqnMemStack::Init (const size_t size, const bool zeroClear, const u32 byteAlignment) { return DqnMemStack_Init (this, size, zeroClear, byteAlign); }
|
bool DqnMemStack::Init (const size_t size, const bool zeroClear, const u32 byteAlignment) { return DqnMemStack_Init (this, size, zeroClear, byteAlignment); }
|
||||||
|
|
||||||
void *DqnMemStack::Push(size_t size) { return DqnMemStack_Push(this, size); }
|
void *DqnMemStack::Push(size_t size) { return DqnMemStack_Push(this, size); }
|
||||||
void DqnMemStack::Pop (void *const ptr, size_t size) { DqnMemStack_Pop (this, ptr, size); }
|
void DqnMemStack::Pop (void *const ptr, size_t size) { DqnMemStack_Pop (this, ptr, size); }
|
||||||
@ -6049,23 +6095,6 @@ DQN_FILE_SCOPE u32 DqnAtomic_Sub32(u32 volatile *src)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Win32Platform > #DqnJobQueue Implementation
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
typedef struct DqnJobQueue
|
|
||||||
{
|
|
||||||
DqnJob *jobList;
|
|
||||||
u32 size;
|
|
||||||
|
|
||||||
// NOTE: Modified by main+worker threads
|
|
||||||
u32 volatile jobToExecuteIndex;
|
|
||||||
u32 volatile numJobsToComplete;
|
|
||||||
void *semaphore;
|
|
||||||
|
|
||||||
// NOTE: Modified by main thread ONLY
|
|
||||||
u32 volatile jobInsertIndex;
|
|
||||||
} DqnJobQueue;
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// Win32Platform > #DqnJobQueueInternal Implementation
|
// Win32Platform > #DqnJobQueueInternal Implementation
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -6114,35 +6143,13 @@ FILE_SCOPE u32 DqnJobQueueInternal_ThreadCallback(void *threadParam)
|
|||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// Win32Platform > #DqnJobQueue Implementation
|
// Win32Platform > #DqnJobQueue Implementation
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
DQN_FILE_SCOPE DqnJobQueue *DqnJobQueue_InitWithMem(const void *const mem, size_t *const memSize,
|
DQN_FILE_SCOPE bool DqnJobQueue_Init(DqnJobQueue *const queue, DqnJob *const jobList,
|
||||||
const u32 queueSize, const u32 numThreads)
|
const u32 jobListSize, const u32 numThreads)
|
||||||
{
|
{
|
||||||
DqnJobQueue emptyQueue = {};
|
if (!queue || !jobList || jobListSize == 0 || numThreads == 0) return false;
|
||||||
size_t reqStructSize = sizeof(emptyQueue);
|
queue->jobList = jobList;
|
||||||
size_t reqQueueSize = sizeof(*emptyQueue.jobList) * queueSize;
|
queue->size = jobListSize;
|
||||||
|
|
||||||
if (!mem || !memSize || *memSize == 0 || queueSize == 0)
|
|
||||||
{
|
|
||||||
*memSize = reqStructSize + reqQueueSize;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
u8 *memPtr = (u8 *)mem;
|
|
||||||
|
|
||||||
// Sub-allocate Queue
|
|
||||||
DqnJobQueue *queue = (DqnJobQueue *)memPtr;
|
|
||||||
*queue = emptyQueue;
|
|
||||||
queue->size = queueSize;
|
|
||||||
|
|
||||||
// Sub-allocate jobList
|
|
||||||
memPtr += reqStructSize;
|
|
||||||
queue->jobList = (DqnJob *)memPtr;
|
|
||||||
|
|
||||||
// Validate memPtr used size
|
|
||||||
memPtr += reqQueueSize;
|
|
||||||
DQN_ASSERT_HARD((size_t)(memPtr - (u8 *)mem) <= *memSize);
|
|
||||||
|
|
||||||
// Create semaphore
|
|
||||||
#ifdef DQN_WIN32_PLATFORM
|
#ifdef DQN_WIN32_PLATFORM
|
||||||
queue->semaphore = (void *)CreateSemaphore(NULL, 0, numThreads, NULL);
|
queue->semaphore = (void *)CreateSemaphore(NULL, 0, numThreads, NULL);
|
||||||
DQN_ASSERT_HARD(queue->semaphore);
|
DQN_ASSERT_HARD(queue->semaphore);
|
||||||
@ -6155,7 +6162,8 @@ DQN_FILE_SCOPE DqnJobQueue *DqnJobQueue_InitWithMem(const void *const mem, size_
|
|||||||
DQN_JOB_QUEUE_INTERNAL_THREAD_DEFAULT_STACK_SIZE, DqnJobQueueInternal_ThreadCallback,
|
DQN_JOB_QUEUE_INTERNAL_THREAD_DEFAULT_STACK_SIZE, DqnJobQueueInternal_ThreadCallback,
|
||||||
(void *)queue, numThreads);
|
(void *)queue, numThreads);
|
||||||
DQN_ASSERT_HARD(numThreads == numThreadsCreated);
|
DQN_ASSERT_HARD(numThreads == numThreadsCreated);
|
||||||
return queue;
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
DQN_FILE_SCOPE bool DqnJobQueue_AddJob(DqnJobQueue *const queue, const DqnJob job)
|
DQN_FILE_SCOPE bool DqnJobQueue_AddJob(DqnJobQueue *const queue, const DqnJob job)
|
||||||
@ -6208,6 +6216,19 @@ DQN_FILE_SCOPE bool DqnJobQueue_AllJobsComplete(DqnJobQueue *const queue)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Win32Platform > #DqnJobQueue CPP Implementation
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
bool DqnJobQueue::Init(DqnJob const *const jobList_, const u32 jobListSize, const u32 numThreads)
|
||||||
|
{
|
||||||
|
bool result = DqnJobQueue_Init(this, jobList, jobListSize, numThreads);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DqnJobQueue::AddJob (const DqnJob job) { return DqnJobQueue_AddJob(this, job); }
|
||||||
|
bool DqnJobQueue::TryExecuteNextJob() { return DqnJobQueue_TryExecuteNextJob(this); }
|
||||||
|
bool DqnJobQueue::AllJobsComplete () { return DqnJobQueue_AllJobsComplete(this); }
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// Win32Platform > #DqnWin32 Implementation
|
// Win32Platform > #DqnWin32 Implementation
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -1705,42 +1705,37 @@ FILE_SCOPE void JobQueueDebugCallbackIncrementCounter(DqnJobQueue *const queue,
|
|||||||
|
|
||||||
FILE_SCOPE void JobQueueTest()
|
FILE_SCOPE void JobQueueTest()
|
||||||
{
|
{
|
||||||
size_t requiredSize;
|
|
||||||
const i32 QUEUE_SIZE = 256;
|
|
||||||
DqnJobQueue_InitWithMem(NULL, &requiredSize, QUEUE_SIZE, 0);
|
|
||||||
|
|
||||||
DqnMemStack memStack = {};
|
DqnMemStack memStack = {};
|
||||||
DQN_ASSERT_HARD(DqnMemStack_Init(&memStack, requiredSize, true));
|
DQN_ASSERT_HARD(memStack.Init(DQN_MEGABYTE(1), true));
|
||||||
|
|
||||||
i32 numThreads, numCores;
|
i32 numThreads, numCores;
|
||||||
DqnWin32_GetNumThreadsAndCores(&numCores, &numThreads);
|
DqnWin32_GetNumThreadsAndCores(&numCores, &numThreads);
|
||||||
DQN_ASSERT(numThreads > 0 && numCores > 0);
|
DQN_ASSERT(numThreads > 0 && numCores > 0);
|
||||||
i32 totalThreads = (numCores - 1) * numThreads;
|
i32 totalThreads = (numCores - 1) * numThreads;
|
||||||
|
|
||||||
void *jobQueueMem = DqnMemStack_Push(&memStack, requiredSize);
|
const i32 QUEUE_SIZE = 256;
|
||||||
DQN_ASSERT_HARD(jobQueueMem);
|
DqnJobQueue jobQueue = {};
|
||||||
DqnJobQueue *jobQueue =
|
DqnJob *jobList = (DqnJob *)memStack.Push(sizeof(*jobQueue.jobList) * QUEUE_SIZE);
|
||||||
DqnJobQueue_InitWithMem(jobQueueMem, &requiredSize, QUEUE_SIZE, totalThreads);
|
DQN_ASSERT(DqnJobQueue_Init(&jobQueue, jobList, QUEUE_SIZE, totalThreads));
|
||||||
DQN_ASSERT_HARD(jobQueue);
|
|
||||||
|
|
||||||
DQN_ASSERT(DqnLock_Init(&globalJobQueueLock));
|
DQN_ASSERT(DqnLock_Init(&globalJobQueueLock));
|
||||||
for (i32 i = 0; i < DQN_ARRAY_COUNT(globalDebugCounterMemoize); i++)
|
for (i32 i = 0; i < DQN_ARRAY_COUNT(globalDebugCounterMemoize); i++)
|
||||||
{
|
{
|
||||||
DqnJob job = {};
|
DqnJob job = {};
|
||||||
job.callback = JobQueueDebugCallbackIncrementCounter;
|
job.callback = JobQueueDebugCallbackIncrementCounter;
|
||||||
while (!DqnJobQueue_AddJob(jobQueue, job))
|
while (!DqnJobQueue_AddJob(&jobQueue, job))
|
||||||
{
|
{
|
||||||
DqnJobQueue_TryExecuteNextJob(jobQueue);
|
DqnJobQueue_TryExecuteNextJob(&jobQueue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
while (DqnJobQueue_TryExecuteNextJob(jobQueue))
|
while (DqnJobQueue_TryExecuteNextJob(&jobQueue))
|
||||||
;
|
;
|
||||||
|
|
||||||
for (i32 i = 0; i < DQN_ARRAY_COUNT(globalDebugCounterMemoize); i++)
|
for (i32 i = 0; i < DQN_ARRAY_COUNT(globalDebugCounterMemoize); i++)
|
||||||
DQN_ASSERT(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);
|
printf("\nJobQueueTest(): Final incremented value: %d\n", globalDebugCounter);
|
||||||
|
@ -21,7 +21,7 @@ Global
|
|||||||
Release|x86 = Release|x86
|
Release|x86 = Release|x86
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
{87785192-6F49-4F85-AA0D-F0AFA5CCCDDA}.Release|x86.ActiveCfg = Release|x86
|
{87785192-6F49-4F85-AA0D-F0AFA5CCCDDA}.Release|x86.ActiveCfg = Release|x64
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
Loading…
Reference in New Issue
Block a user