51Degrees Device Detection C/C++  4.1

A device detection library that is used natively or by 51Degrees products

Threading

Detailed Description

Defines multi threading macros if the FIFTYONE_DEGREES_NO_THREADING compiler directive is not explicitly requesting single threaded operation.

Collaboration diagram for Threading:

Structs

struct  fiftyoneDegreesSignal
A signal used to limit the number of items that can be created by the pool. More...

Macros

#define  FIFTYONE_DEGREES_THREAD   pthread_t
A thread created with the FIFTYONE_DEGREES_THREAD_CREATE macro.
#define  FIFTYONE_DEGREES_SIGNAL_CREATE(s)   s = fiftyoneDegreesSignalCreate()
Creates a new signal that can be used to wait for other operations to complete before continuing. More...
#define  FIFTYONE_DEGREES_SIGNAL_CLOSE(s)   fiftyoneDegreesSignalClose(s)
Frees the handle provided to the macro. More...
#define  FIFTYONE_DEGREES_SIGNAL_SET(s)   fiftyoneDegreesSignalSet(s)
Signals a thread waiting for the signal to proceed. More...
#define  FIFTYONE_DEGREES_SIGNAL_WAIT(s)   fiftyoneDegreesSignalWait(s)
Waits for the signal to become set by another thread. More...
#define  FIFTYONE_DEGREES_MUTEX_CREATE(m)   fiftyoneDegreesMutexCreate(&m)
Creates a new mutex at the pointer provided. More...
#define  FIFTYONE_DEGREES_MUTEX_CLOSE(m)   fiftyoneDegreesMutexClose(&m)
Frees the mutex at the pointer provided. More...
#define  FIFTYONE_DEGREES_MUTEX_LOCK(m)   fiftyoneDegreesMutexLock(m)
Locks the mutex at the pointer provided. More...
#define  FIFTYONE_DEGREES_MUTEX_UNLOCK(m)   fiftyoneDegreesMutexUnlock(m)
Unlocks the mutex at the pointer provided. More...
#define  FIFTYONE_DEGREES_MUTEX_VALID(m)   fiftyoneDegreesMutexValid(m)
Returns true if the mutex is valid. More...
#define  FIFTYONE_DEGREES_THREAD_CREATE(t, m, s)   pthread_create(&t, NULL, m, s)
Creates a new thread with the following parameters: More...
#define  FIFTYONE_DEGREES_THREAD_JOIN(t)   pthread_join(t, NULL)
Joins the thread provided to the current thread waiting indefinitely for the operation to complete. More...
#define  FIFTYONE_DEGREES_THREAD_CLOSE(t)
Closes the thread passed to the macro. More...
#define  FIFTYONE_DEGREES_THREAD_EXIT   pthread_exit(NULL)
Exits the calling thread.
#define  FIFTYONE_DEGREES_INTERLOCK_INC(v)   (__sync_add_and_fetch(v, 1))
Increments the value and returns the final value. More...
#define  FIFTYONE_DEGREES_INTERLOCK_DEC(v)   (__sync_add_and_fetch(v, -1))
Decrements the value and returns the final value. More...
#define  FIFTYONE_DEGREES_INTERLOCK_EXCHANGE(d, e, c)   __sync_val_compare_and_swap(&d,c,e)
Replaces the destination value with the exchange value, only if the destination value matched the comparand. More...
#define  FIFTYONE_DEGREES_INTERLOCK_EXCHANGE_64(d, e, c)   FIFTYONE_DEGREES_INTERLOCK_EXCHANGE(d,e,c)
64 bit compare and swap. More...
#define  FIFTYONE_DEGREES_INTERLOCK_EXCHANGE_PTR(d, e, c)   FIFTYONE_DEGREES_INTERLOCK_EXCHANGE(d,e,c)
Replaces the destination pointer with the exchange pointer, only if the destination pointer matched the comparand. More...
#define  FIFTYONE_DEGREES_INTERLOCK_EXCHANGE_PTR_DW(d, e, c)
Double width (64 or 128 depending on the architecture) compare and exchange. More...

Typedefs

typedef void *(*  FIFTYONE_DEGREES_THREAD_ROUTINE) (void *)
A thread method passed to the FIFTYONE_DEGREES_THREAD_CREATE macro.
typedef pthread_mutex_t  fiftyoneDegreesMutex
MUTEX AND THREADING MACROS. More...

