33 #ifndef FIFTYONE_DEGREES_THREADING_INCLUDED 34 #define FIFTYONE_DEGREES_THREADING_INCLUDED 40 #define EXTERNAL extern "C" 58 #define FIFTYONE_DEGREES_THREAD_ROUTINE LPTHREAD_START_ROUTINE 60 typedef void*(*FIFTYONE_DEGREES_THREAD_ROUTINE)(
void*);
64 #if !defined(DEBUG) && !defined(_DEBUG) && !defined(NDEBUG) 71 #pragma intrinsic (_InterlockedIncrement) 72 #pragma intrinsic (_InterlockedDecrement) 120 typedef struct fiftyone_degrees_signal_t {
170 #define FIFTYONE_DEGREES_THREAD HANDLE 172 #define FIFTYONE_DEGREES_THREAD pthread_t 180 #define FIFTYONE_DEGREES_SIGNAL_CREATE(s) s = fiftyoneDegreesSignalCreate() 186 #define FIFTYONE_DEGREES_SIGNAL_CLOSE(s) fiftyoneDegreesSignalClose(s) 192 #define FIFTYONE_DEGREES_SIGNAL_SET(s) fiftyoneDegreesSignalSet(s) 198 #define FIFTYONE_DEGREES_SIGNAL_WAIT(s) fiftyoneDegreesSignalWait(s) 205 #define FIFTYONE_DEGREES_MUTEX_CREATE(m) m = CreateMutex(NULL,FALSE,NULL) 207 #define FIFTYONE_DEGREES_MUTEX_CREATE(m) fiftyoneDegreesMutexCreate(&m) 215 #define FIFTYONE_DEGREES_MUTEX_CLOSE(m) if (m != NULL) { CloseHandle(m); } 217 #define FIFTYONE_DEGREES_MUTEX_CLOSE(m) fiftyoneDegreesMutexClose(&m) 225 #define FIFTYONE_DEGREES_MUTEX_LOCK(m) WaitForSingleObject(*m, INFINITE) 227 #define FIFTYONE_DEGREES_MUTEX_LOCK(m) fiftyoneDegreesMutexLock(m) 235 #define FIFTYONE_DEGREES_MUTEX_UNLOCK(m) ReleaseMutex(*m) 237 #define FIFTYONE_DEGREES_MUTEX_UNLOCK(m) fiftyoneDegreesMutexUnlock(m) 246 #define FIFTYONE_DEGREES_MUTEX_VALID(m) (*m != NULL) 248 #define FIFTYONE_DEGREES_MUTEX_VALID(m) fiftyoneDegreesMutexValid(m) 259 #define FIFTYONE_DEGREES_THREAD_CREATE(t, m, s) t = \ 260 (FIFTYONE_DEGREES_THREAD)CreateThread(NULL, 0, m, s, 0, NULL) 262 #define FIFTYONE_DEGREES_THREAD_CREATE(t, m, s) pthread_create(&t, NULL, m, s) 271 #define FIFTYONE_DEGREES_THREAD_JOIN(t) WaitForSingleObject(t, INFINITE) 273 #define FIFTYONE_DEGREES_THREAD_JOIN(t) pthread_join(t, NULL) 281 #define FIFTYONE_DEGREES_THREAD_CLOSE(t) CloseHandle(t) 283 #define FIFTYONE_DEGREES_THREAD_CLOSE(t) 290 #define FIFTYONE_DEGREES_THREAD_EXIT ExitThread(0) 292 #define FIFTYONE_DEGREES_THREAD_EXIT pthread_exit(NULL) 301 #define FIFTYONE_DEGREES_INTERLOCK_INC(v) _InterlockedIncrement(v) 303 #define FIFTYONE_DEGREES_INTERLOCK_INC(v) (__sync_add_and_fetch(v, 1)) 312 #define FIFTYONE_DEGREES_INTERLOCK_DEC(v) _InterlockedDecrement(v) 314 #define FIFTYONE_DEGREES_INTERLOCK_DEC(v) (__sync_add_and_fetch(v, -1)) 326 #define FIFTYONE_DEGREES_INTERLOCK_EXCHANGE(d,e,c) \ 327 InterlockedCompareExchange(&d, e, c) 329 #define FIFTYONE_DEGREES_INTERLOCK_EXCHANGE(d,e,c) \ 330 __sync_val_compare_and_swap(&d,c,e) 342 #define FIFTYONE_DEGREES_INTERLOCK_EXCHANGE_64(d,e,c) \ 343 InterlockedCompareExchange64((volatile __int64*)&d, (__int64)e, (__int64)c) 345 #define FIFTYONE_DEGREES_INTERLOCK_EXCHANGE_64(d,e,c) \ 346 FIFTYONE_DEGREES_INTERLOCK_EXCHANGE(d,e,c) 358 #define FIFTYONE_DEGREES_INTERLOCK_EXCHANGE_PTR(d,e,c) \ 359 InterlockedCompareExchangePointer((volatile PVOID*)&d,e,c) 361 #define FIFTYONE_DEGREES_INTERLOCK_EXCHANGE_PTR(d,e,c) \ 362 FIFTYONE_DEGREES_INTERLOCK_EXCHANGE(d,e,c) 388 const void* exchange,
392 __asm __volatile(
"lock cmpxchg16b %0; setz %3" 393 :
"+m" (*(
void**)destination),
394 "=a" (((
void**)compare)[0]),
395 "=d" (((
void**)compare)[1]),
397 :
"a" (((
void**)compare)[0]),
398 "d" (((
void**)compare)[1]),
399 "b" (((
const void**)exchange)[0]),
400 "c" (((
const void**)exchange)[1])
417 typedef struct fiftyone_degrees_interlock_dw_type_t {
421 #define FIFTYONE_DEGREES_INTERLOCK_EXCHANGE_DW(d,e,c) \ 422 InterlockedCompareExchange128(&d.low, e.high, e.low, &c.low) 424 typedef struct fiftyone_degrees_interlock_dw_type_t {
427 #define FIFTYONE_DEGREES_INTERLOCK_EXCHANGE_DW(d,e,c) \ 428 InterlockedCompareExchange64(&d.value, e.value, c.value) == c.value 431 #if defined(__x86_64__) || defined(__aarch64__) 432 typedef struct fiftyone_degrees_interlock_dw_type_t {
437 typedef struct fiftyone_degrees_interlock_dw_type_t {
441 #define FIFTYONE_DEGREES_INTERLOCK_EXCHANGE_DW(d,e,c) \ 442 (sizeof(void*) == 8 ? \ 443 __fod_sync_bool_compare_and_swap_16((void*)&d, (void*)&e, (void*)&c) : \ 444 __sync_bool_compare_and_swap((int64_t*)&d, *((int64_t*)&c), *((int64_t*)&e))) void fiftyoneDegreesMutexCreate(fiftyoneDegreesMutex *mutex)
Initialises the mutex passed to the method.
void fiftyoneDegreesMutexUnlock(fiftyoneDegreesMutex *mutex)
Unlocks the mutex passed to the method.
pthread_mutex_t mutex
Mutex for the signal.
Definition: threading.h:123
void fiftyoneDegreesMutexLock(fiftyoneDegreesMutex *mutex)
Locks the mutex passed to the method.
fiftyoneDegreesSignal * fiftyoneDegreesSignalCreate()
Initialises the signal pointer by setting the condition first followed by the mutex if the condition ...
pthread_mutex_t fiftyoneDegreesMutex
MUTEX AND THREADING MACROS.
Definition: threading.h:90
void fiftyoneDegreesMutexClose(fiftyoneDegreesMutex *mutex)
Closes the mutex passed to the method.
pthread_cond_t cond
Condition variable for the signal.
Definition: threading.h:122
A signal used to limit the number of items that can be created by the pool.
Definition: threading.h:120
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.
static __inline int __fod_sync_bool_compare_and_swap_16(void *destination, const void *exchange, void *compare)
Implements the __sync_bool_compare_and_swap_16 function which is often not implemtned by the compiler...
Definition: threading.h:386
void fiftyoneDegreesSignalClose(fiftyoneDegreesSignal *signal)
Closes the signal ensuring there is a lock on the signal before destroying the signal.
volatile bool wait
Flag indicating if the thread should wait.
Definition: threading.h:121
void fiftyoneDegreesSignalSet(fiftyoneDegreesSignal *signal)
If the signal has not been destroyed then sends a signal to a waiting thread that the signal has been...
Double width (64 or 128 depending on the architecture) compare and exchange.
Definition: threading.h:437