33#ifndef FIFTYONE_DEGREES_THREADING_INCLUDED
34#define FIFTYONE_DEGREES_THREADING_INCLUDED
36#ifdef FIFTYONE_DEGREES_IPI_SYMBOLS
37#include "ipiSymbols.h"
59#define FIFTYONE_DEGREES_THREAD_ROUTINE LPTHREAD_START_ROUTINE
61typedef void*(*FIFTYONE_DEGREES_THREAD_ROUTINE)(
void*);
65#if !defined(DEBUG) && !defined(_DEBUG) && !defined(NDEBUG)
71#pragma warning (disable: 5105)
73#pragma warning (default: 5105)
76#pragma intrinsic (_InterlockedIncrement)
77#pragma intrinsic (_InterlockedDecrement)
128typedef struct fiftyone_degrees_signal_t {
178#define FIFTYONE_DEGREES_THREAD HANDLE
180#define FIFTYONE_DEGREES_THREAD pthread_t
188#define FIFTYONE_DEGREES_SIGNAL_CREATE(s) s = fiftyoneDegreesSignalCreate()
194#define FIFTYONE_DEGREES_SIGNAL_CLOSE(s) fiftyoneDegreesSignalClose(s)
200#define FIFTYONE_DEGREES_SIGNAL_SET(s) fiftyoneDegreesSignalSet(s)
206#define FIFTYONE_DEGREES_SIGNAL_WAIT(s) fiftyoneDegreesSignalWait(s)
213#define FIFTYONE_DEGREES_MUTEX_CREATE(m) InitializeSRWLock(&m)
215#define FIFTYONE_DEGREES_MUTEX_CREATE(m) fiftyoneDegreesMutexCreate(&m)
224#define FIFTYONE_DEGREES_MUTEX_CLOSE(m)
226#define FIFTYONE_DEGREES_MUTEX_CLOSE(m) fiftyoneDegreesMutexClose(&m)
234#define FIFTYONE_DEGREES_MUTEX_LOCK(m) AcquireSRWLockExclusive(m)
236#define FIFTYONE_DEGREES_MUTEX_LOCK(m) fiftyoneDegreesMutexLock(m)
244#define FIFTYONE_DEGREES_MUTEX_UNLOCK(m) ReleaseSRWLockExclusive(m)
246#define FIFTYONE_DEGREES_MUTEX_UNLOCK(m) fiftyoneDegreesMutexUnlock(m)
255#define FIFTYONE_DEGREES_MUTEX_VALID(m) (m != NULL)
257#define FIFTYONE_DEGREES_MUTEX_VALID(m) fiftyoneDegreesMutexValid(m)
268#define FIFTYONE_DEGREES_THREAD_CREATE(t, m, s) t = \
269 (FIFTYONE_DEGREES_THREAD)CreateThread(NULL, 0, m, s, 0, NULL)
271#define FIFTYONE_DEGREES_THREAD_CREATE(t, m, s) pthread_create(&t, NULL, m, s)
280#define FIFTYONE_DEGREES_THREAD_JOIN(t) WaitForSingleObject(t, INFINITE)
282#define FIFTYONE_DEGREES_THREAD_JOIN(t) pthread_join(t, NULL)
290#define FIFTYONE_DEGREES_THREAD_CLOSE(t) CloseHandle(t)
292#define FIFTYONE_DEGREES_THREAD_CLOSE(t)
299#define FIFTYONE_DEGREES_THREAD_EXIT ExitThread(0)
301#define FIFTYONE_DEGREES_THREAD_EXIT pthread_exit(NULL)
310#define FIFTYONE_DEGREES_INTERLOCK_INC(v) _InterlockedIncrement(v)
312#define FIFTYONE_DEGREES_INTERLOCK_INC(v) (__atomic_add_fetch(v, 1, __ATOMIC_SEQ_CST))
321#define FIFTYONE_DEGREES_INTERLOCK_DEC(v) _InterlockedDecrement(v)
323#define FIFTYONE_DEGREES_INTERLOCK_DEC(v) (__atomic_add_fetch(v, -1, __ATOMIC_SEQ_CST))
335#define FIFTYONE_DEGREES_INTERLOCK_EXCHANGE(d,e,c) \
336 InterlockedCompareExchange(&d, e, c)
341#define FIFTYONE_DEGREES_INTERLOCK_EXCHANGE(d,e,c) \
342 __sync_val_compare_and_swap(&d,c,e)
354#define FIFTYONE_DEGREES_INTERLOCK_EXCHANGE_64(d,e,c) \
355 InterlockedCompareExchange64((volatile __int64*)&d, (__int64)e, (__int64)c)
357#define FIFTYONE_DEGREES_INTERLOCK_EXCHANGE_64(d,e,c) \
358 FIFTYONE_DEGREES_INTERLOCK_EXCHANGE(d,e,c)
370#define FIFTYONE_DEGREES_INTERLOCK_EXCHANGE_PTR(d,e,c) \
371 InterlockedCompareExchangePointer((volatile PVOID*)&d,e,c)
373#define FIFTYONE_DEGREES_INTERLOCK_EXCHANGE_PTR(d,e,c) \
374 FIFTYONE_DEGREES_INTERLOCK_EXCHANGE(d,e,c)
410typedef struct fiftyone_degrees_interlock_dw_type_t {
414#define FIFTYONE_DEGREES_INTERLOCK_EXCHANGE_DW(d,e,c) \
415 InterlockedCompareExchange128(&d.low, e.high, e.low, &c.low)
417typedef struct fiftyone_degrees_interlock_dw_type_t {
420#define FIFTYONE_DEGREES_INTERLOCK_EXCHANGE_DW(d,e,c) \
421 InterlockedCompareExchange64(&d.value, e.value, c.value) == c.value
424#if (defined(_LP64) || defined(__MINGW64__))
425typedef struct fiftyone_degrees_interlock_dw_type_t {
430typedef struct fiftyone_degrees_interlock_dw_type_t {
434#define FIFTYONE_DEGREES_INTERLOCK_EXCHANGE_DW(d,e,c) \
435 (__atomic_compare_exchange( \
436 (fiftyoneDegreesInterlockDoubleWidth*)&d, \
437 (fiftyoneDegreesInterlockDoubleWidth*)&c, \
438 (fiftyoneDegreesInterlockDoubleWidth*)&e, \
447#define FIFTYONE_DEGREES_IS_LOCK_FREE IsProcessorFeaturePresent(PF_COMPARE_EXCHANGE128)
449#define FIFTYONE_DEGREES_IS_LOCK_FREE true
452#define FIFTYONE_DEGREES_IS_LOCK_FREE __atomic_is_lock_free(sizeof(fiftyoneDegreesInterlockDoubleWidth), NULL)
pthread_mutex_t fiftyoneDegreesMutex
MUTEX AND THREADING MACROS.
Definition threading.h:98
void fiftyoneDegreesMutexUnlock(fiftyoneDegreesMutex *mutex)
Unlocks the mutex passed to the method.
void fiftyoneDegreesSignalClose(fiftyoneDegreesSignal *signal)
Closes the signal ensuring there is a lock on the signal before destroying the signal.
void fiftyoneDegreesMutexCreate(fiftyoneDegreesMutex *mutex)
Initialises the mutex passed to the method.
bool fiftyoneDegreesThreadingGetIsThreadSafe()
Determines if the methods that should be thread safe have been compiled so they are thread safe.
void fiftyoneDegreesSignalWait(fiftyoneDegreesSignal *signal)
Wait for a signal to be set.
void fiftyoneDegreesSignalSet(fiftyoneDegreesSignal *signal)
If the signal has not been destroyed then sends a signal to a waiting thread that the signal has been...
fiftyoneDegreesSignal * fiftyoneDegreesSignalCreate()
Initialises the signal pointer by setting the condition first followed by the mutex if the condition ...
void fiftyoneDegreesMutexClose(fiftyoneDegreesMutex *mutex)
Closes the mutex passed to the method.
void fiftyoneDegreesMutexLock(fiftyoneDegreesMutex *mutex)
Locks the mutex passed to the method.
Double width (64 or 128 depending on the architecture) compare and exchange.
Definition threading.h:430
A signal used to limit the number of items that can be created by the pool.
Definition threading.h:128
pthread_cond_t cond
Condition variable for the signal.
Definition threading.h:130
pthread_mutex_t mutex
Mutex for the signal.
Definition threading.h:131
volatile bool wait
Flag indicating if the thread should wait.
Definition threading.h:129