summaryrefslogtreecommitdiffhomepage
path: root/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Atomic.h
diff options
context:
space:
mode:
Diffstat (limited to 'ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Atomic.h')
-rw-r--r--ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Atomic.h196
1 files changed, 196 insertions, 0 deletions
diff --git a/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Atomic.h b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Atomic.h
new file mode 100644
index 0000000..d4d2c3b
--- /dev/null
+++ b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Atomic.h
@@ -0,0 +1,196 @@
+/************************************************************************************
+
+Filename : OVR_Atomic.h
+Content : Contains atomic operations and inline fastest locking
+ functionality. Will contain #ifdefs for OS efficiency.
+ Have non-thread-safe implementaion if not available.
+Created : September 19, 2012
+Notes :
+
+Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved.
+
+Licensed under the Oculus Master SDK License Version 1.0 (the "License");
+you may not use the Oculus VR Rift SDK except in compliance with the License,
+which is provided at the time of installation or download, or which
+otherwise accompanies this software in either electronic or hard copy form.
+
+You may obtain a copy of the License at
+
+https://developer.oculus.com/licenses/oculusmastersdk-1.0
+
+Unless required by applicable law or agreed to in writing, the Oculus VR SDK
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+************************************************************************************/
+
+#ifndef OVR_Atomic_h
+#define OVR_Atomic_h
+
+#include "OVR_Types.h"
+
+#include <atomic>
+
+// Include System thread functionality.
+#if defined(OVR_OS_MS) && !defined(OVR_OS_MS_MOBILE)
+#include "OVR_Win32_IncludeWindows.h"
+#else
+#include <pthread.h>
+#endif
+
+namespace OVR {
+
+//-----------------------------------------------------------------------------------
+// ***** Lock
+
+// Lock is a simplest and most efficient mutual-exclusion lock class.
+// Unlike Mutex, it cannot be waited on.
+
+class Lock {
+#if !defined(OVR_ENABLE_THREADS)
+
+ public:
+ // With no thread support, lock does nothing.
+ inline Lock() {}
+ inline Lock(unsigned) {}
+ inline ~Lock() {}
+ inline void DoLock() {}
+ inline void Unlock() {}
+
+// Windows.
+#elif defined(OVR_OS_MS)
+
+ CRITICAL_SECTION cs;
+
+ public:
+ Lock(unsigned spinCount = 10000); // Mutexes with non-zero spin counts usually result in better
+ // performance.
+ ~Lock();
+ // Locking functions.
+ inline void DoLock() {
+ ::EnterCriticalSection(&cs);
+ }
+ inline void Unlock() {
+ ::LeaveCriticalSection(&cs);
+ }
+ inline bool TryLock() {
+ return (::TryEnterCriticalSection(&cs) == TRUE);
+ }
+#else
+ pthread_mutex_t mutex;
+
+ public:
+ static pthread_mutexattr_t RecursiveAttr;
+ static bool RecursiveAttrInit;
+
+ Lock(unsigned spinCount = 0) // To do: Support spin count, probably via a custom lock
+ // implementation.
+ {
+ OVR_UNUSED(spinCount);
+ if (!RecursiveAttrInit) {
+ pthread_mutexattr_init(&RecursiveAttr);
+ pthread_mutexattr_settype(&RecursiveAttr, PTHREAD_MUTEX_RECURSIVE);
+ RecursiveAttrInit = 1;
+ }
+ pthread_mutex_init(&mutex, &RecursiveAttr);
+ }
+ ~Lock() {
+ pthread_mutex_destroy(&mutex);
+ }
+ inline void DoLock() {
+ pthread_mutex_lock(&mutex);
+ }
+ inline void Unlock() {
+ pthread_mutex_unlock(&mutex);
+ }
+ inline bool TryLock() {
+ return (pthread_mutex_trylock(&mutex) == 0);
+ }
+
+#endif // OVR_ENABLE_THREDS
+
+ public:
+ // Locker class, used for automatic locking
+ class Locker {
+ Lock* pLock;
+
+ public:
+ Locker(Lock* plock) {
+ pLock = plock;
+ if (plock)
+ pLock->DoLock();
+ }
+ ~Locker() {
+ Release();
+ }
+
+ void Release() {
+ if (pLock)
+ pLock->Unlock();
+ pLock = nullptr;
+ }
+ };
+
+ // Unlocker class, used for automatic unlocking
+ class Unlocker {
+ // OVR_NON_COPYABLE(Unlocker);
+ Lock* mLock;
+
+ public:
+ Unlocker(Lock* lock) : mLock(lock) {}
+ ~Unlocker() {
+ Release();
+ }
+ void Release() {
+ if (mLock)
+ mLock->Unlock();
+ mLock = nullptr;
+ }
+ };
+};
+
+//-------------------------------------------------------------------------------------
+// Thin locking wrapper around data
+
+template <class T>
+class LockedData {
+ public:
+ LockedData(Lock& lock) : TheLock(lock) {}
+ LockedData& operator=(const LockedData& /*rhs*/) {
+ OVR_ASSERT(false);
+ return *this;
+ }
+
+ T Get() {
+ Lock::Locker locker(&TheLock);
+ return Instance;
+ }
+
+ void Set(const T& value) {
+ Lock::Locker locker(&TheLock);
+ Instance = value;
+ }
+
+ // Returns true if the value has changed.
+ // Returns false if the value has not changed.
+ bool GetIfChanged(T& value) {
+ Lock::Locker locker(&TheLock);
+
+ if (value != Instance) {
+ value = Instance;
+ return true;
+ }
+
+ return false;
+ }
+
+ protected:
+ T Instance;
+ Lock& TheLock;
+};
+
+} // namespace OVR
+
+#endif