Make atomic add allow amounts not just +-1
This commit is contained in:
		
							parent
							
								
									fca8db0366
								
							
						
					
					
						commit
						866126e735
					
				
							
								
								
									
										80
									
								
								dqn.h
									
									
									
									
									
								
							
							
						
						
									
										80
									
								
								dqn.h
									
									
									
									
									
								
							| @ -1093,13 +1093,15 @@ typedef struct DqnLock | |||||||
| 	void Release(); | 	void Release(); | ||||||
| 	void Delete (); | 	void Delete (); | ||||||
| 
 | 
 | ||||||
|  | 	// Create a lock guard on the lock this is invoked on.
 | ||||||
| 	struct DqnLockGuard LockGuard(); | 	struct DqnLockGuard LockGuard(); | ||||||
| #endif | #endif | ||||||
| } DqnLock; | } DqnLock; | ||||||
| 
 | 
 | ||||||
| #if defined(DQN_CPP_MODE) | #if defined(DQN_CPP_MODE) | ||||||
| // Lock guard automatically acquires a lock on construction and releases a lock
 | // Lock guard automatically acquires a lock on construction and releases the associated lock on
 | ||||||
| // on destruction.
 | // destruction. If the lock is unable to be acquired, the program blocks at construction until it
 | ||||||
|  | // can.
 | ||||||