Functions

bool  fiftyoneDegreesThreadingGetIsThreadSafe ()
Determines if the methods that should be thread safe have been compiled so they are thread safe. More...
void  fiftyoneDegreesMutexCreate (fiftyoneDegreesMutex *mutex)
Initialises the mutex passed to the method. More...
void  fiftyoneDegreesMutexClose (fiftyoneDegreesMutex *mutex)
Closes the mutex passed to the method. More...
void  fiftyoneDegreesMutexLock (fiftyoneDegreesMutex *mutex)
Locks the mutex passed to the method. More...
void  fiftyoneDegreesMutexUnlock (fiftyoneDegreesMutex *mutex)
Unlocks the mutex passed to the method. More...
fiftyoneDegreesSignal *  fiftyoneDegreesSignalCreate ()
Initialises the signal pointer by setting the condition first followed by the mutex if the condition was set correctly. More...
void  fiftyoneDegreesSignalClose (fiftyoneDegreesSignal *signal)
Closes the signal ensuring there is a lock on the signal before destroying the signal. More...
void  fiftyoneDegreesSignalSet (fiftyoneDegreesSignal *signal)
If the signal has not been destroyed then sends a signal to a waiting thread that the signal has been set and one can continue. More...
void  fiftyoneDegreesSignalWait (fiftyoneDegreesSignal *signal)
Wait for a signal to be set. More...
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. More...

Macro Definition Documentation

◆ FIFTYONE_DEGREES_INTERLOCK_DEC

#define FIFTYONE_DEGREES_INTERLOCK_DEC (   v )    (__sync_add_and_fetch(v, -1))

Decrements the value and returns the final value.

Parameters
v - the value to decrement
Returns
value after decrementing

◆ FIFTYONE_DEGREES_INTERLOCK_EXCHANGE

#define FIFTYONE_DEGREES_INTERLOCK_EXCHANGE (   d,
  e,
  c  
)    __sync_val_compare_and_swap(&d,c,e)

Replaces the destination value with the exchange value, only if the destination value matched the comparand.

Returns the value of d before the swap.

Parameters
d - the destination to swap
e - the exchange value
c - the comparand

◆ FIFTYONE_DEGREES_INTERLOCK_EXCHANGE_64

#define FIFTYONE_DEGREES_INTERLOCK_EXCHANGE_64 (   d,
  e,
  c  
)    FIFTYONE_DEGREES_INTERLOCK_EXCHANGE(d,e,c)

64 bit compare and swap.

Replaces the destination value with the exchange value, only if the destination value matched the comparand. Returns the value of d before the swap.

Parameters
d - the destination to swap
e - the exchange value
c - the comparand

◆ FIFTYONE_DEGREES_INTERLOCK_EXCHANGE_PTR

#define FIFTYONE_DEGREES_INTERLOCK_EXCHANGE_PTR (   d,
  e,
  c  
)    FIFTYONE_DEGREES_INTERLOCK_EXCHANGE(d,e,c)

Replaces the destination pointer with the exchange pointer, only if the destination pointer matched the comparand.

Returns the value of d before the swap.

Parameters
d - the destination to swap
e - the exchange value
c - the comparand

◆ FIFTYONE_DEGREES_INTERLOCK_EXCHANGE_PTR_DW

#define FIFTYONE_DEGREES_INTERLOCK_EXCHANGE_PTR_DW (   d,
  e,
  c  
)
Value:
(sizeof(void*) == 8 ? \
__fod_sync_bool_compare_and_swap_16((void*)d, (void*)&e, (void*)&c) : \
__sync_bool_compare_and_swap((long*)d, *((long*)&c), *((long*)&e)))
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:390

Double width (64 or 128 depending on the architecture) compare and exchange.

Replaces the destination value with the exchange value, only if the destination value matched the comparand. Returns true if the value was exchanged.

Parameters
d - the destination to swap
e - the exchange value
c - the comparand

◆ FIFTYONE_DEGREES_INTERLOCK_INC

#define FIFTYONE_DEGREES_INTERLOCK_INC (   v )    (__sync_add_and_fetch(v, 1))

Increments the value and returns the final value.

Parameters
v - the value to decrement
Returns
value after incrementing

◆ FIFTYONE_DEGREES_MUTEX_CLOSE

