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_PROCESSOR_COUNT_MAX (UINT16_MAX - 1)
73#define FIFTYONE_DEGREES_THREAD_ROUTINE LPTHREAD_START_ROUTINE
75typedef void*(*FIFTYONE_DEGREES_THREAD_ROUTINE)(
void*);
79#if !defined(DEBUG) && !defined(_DEBUG) && !defined(NDEBUG)
85#pragma warning (disable: 5105)
87#pragma warning (default: 5105)
90#pragma intrinsic (_InterlockedIncrement)
91#pragma intrinsic (_InterlockedDecrement)
142typedef struct fiftyone_degrees_signal_t {
192#define FIFTYONE_DEGREES_THREAD HANDLE
194#define FIFTYONE_DEGREES_THREAD pthread_t
202#define FIFTYONE_DEGREES_SIGNAL_CREATE(s) s = fiftyoneDegreesSignalCreate()
208#define FIFTYONE_DEGREES_SIGNAL_CLOSE(s) fiftyoneDegreesSignalClose(s)
214#define FIFTYONE_DEGREES_SIGNAL_SET(s) fiftyoneDegreesSignalSet(s)
220#define FIFTYONE_DEGREES_SIGNAL_WAIT(s) fiftyoneDegreesSignalWait(s)
227#define FIFTYONE_DEGREES_MUTEX_CREATE(m) InitializeSRWLock(&m)
229#define FIFTYONE_DEGREES_MUTEX_CREATE(m) fiftyoneDegreesMutexCreate(&m)
238#define FIFTYONE_DEGREES_MUTEX_CLOSE(m)
240#define FIFTYONE_DEGREES_MUTEX_CLOSE(m) fiftyoneDegreesMutexClose(&m)
248#define FIFTYONE_DEGREES_MUTEX_LOCK(m) AcquireSRWLockExclusive(m)
250#define FIFTYONE_DEGREES_MUTEX_LOCK(m) fiftyoneDegreesMutexLock(m)
258#define FIFTYONE_DEGREES_MUTEX_UNLOCK(m) ReleaseSRWLockExclusive(m)
260#define FIFTYONE_DEGREES_MUTEX_UNLOCK(m) fiftyoneDegreesMutexUnlock(m)
269#define FIFTYONE_DEGREES_MUTEX_VALID(m) (m != NULL)
271#define FIFTYONE_DEGREES_MUTEX_VALID(m) fiftyoneDegreesMutexValid(m)
282#define FIFTYONE_DEGREES_THREAD_CREATE(t, m, s) t = \
283 (FIFTYONE_DEGREES_THREAD)CreateThread(NULL, 0, m, s, 0, NULL)
285#define FIFTYONE_DEGREES_THREAD_CREATE(t, m, s) pthread_create(&t, NULL, m, s)
294#define FIFTYONE_DEGREES_THREAD_JOIN(t) WaitForSingleObject(t, INFINITE)
296#define FIFTYONE_DEGREES_THREAD_JOIN(t) pthread_join(t, NULL)
304#define FIFTYONE_DEGREES_THREAD_CLOSE(t) CloseHandle(t)
306#define FIFTYONE_DEGREES_THREAD_CLOSE(t)
313#define FIFTYONE_DEGREES_THREAD_EXIT ExitThread(0)
315#define FIFTYONE_DEGREES_THREAD_EXIT pthread_exit(NULL)
324#define FIFTYONE_DEGREES_INTERLOCK_INC(v) _InterlockedIncrement(v)
326#define FIFTYONE_DEGREES_INTERLOCK_INC(v) (__atomic_add_fetch(v, 1, __ATOMIC_SEQ_CST))
335#define FIFTYONE_DEGREES_INTERLOCK_DEC(v) _InterlockedDecrement(v)
337#define FIFTYONE_DEGREES_INTERLOCK_DEC(v) (__atomic_add_fetch(v, -1, __ATOMIC_SEQ_CST))
349#define FIFTYONE_DEGREES_INTERLOCK_EXCHANGE(d,e,c) \
350 InterlockedCompareExchange(&d, e, c)
355#define FIFTYONE_DEGREES_INTERLOCK_EXCHANGE(d,e,c) \
356 __sync_val_compare_and_swap(&d,c,e)
368#define FIFTYONE_DEGREES_INTERLOCK_EXCHANGE_64(d,e,c) \
369 InterlockedCompareExchange64((volatile __int64*)&d, (__int64)e, (__int64)c)
371#define FIFTYONE_DEGREES_INTERLOCK_EXCHANGE_64(d,e,c) \
372 FIFTYONE_DEGREES_INTERLOCK_EXCHANGE(d,e,c)
384#define FIFTYONE_DEGREES_INTERLOCK_EXCHANGE_PTR(d,e,c) \
385 InterlockedCompareExchangePointer((volatile PVOID*)&d,e,c)
387#define FIFTYONE_DEGREES_INTERLOCK_EXCHANGE_PTR(d,e,c) \
388 FIFTYONE_DEGREES_INTERLOCK_EXCHANGE(d,e,c)
424typedef struct fiftyone_degrees_interlock_dw_type_t {
428#define FIFTYONE_DEGREES_INTERLOCK_EXCHANGE_DW(d,e,c) \
429 InterlockedCompareExchange128(&d.low, e.high, e.low, &c.low)
431typedef struct fiftyone_degrees_interlock_dw_type_t {
434#define FIFTYONE_DEGREES_INTERLOCK_EXCHANGE_DW(d,e,c) \
435 InterlockedCompareExchange64(&d.value, e.value, c.value) == c.value
438#if (defined(_LP64) || defined(__MINGW64__))
439typedef struct fiftyone_degrees_interlock_dw_type_t {
444typedef struct fiftyone_degrees_interlock_dw_type_t {
448#define FIFTYONE_DEGREES_INTERLOCK_EXCHANGE_DW(d,e,c) \
449 (__atomic_compare_exchange( \
450 (fiftyoneDegreesInterlockDoubleWidth*)&d, \
451 (fiftyoneDegreesInterlockDoubleWidth*)&c, \
452 (fiftyoneDegreesInterlockDoubleWidth*)&e, \
461#define FIFTYONE_DEGREES_IS_LOCK_FREE IsProcessorFeaturePresent(PF_COMPARE_EXCHANGE128)
463#define FIFTYONE_DEGREES_IS_LOCK_FREE true
466#define FIFTYONE_DEGREES_IS_LOCK_FREE __atomic_is_lock_free(sizeof(fiftyoneDegreesInterlockDoubleWidth), NULL)
pthread_mutex_t fiftyoneDegreesMutex
MUTEX AND THREADING MACROS.
Definition threading.h:112
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.
uint16_t fiftyoneDegreesThreadingGetProcessorCount()
Gets the number of processors the system has online, which is the default for the number of operation...
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:444
A signal used to limit the number of items that can be created by the pool.
Definition threading.h:142
pthread_cond_t cond
Condition variable for the signal.
Definition threading.h:144
pthread_mutex_t mutex
Mutex for the signal.
Definition threading.h:145
volatile bool wait
Flag indicating if the thread should wait.
Definition threading.h:143