gwnavruntime/kernel/SF_Atomic.h Source File

SF_Atomic.h
Go to the documentation of this file.
1 /*
2 * Copyright 2016 Autodesk, Inc. All rights reserved.
3 * Use of this software is subject to the terms of the Autodesk license agreement and any attachments or Appendices thereto provided at the time of installation or download,
4 * or which otherwise accompanies this software in either electronic or hard copy form, or which is signed by you and accepted by Autodesk.
5 */
6 
7 /**************************************************************************
8 
9 PublicHeader: None
10 Filename : KY_Atomic.h
11 Content : Contains atomic operations and inline fastest locking
12  functionality. Will contain #ifdefs for OS efficiency.
13  Have non-thread-safe implementaion if not available.
14 Created : May 5, 2003
15 Authors : Michael Antonov, Andrew Reisse
16 
17 **************************************************************************/
18 
19 #pragma once
20 
22 #include <atomic>
23 #include <mutex>
24 
25 namespace Kaim {
26 
27 // Lock is a simplest and most efficient mutual-exclusion lock class. Unlike Mutex, it cannot be waited on.
28 class Lock
29 {
30  // NOTE: Locks are not allocatable and they themselves should not allocate memory by standard means. This is the case because StandardAllocator relies on this class.
31  // Make 'delete' private. Don't do this for 'new' since it can be redefined.
32  void operator delete(void*) {}
33 
34  std::recursive_mutex mutex;
35 public:
36  Lock(/*unsigned spinCount = 0*/) {}
37  ~Lock() {}
38  void DoLock() { mutex.lock(); }
39  void Unlock() { mutex.unlock(); }
40 
41 public:
42  // Locker class, used for automatic locking
43  class Locker
44  {
45  public:
46  Lock *lock;
47  inline Locker(Lock *plock) { lock = plock; lock->DoLock(); }
48  inline ~Locker() { lock->Unlock(); }
49  };
50 };
51 
52 
53 // Safe lock for defensive design with assertion. Also contains temporary unlocker.
54 //-------------------------------------------
55 class LockSafe
56 {
57 public:
58  LockSafe(/*unsigned spinCount = 0*/) : mLock(/*spinCount*/)
59 #ifdef KY_CONFIG_DEBUG
60  , LockCount(0)
61 #endif
62  {}
63 
64  void DoLock()
65  {
66 #ifdef KY_CONFIG_DEBUG
67  LockCount++;
68 #endif
69  mLock.DoLock();
70  }
71 
72  void Unlock()
73  {
74  mLock.Unlock();
75 #ifdef KY_CONFIG_DEBUG
76  KY_ASSERT(LockCount.fetch_add(-1) > 0);
77 #endif
78  }
79 
80 #ifdef KY_CONFIG_DEBUG
81  bool IsLocked() const
82  {
83  return LockCount != 0;
84  }
85 #endif
86 
87  class Locker
88  {
89  public:
90  LockSafe *pLock;
91  Locker(LockSafe *lock)
92  {
93  pLock = lock;
94  pLock->DoLock();
95  }
96  ~Locker()
97  {
98  pLock->Unlock();
99  }
100  };
101 
102  class TmpUnlocker
103  {
104  public:
105  LockSafe *pLock;
106  TmpUnlocker(LockSafe *lock)
107  {
108  pLock = lock;
109  pLock->Unlock();
110  }
111  ~TmpUnlocker()
112  {
113  pLock->DoLock();
114  }
115  };
116 
117 
118 private:
119  Lock mLock;
120 #ifdef KY_CONFIG_DEBUG
121  std::atomic<int> LockCount;
122 #endif
123 };
124 
125 }
126 
The Autodesk Navigation namespace.
Definition: gamekitcrowddispersion.cpp:17