Expose job queue, update init function
This commit is contained in:
		
							parent
							
								
									f9de41b6c0
								
							
						
					
					
						commit
						45bc637773
					
				
							
								
								
									
										141
									
								
								dqn.h
									
									
									
									
									
								
							
							
						
						
									
										141
									
								
								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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user