#define FIFTYONE_DEGREES_MUTEX_CLOSE (   m )    fiftyoneDegreesMutexClose(&m)

Frees the mutex at the pointer provided.

Parameters
m - mutex to close

◆ FIFTYONE_DEGREES_MUTEX_CREATE

#define FIFTYONE_DEGREES_MUTEX_CREATE (   m )    fiftyoneDegreesMutexCreate(&m)

Creates a new mutex at the pointer provided.

Parameters
m - mutex to create

◆ FIFTYONE_DEGREES_MUTEX_LOCK

#define FIFTYONE_DEGREES_MUTEX_LOCK (   m )    fiftyoneDegreesMutexLock(m)

Locks the mutex at the pointer provided.

Parameters
m - mutex to lock

◆ FIFTYONE_DEGREES_MUTEX_UNLOCK

#define FIFTYONE_DEGREES_MUTEX_UNLOCK (   m )    fiftyoneDegreesMutexUnlock(m)

Unlocks the mutex at the pointer provided.

Parameters
m - mutex to unlock

◆ FIFTYONE_DEGREES_MUTEX_VALID

#define FIFTYONE_DEGREES_MUTEX_VALID (   m )    fiftyoneDegreesMutexValid(m)

Returns true if the mutex is valid.

Parameters
m - mutex to check
Returns
true if valid

◆ FIFTYONE_DEGREES_SIGNAL_CLOSE

#define FIFTYONE_DEGREES_SIGNAL_CLOSE (   s )    fiftyoneDegreesSignalClose(s)

Frees the handle provided to the macro.

Parameters
s - signal to close

◆ FIFTYONE_DEGREES_SIGNAL_CREATE

#define FIFTYONE_DEGREES_SIGNAL_CREATE (   s )    s = fiftyoneDegreesSignalCreate()

Creates a new signal that can be used to wait for other operations to complete before continuing.

Parameters
s - signal to create

◆ FIFTYONE_DEGREES_SIGNAL_SET

#define FIFTYONE_DEGREES_SIGNAL_SET (   s )    fiftyoneDegreesSignalSet(s)

Signals a thread waiting for the signal to proceed.

Parameters
s - signal to set

◆ FIFTYONE_DEGREES_SIGNAL_WAIT

#define FIFTYONE_DEGREES_SIGNAL_WAIT (   s )    fiftyoneDegreesSignalWait(s)

Waits for the signal to become set by another thread.

Parameters
s - signal to wait on

◆ FIFTYONE_DEGREES_THREAD_CLOSE

#define FIFTYONE_DEGREES_THREAD_CLOSE (   t )

Closes the thread passed to the macro.

Parameters
t - thread to close

◆ FIFTYONE_DEGREES_THREAD_CREATE

#define FIFTYONE_DEGREES_THREAD_CREATE (   t,
  m,
  s  
)    pthread_create(&t, NULL, m, s)

Creates a new thread with the following parameters:

Parameters
t - pointer to FIFTYONE_DEGREES_THREAD memory
m - the method to call when the thread runs
s - pointer to the state data to pass to the method
Returns
new thread

◆ FIFTYONE_DEGREES_THREAD_JOIN

#define FIFTYONE_DEGREES_THREAD_JOIN (   t )    pthread_join(t, NULL)

◆ FIFTYONE_DEGREES_THREAD_CREATE

#define FIFTYONE_DEGREES_THREAD_CREATE (   t,
  m,
  s  
)    pthread_create(&t, NULL, m, s)

Creates a new thread with the following parameters:

Parameters
t - pointer to FIFTYONE_DEGREES_THREAD memory
m - the method to call when the thread runs
s - pointer to the state data to pass to the method
Returns
new thread

◆ FIFTYONE_DEGREES_THREAD_JOIN

#define FIFTYONE_DEGREES_THREAD_JOIN (   t )    pthread_join(t, NULL)

Joins the thread provided to the current thread waiting indefinitely for the operation to complete.

Parameters
t - pointer to a previously created thread

Typedef Documentation

◆ fiftyoneDegreesMutex

typedef pthread_mutex_t fiftyoneDegreesMutex

MUTEX AND THREADING MACROS.

Mutex used to synchronise access to data structures that could be used in parallel in a multi threaded environment.

Function Documentation