| struct DqnLockGuard | struct DqnLockGuard | ||||||
| { | { | ||||||
| 	// lock: Takes a pointer to a pre-existing and already initialised lock
 | 	// lock: Takes a pointer to a pre-existing and already initialised lock
 | ||||||
| @ -1153,8 +1155,8 @@ typedef struct DqnJobQueue | |||||||
| 	u32     size; | 	u32     size; | ||||||
| 
 | 
 | ||||||
| 	// NOTE(doyle): Modified by main+worker threads
 | 	// NOTE(doyle): Modified by main+worker threads
 | ||||||
| 	u32   volatile jobToExecuteIndex; | 	i32   volatile jobToExecuteIndex; | ||||||
| 	u32   volatile numJobsToComplete; | 	i32   volatile numJobsToComplete; | ||||||
| 
 | 
 | ||||||
| #if defined(DQN_WIN32_PLATFORM) | #if defined(DQN_WIN32_PLATFORM) | ||||||
| 	void *semaphore; | 	void *semaphore; | ||||||
| @ -1167,9 +1169,8 @@ typedef struct DqnJobQueue | |||||||
| 
 | 
 | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| 	// NOTE: Modified by main thread ONLY
 | 	// NOTE: Modified by main thread ONLY
 | ||||||
| 	u32 volatile jobInsertIndex; | 	i32 volatile jobInsertIndex; | ||||||
| 
 | 
 | ||||||
| #if defined(DQN_CPP_MODE) | #if defined(DQN_CPP_MODE) | ||||||
| 	bool Init             (const DqnJob *const jobList_, const u32 jobListSize, const u32 numThreads); | 	bool Init             (const DqnJob *const jobList_, const u32 jobListSize, const u32 numThreads); | ||||||
| @ -1217,15 +1218,11 @@ DQN_FILE_SCOPE bool DqnJobQueue_AllJobsComplete  (DqnJobQueue *const queue); | |||||||
| // swapVal:    The value to put into "dest", IF at point of read, "dest" has the value of "compareVal"
 | // swapVal:    The value to put into "dest", IF at point of read, "dest" has the value of "compareVal"
 | ||||||
| // compareVal: The value to check in "dest"
 | // compareVal: The value to check in "dest"
 | ||||||
| // return:     Return the original value that was in "dest"
 | // return:     Return the original value that was in "dest"
 | ||||||
| DQN_FILE_SCOPE u32 DqnAtomic_CompareSwap32(u32 volatile *const dest, const u32 swapVal, const u32 compareVal); | DQN_FILE_SCOPE i32 DqnAtomic_CompareSwap32(i32 volatile *const dest, const i32 swapVal, const i32 compareVal); | ||||||
| 
 | 
 | ||||||
| // Increment the value at src by 1
 | // Add "value" to src
 | ||||||
| // return: The incremented value
 | // return: The new value at src
 | ||||||
| DQN_FILE_SCOPE u32 DqnAtomic_Add32(u32 volatile *const src); | DQN_FILE_SCOPE i32 DqnAtomic_Add32(i32 volatile *const src, const i32 value); | ||||||
| 
 |  | ||||||
| // Decrement the value at src by 1
 |  | ||||||
| // return: The decremented value
 |  | ||||||
| DQN_FILE_SCOPE u32 DqnAtomic_Sub32(u32 volatile *const src); |  | ||||||
| 
 | 
 | ||||||
| ////////////////////////////////////////////////////////////////////////////////
 | ////////////////////////////////////////////////////////////////////////////////
 | ||||||
| // XPlatform > #DqnPlatform Public API - Common Platform API Helpers
 | // XPlatform > #DqnPlatform Public API - Common Platform API Helpers
 | ||||||
| @ -6426,12 +6423,12 @@ DQN_FILE_SCOPE bool DqnJobQueue_Init(DqnJobQueue *const queue, DqnJob *const job | |||||||
| 
 | 
 | ||||||
| DQN_FILE_SCOPE bool DqnJobQueue_AddJob(DqnJobQueue *const queue, const DqnJob job) | DQN_FILE_SCOPE bool DqnJobQueue_AddJob(DqnJobQueue *const queue, const DqnJob job) | ||||||
| { | { | ||||||
| 	u32 newJobInsertIndex = (queue->jobInsertIndex + 1) % queue->size; | 	i32 newJobInsertIndex = (queue->jobInsertIndex + 1) % queue->size; | ||||||
| 	if (newJobInsertIndex == queue->jobToExecuteIndex) return false; | 	if (newJobInsertIndex == queue->jobToExecuteIndex) return false; | ||||||
| 
 | 
 | ||||||
| 	queue->jobList[queue->jobInsertIndex] = job; | 	queue->jobList[queue->jobInsertIndex] = job; | ||||||
| 
 | 
 | ||||||
| 	DqnAtomic_Add32(&queue->numJobsToComplete); | 	DqnAtomic_Add32(&queue->numJobsToComplete, 1); | ||||||
| 	DQN_ASSERT(DqnJobQueueInternal_ReleaseSemaphore(queue)); | 	DQN_ASSERT(DqnJobQueueInternal_ReleaseSemaphore(queue)); | ||||||
| 
 | 
 | ||||||
| 	queue->jobInsertIndex = newJobInsertIndex; | 	queue->jobInsertIndex = newJobInsertIndex; | ||||||
| @ -6448,11 +6445,11 @@ DQN_FILE_SCOPE bool DqnJobQueue_TryExecuteNextJob(DqnJobQueue *const queue) | |||||||
| { | { | ||||||
| 	if (!queue) return false; | 	if (!queue) return false; | ||||||
| 
 | 
 | ||||||
| 	u32 originalJobToExecute = queue->jobToExecuteIndex; | 	i32 originalJobToExecute = queue->jobToExecuteIndex; | ||||||
| 	if (originalJobToExecute != queue->jobInsertIndex) | 	if (originalJobToExecute != queue->jobInsertIndex) | ||||||
| 	{ | 	{ | ||||||
| 		u32 newJobIndexForNextThread = (originalJobToExecute + 1) % queue->size; | 		i32 newJobIndexForNextThread = (originalJobToExecute + 1) % queue->size; | ||||||
| 		u32 index = DqnAtomic_CompareSwap32(&queue->jobToExecuteIndex, newJobIndexForNextThread, | 		i32 index = DqnAtomic_CompareSwap32(&queue->jobToExecuteIndex, newJobIndexForNextThread, | ||||||
| 		                                    originalJobToExecute); | 		                                    originalJobToExecute); | ||||||
| 
 | 
 | ||||||
| 		// NOTE: If we weren't successful at the interlock, another thread has
 | 		// NOTE: If we weren't successful at the interlock, another thread has
 | ||||||
| @ -6463,7 +6460,7 @@ DQN_FILE_SCOPE bool DqnJobQueue_TryExecuteNextJob(DqnJobQueue *const queue) | |||||||
| 		{ | 		{ | ||||||
| 			DqnJob job = queue->jobList[index]; | 			DqnJob job = queue->jobList[index]; | ||||||
| 			job.callback(queue, job.userData); | 			job.callback(queue, job.userData); | ||||||
| 			DqnAtomic_Sub32(&queue->numJobsToComplete); | 			DqnAtomic_Add32(&queue->numJobsToComplete, -1); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		return true; | 		return true; | ||||||
| @ -6497,13 +6494,17 @@ bool DqnJobQueue::AllJobsComplete  ()                 { return DqnJobQueue_AllJo | |||||||
| ////////////////////////////////////////////////////////////////////////////////
 | ////////////////////////////////////////////////////////////////////////////////
 | ||||||
| // XPlatform > #DqnAtomic Implementation
 | // XPlatform > #DqnAtomic Implementation
 | ||||||
| ////////////////////////////////////////////////////////////////////////////////
 | ////////////////////////////////////////////////////////////////////////////////
 | ||||||
| DQN_FILE_SCOPE u32 DqnAtomic_CompareSwap32(u32 volatile *const dest, const u32 swapVal, | 
 | ||||||
|                                            const u32 compareVal) |  | ||||||
| { |  | ||||||
| 	u32 result = 0; |  | ||||||
| #if defined(DQN_WIN32_PLATFORM) | #if defined(DQN_WIN32_PLATFORM) | ||||||
| 	DQN_ASSERT(sizeof(LONG) == sizeof(u32)); | 	DQN_COMPILE_ASSERT(sizeof(LONG) == sizeof(i32)); | ||||||
| 	result = (u32)InterlockedCompareExchange((LONG volatile *)dest, (LONG)swapVal, (LONG)compareVal); | #endif | ||||||
|  | 
 | ||||||
|  | DQN_FILE_SCOPE i32 DqnAtomic_CompareSwap32(i32 volatile *const dest, const i32 swapVal, | ||||||
|  |                                            const i32 compareVal) | ||||||
|  | { | ||||||
|  | 	i32 result = 0; | ||||||
|  | #if defined(DQN_WIN32_PLATFORM) | ||||||
|  | 	result = (i32)InterlockedCompareExchange((LONG volatile *)dest, (LONG)swapVal, (LONG)compareVal); | ||||||
| 
 | 
 | ||||||
| #elif defined(DQN_UNIX_PLATFORM) | #elif defined(DQN_UNIX_PLATFORM) | ||||||
| 	result = __sync_val_compare_and_swap(dest, compareVal, swapVal); | 	result = __sync_val_compare_and_swap(dest, compareVal, swapVal); | ||||||
| @ -6515,33 +6516,14 @@ DQN_FILE_SCOPE u32 DqnAtomic_CompareSwap32(u32 volatile *const dest, const u32 s | |||||||
| 	return result; | 	return result; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| DQN_FILE_SCOPE u32 DqnAtomic_Add32(u32 volatile *const src) | DQN_FILE_SCOPE i32 DqnAtomic_Add32(i32 volatile *const src, const i32 value) | ||||||
| { | { | ||||||
| 	u32 result = 0; | 	i32 result = 0; | ||||||
| #if defined(DQN_WIN32_PLATFORM) | #if defined(DQN_WIN32_PLATFORM) | ||||||
| 	DQN_ASSERT(sizeof(LONG) == sizeof(u32)); | 	result = (i32)InterlockedAdd((LONG volatile *)src, value); | ||||||
| 	result = (u32)InterlockedIncrement((LONG volatile *)src); |  | ||||||
| 
 | 
 | ||||||
| #elif defined(DQN_UNIX_PLATFORM) | #elif defined(DQN_UNIX_PLATFORM) | ||||||
| 	result = __sync_add_and_fetch(src, 1); | 	result = __sync_add_and_fetch(src, value); | ||||||
| 
 |  | ||||||
| #else |  | ||||||
| 	#error Unsupported platform |  | ||||||
| 
 |  | ||||||
| #endif |  | ||||||
| 
 |  | ||||||
| 	return result; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| DQN_FILE_SCOPE u32 DqnAtomic_Sub32(u32 volatile *const src) |  | ||||||
| { |  | ||||||
| 	u32 result = 0; |  | ||||||
| #if defined(DQN_WIN32_PLATFORM) |  | ||||||
| 	DQN_ASSERT(sizeof(LONG) == sizeof(u32)); |  | ||||||
| 	result = (u32)InterlockedDecrement((LONG volatile *)src); |  | ||||||
| 
 |  | ||||||
| #elif defined(DQN_UNIX_PLATFORM) |  | ||||||
| 	result = __sync_sub_and_fetch(src, 1); |  | ||||||
| 
 | 
 | ||||||
| #else | #else | ||||||
| 	#error Unsupported platform | 	#error Unsupported platform | ||||||
|  | |||||||
| @ -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