diff options
author | sanine <sanine.not@pm.me> | 2022-10-01 20:59:36 -0500 |
---|---|---|
committer | sanine <sanine.not@pm.me> | 2022-10-01 20:59:36 -0500 |
commit | c5fc66ee58f2c60f2d226868bb1cf5b91badaf53 (patch) | |
tree | 277dd280daf10bf77013236b8edfa5f88708c7e0 /libs/ode-0.16.1/ode/src/threading_atomics_provs.h | |
parent | 1cf9cc3408af7008451f9133fb95af66a9697d15 (diff) |
add ode
Diffstat (limited to 'libs/ode-0.16.1/ode/src/threading_atomics_provs.h')
-rw-r--r-- | libs/ode-0.16.1/ode/src/threading_atomics_provs.h | 194 |
1 files changed, 194 insertions, 0 deletions
diff --git a/libs/ode-0.16.1/ode/src/threading_atomics_provs.h b/libs/ode-0.16.1/ode/src/threading_atomics_provs.h new file mode 100644 index 0000000..3afc7b3 --- /dev/null +++ b/libs/ode-0.16.1/ode/src/threading_atomics_provs.h @@ -0,0 +1,194 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * Threading atomics providers file. * + * Copyright (C) 2011-2019 Oleh Derevenko. All rights reserved. * + * e-mail: odar@eleks.com (change all "a" to "e") * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +/* + * Fake atomics provider for built-in threading support provider. + * OU-based atomics provider for built-in threading support provider. + * + * The classes have been moved into a separate header as they are to be used + * in both WIN and POSIX implementations. + */ + + +#ifndef _ODE_THREADING_ATOMICS_PROVS_H_ +#define _ODE_THREADING_ATOMICS_PROVS_H_ + + +#include <ode/odeconfig.h> +#include <ode/error.h> + + +/************************************************************************/ +/* Fake atomics provider class implementation */ +/************************************************************************/ + +class dxFakeAtomicsProvider +{ +public: + typedef unsigned long atomicord_t; + typedef void *atomicptr_t; + +public: + static void IncrementTargetNoRet(volatile atomicord_t *value_accumulator_ptr) + { + ++(*value_accumulator_ptr); + } + + static void DecrementTargetNoRet(volatile atomicord_t *value_accumulator_ptr) + { + --(*value_accumulator_ptr); + } + + static atomicord_t QueryTargetValue(volatile atomicord_t *value_storage_ptr) + { + return *value_storage_ptr; + } + + template<unsigned type_size> + static sizeint AddValueToTarget(volatile void *value_accumulator_ptr, diffint value_addend); + + static bool CompareExchangeTargetPtr(volatile atomicptr_t *pointer_storage_ptr, + atomicptr_t comparand_value, atomicptr_t new_value) + { + bool exchange_result = false; + + atomicptr_t original_value = *pointer_storage_ptr; + + if (original_value == comparand_value) + { + *pointer_storage_ptr = new_value; + + exchange_result = true; + } + + return exchange_result; + } +}; + +template<> +inline sizeint dxFakeAtomicsProvider::AddValueToTarget<sizeof(dxFakeAtomicsProvider::atomicord_t)>(volatile void *value_accumulator_ptr, diffint value_addend) +{ + atomicord_t original_value = *(volatile atomicord_t *)value_accumulator_ptr; + + *(volatile atomicord_t *)value_accumulator_ptr = original_value + (atomicord_t)value_addend; + + return original_value; +} + +template<> +inline sizeint dxFakeAtomicsProvider::AddValueToTarget<2 * sizeof(dxFakeAtomicsProvider::atomicord_t)>(volatile void *value_accumulator_ptr, diffint value_addend) +{ + atomicptr_t original_value = *(volatile atomicptr_t *)value_accumulator_ptr; + + *(volatile atomicptr_t *)value_accumulator_ptr = (atomicptr_t)((sizeint)original_value + (sizeint)value_addend); + + return (sizeint)original_value; +} + + +#if dBUILTIN_THREADING_IMPL_ENABLED + +/************************************************************************/ +/* dxOUAtomicsProvider class implementation */ +/************************************************************************/ + +#if !dOU_ENABLED +#error OU library must be enabled for this to compile +#elif !dATOMICS_ENABLED +#error OU Atomics must be enabled for this to compile +#endif +#include "odeou.h" + +class dxOUAtomicsProvider +{ +public: + typedef _OU_NAMESPACE::atomicord32 atomicord_t; + typedef _OU_NAMESPACE::atomicptr atomicptr_t; + +public: + static void IncrementTargetNoRet(volatile atomicord_t *value_accumulator_ptr) + { + _OU_NAMESPACE::AtomicIncrementNoResult(value_accumulator_ptr); + } + + static void DecrementTargetNoRet(volatile atomicord_t *value_accumulator_ptr) + { + _OU_NAMESPACE::AtomicDecrementNoResult(value_accumulator_ptr); + } + + static atomicord_t QueryTargetValue(volatile atomicord_t *value_storage_ptr) + { + // Query value with memory barrier before + atomicord_t result_value = *value_storage_ptr; + + if (!_OU_NAMESPACE::AtomicCompareExchange(value_storage_ptr, result_value, result_value)) + { + result_value = *value_storage_ptr; + } + + return result_value; + } + + template<unsigned type_size> + static sizeint AddValueToTarget(volatile void *value_accumulator_ptr, diffint value_addend); + + static bool CompareExchangeTargetPtr(volatile atomicptr_t *pointer_storage_ptr, + atomicptr_t comparand_value, atomicptr_t new_value) + { + return _OU_NAMESPACE::AtomicCompareExchangePointer(pointer_storage_ptr, comparand_value, new_value); + } +}; + +template<> +inline sizeint dxOUAtomicsProvider::AddValueToTarget<sizeof(dxOUAtomicsProvider::atomicord_t)>(volatile void *value_accumulator_ptr, diffint value_addend) +{ + return _OU_NAMESPACE::AtomicExchangeAdd((volatile atomicord_t *)value_accumulator_ptr, (atomicord_t)value_addend); +} + +template<> +inline sizeint dxOUAtomicsProvider::AddValueToTarget<2 * sizeof(dxOUAtomicsProvider::atomicord_t)>(volatile void *value_accumulator_ptr, diffint value_addend) +{ + atomicptr_t original_value; + + while (true) + { + original_value = *(volatile atomicptr_t *)value_accumulator_ptr; + + atomicptr_t new_value = (atomicptr_t)((sizeint)original_value + (sizeint)value_addend); + if (_OU_NAMESPACE::AtomicCompareExchangePointer((volatile atomicptr_t *)value_accumulator_ptr, original_value, new_value)) + { + break; + } + } + + return (sizeint)original_value; +} + + +#endif // #if dBUILTIN_THREADING_IMPL_ENABLED + + +#endif // #ifndef _ODE_THREADING_ATOMICS_PROVS_H_ |