36 #ifndef _ODE_THREADING_ATOMICS_PROVS_H_
37 #define _ODE_THREADING_ATOMICS_PROVS_H_
40 #include <ode/odeconfig.h>
41 #include <ode/error.h>
51 typedef unsigned long atomicord_t;
52 typedef void *atomicptr_t;
55 static void IncrementTargetNoRet(
volatile atomicord_t *value_accumulator_ptr)
57 ++(*value_accumulator_ptr);
60 static void DecrementTargetNoRet(
volatile atomicord_t *value_accumulator_ptr)
62 --(*value_accumulator_ptr);
65 static atomicord_t QueryTargetValue(
volatile atomicord_t *value_storage_ptr)
67 return *value_storage_ptr;
70 template<
unsigned type_size>
71 static size_t AddValueToTarget(
volatile void *value_accumulator_ptr, ptrdiff_t value_addend);
73 static bool CompareExchangeTargetPtr(
volatile atomicptr_t *pointer_storage_ptr,
74 atomicptr_t comparand_value, atomicptr_t new_value)
76 bool exchange_result =
false;
78 atomicptr_t original_value = *pointer_storage_ptr;
80 if (original_value == comparand_value)
82 *pointer_storage_ptr = new_value;
84 exchange_result =
true;
87 return exchange_result;
92 inline size_t dxFakeAtomicsProvider::AddValueToTarget<sizeof(dxFakeAtomicsProvider::atomicord_t)>(
volatile void *value_accumulator_ptr, ptrdiff_t value_addend)
94 atomicord_t original_value = *(
volatile atomicord_t *)value_accumulator_ptr;
96 *(
volatile atomicord_t *)value_accumulator_ptr = original_value + (atomicord_t)value_addend;
98 return original_value;
102 inline size_t dxFakeAtomicsProvider::AddValueToTarget<2 * sizeof(dxFakeAtomicsProvider::atomicord_t)>(
volatile void *value_accumulator_ptr, ptrdiff_t value_addend)
104 atomicptr_t original_value = *(
volatile atomicptr_t *)value_accumulator_ptr;
106 *(
volatile atomicptr_t *)value_accumulator_ptr = (atomicptr_t)((size_t)original_value + (
size_t)value_addend);
108 return (
size_t)original_value;
112 #if dBUILTIN_THREADING_IMPL_ENABLED
119 #error OU library must be enabled for this to compile
120 #elif !dATOMICS_ENABLED
121 #error OU Atomics must be enabled for this to compile
125 class dxOUAtomicsProvider
128 typedef _OU_NAMESPACE::atomicord32 atomicord_t;
129 typedef _OU_NAMESPACE::atomicptr atomicptr_t;
132 static void IncrementTargetNoRet(
volatile atomicord_t *value_accumulator_ptr)
134 _OU_NAMESPACE::AtomicIncrementNoResult(value_accumulator_ptr);
137 static void DecrementTargetNoRet(
volatile atomicord_t *value_accumulator_ptr)
139 _OU_NAMESPACE::AtomicDecrementNoResult(value_accumulator_ptr);
142 static atomicord_t QueryTargetValue(
volatile atomicord_t *value_storage_ptr)
145 atomicord_t result_value = *value_storage_ptr;
147 if (!_OU_NAMESPACE::AtomicCompareExchange(value_storage_ptr, result_value, result_value))
149 result_value = *value_storage_ptr;
155 template<
unsigned type_size>
156 static size_t AddValueToTarget(
volatile void *value_accumulator_ptr, ptrdiff_t value_addend);
158 static bool CompareExchangeTargetPtr(
volatile atomicptr_t *pointer_storage_ptr,
159 atomicptr_t comparand_value, atomicptr_t new_value)
161 return _OU_NAMESPACE::AtomicCompareExchangePointer(pointer_storage_ptr, comparand_value, new_value);
166 inline size_t dxOUAtomicsProvider::AddValueToTarget<sizeof(dxOUAtomicsProvider::atomicord_t)>(
volatile void *value_accumulator_ptr, ptrdiff_t value_addend)
168 return _OU_NAMESPACE::AtomicExchangeAdd((
volatile atomicord_t *)value_accumulator_ptr, (atomicord_t)value_addend);
172 inline size_t dxOUAtomicsProvider::AddValueToTarget<2 * sizeof(dxOUAtomicsProvider::atomicord_t)>(
volatile void *value_accumulator_ptr, ptrdiff_t value_addend)
174 atomicptr_t original_value;
178 original_value = *(
volatile atomicptr_t *)value_accumulator_ptr;
180 atomicptr_t new_value = (atomicptr_t)((
size_t)original_value + (size_t)value_addend);
181 if (_OU_NAMESPACE::AtomicCompareExchangePointer((
volatile atomicptr_t *)value_accumulator_ptr, original_value, new_value))
187 return (
size_t)original_value;
191 #endif // #if dBUILTIN_THREADING_IMPL_ENABLED
194 #endif // #ifndef _ODE_THREADING_ATOMICS_PROVS_H_
Definition: threading_atomics_provs.h:48