◆ __fod_sync_bool_compare_and_swap_16()

static __inline int __fod_sync_bool_compare_and_swap_16 ( void *   destination,
const void *   exchange,
void *   compare  
)
static

Implements the __sync_bool_compare_and_swap_16 function which is often not implemtned by the compiler.

This uses the cmpxchg16b instruction from the x86-64 instruction set, the same instruction as the InterlockedCompareExchange128 implementation (see https://docs.microsoft.com/en-us/cpp/intrinsics/interlockedcompareexchange128?view=vs-2019#remarks). It is therefore supported by modern Intel and AMD CPUs. However, most ARM chips will not support this. For full details of the cmpxchg16b instruction, see the manual: https://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-instruction-set-reference-manual-325383.pdf and other example implementations: https://github.com/ivmai/libatomic_ops/blob/release-7_2/src/atomic_ops/sysdeps/gcc/x86_64.h#L148 https://github.com/haproxy/haproxy/blob/a7bf57352059277239794950f9aac33d05741f1a/include/common/hathreads.h#L1000

Parameters
destination - memory location to be replaced if the compare is true
exchange - memory to copy to the destination if the compare is true
compare - memory to compare to destination.
Returns
1 if all 16 bytes of destination and compare were equal and destination was replaced, otherwise 0

◆ fiftyoneDegreesMutexClose()

void fiftyoneDegreesMutexClose ( fiftyoneDegreesMutex *   mutex )

Closes the mutex passed to the method.

Parameters
mutex - to be closed.

◆ fiftyoneDegreesMutexCreate()

void fiftyoneDegreesMutexCreate ( fiftyoneDegreesMutex *   mutex )

Initialises the mutex passed to the method.

Parameters
mutex - to be initialised.

◆ fiftyoneDegreesMutexLock()

void fiftyoneDegreesMutexLock ( fiftyoneDegreesMutex *   mutex )

Locks the mutex passed to the method.

Parameters
mutex - to be locked.

◆ fiftyoneDegreesMutexUnlock()

void fiftyoneDegreesMutexUnlock ( fiftyoneDegreesMutex *   mutex )

Unlocks the mutex passed to the method.

Parameters
mutex - to be unlocked.

◆ fiftyoneDegreesSignalClose()

void fiftyoneDegreesSignalClose ( fiftyoneDegreesSignal *   signal )

Closes the signal ensuring there is a lock on the signal before destroying the signal.

This means that no other process can be waiting on the signal before it is destroyed. The destroyed field of the signal structure is set to true after the condition is destroyed. All methods that could subsequently try and get a lock on the signal MUST check the destroyed field before trying to get the lock.

Parameters
signal - to be closed.

◆ fiftyoneDegreesSignalCreate()

fiftyoneDegreesSignal* fiftyoneDegreesSignalCreate ( )

Initialises the signal pointer by setting the condition first followed by the mutex if the condition was set correctly.

Destroyed is set to false to indicate to the other methods that the signal is still valid. The memory used by the signal should be part of another structure and will be released when that structure is released. If there is a problem creating the mutex the condition is also released.

Returns
new signal

◆ fiftyoneDegreesSignalSet()

void fiftyoneDegreesSignalSet ( fiftyoneDegreesSignal *   signal )

If the signal has not been destroyed then sends a signal to a waiting thread that the signal has been set and one can continue.

This possible because the condition will auto reset only enabling a signal thread to continue even if multi threads are waiting.

Parameters
signal - to be set.

◆ fiftyoneDegreesSignalWait()

void fiftyoneDegreesSignalWait ( fiftyoneDegreesSignal *   signal )

Wait for a signal to be set.

Only waits for the signal if the signal has not been destroyed. Locks the mutex before the signal is waited for. This ensures only one thread can be waiting on the signal at any one time.

Parameters
signal - pointer to the signal used to wait on.

◆ fiftyoneDegreesThreadingGetIsThreadSafe()

bool fiftyoneDegreesThreadingGetIsThreadSafe ( )

Determines if the methods that should be thread safe have been compiled so they are thread safe.

In single threaded operation compiling without threading using the FIFTYONE_DEGREES_NO_THREADING directive results in performance improvements.

Returns
true if the library is thread safe, otherwise false.
Examples
Hash/ReloadFromFile.cpp, and Hash/ReloadFromMemory.cpp.