1 /*---------------------------------------------------------------------------* 2 Project: Horizon 3 File: os_CriticalSection.h 4 5 Copyright (C)2009-2012 Nintendo Co., Ltd. All rights reserved. 6 7 These coded instructions, statements, and computer programs contain 8 proprietary information of Nintendo of America Inc. and/or Nintendo 9 Company Ltd., and are protected by Federal copyright law. They may 10 not be disclosed to third parties or copied or duplicated in any form, 11 in whole or in part, without the prior written consent of Nintendo. 12 13 $Rev: 47236 $ 14 *---------------------------------------------------------------------------*/ 15 16 /* Please see man pages for details 17 18 19 20 */ 21 22 #ifndef NN_OS_OS_CRITICALSECTION_H_ 23 #define NN_OS_OS_CRITICALSECTION_H_ 24 25 #include <nn/os/os_SimpleLock.h> 26 #include <nn/assert.h> 27 #include <nn/WithInitialize.h> 28 #include <nn/util/detail/util_ScopedLockImpl.h> 29 #include <nn/hw/ARM/reg_access.h> 30 31 #ifdef __cplusplus 32 33 namespace nn { namespace os { 34 35 /* Please see man pages for details 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 */ 55 56 class CriticalSection : private nn::util::NonCopyable<CriticalSection> 57 { 58 public: 59 /* Please see man pages for details 60 61 62 63 64 65 */ CriticalSection()66 CriticalSection() : m_ThreadUniqueValue(GetInvalidThreadUniqueValue()), m_LockCount(-1) {} 67 68 /* Please see man pages for details 69 70 */ CriticalSection(const nn::WithInitialize &)71 CriticalSection(const nn::WithInitialize&) { Initialize(); } 72 73 /* Please see man pages for details 74 75 76 77 */ 78 void Initialize(); 79 80 /* Please see man pages for details 81 82 83 84 */ TryInitialize()85 nn::Result TryInitialize() 86 { 87 Initialize(); 88 return ResultSuccess(); 89 } 90 91 /* Please see man pages for details 92 93 94 95 96 97 */ Finalize()98 void Finalize() { m_LockCount = -1; } 99 100 /* Please see man pages for details 101 102 */ ~CriticalSection()103 ~CriticalSection() {} 104 105 /* Please see man pages for details 106 107 108 109 */ 110 void Enter(); 111 112 /* Please see man pages for details 113 114 115 116 */ 117 bool TryEnter(); 118 119 /* Please see man pages for details 120 121 122 123 */ 124 void Leave(); 125 126 /* Please see man pages for details 127 128 129 130 131 */ 132 class ScopedLock; 133 IsLocked()134 bool IsLocked() const 135 { 136 return m_Lock.IsLocked(); 137 } 138 139 private: OnLocked()140 void OnLocked() 141 { 142 NN_TASSERT_(m_LockCount == 0); 143 144 // Save ID of thread that got critical section. 145 this->m_ThreadUniqueValue = GetThreadUniqueValue(); 146 } 147 148 // TODO: Recommend moving to ARM. 149 #ifdef NN_PROCESSOR_ARM946ES GetThreadUniqueValue()150 static uptr GetThreadUniqueValue() 151 { 152 return nn::os::CTR::ARM946ES::GetThreadId(); 153 } GetInvalidThreadUniqueValue()154 static uptr GetInvalidThreadUniqueValue() 155 { 156 return static_cast<uptr>(-1); 157 } 158 #else GetThreadUniqueValue()159 static uptr GetThreadUniqueValue() 160 { 161 uptr v; 162 HW_GET_CP15_THREAD_ID_USER_READ_ONLY(v); 163 return v; 164 } GetInvalidThreadUniqueValue()165 static uptr GetInvalidThreadUniqueValue() 166 { 167 return 0; 168 } 169 #endif 170 LockedByCurrentThread()171 bool LockedByCurrentThread() const 172 { 173 return GetThreadUniqueValue() == m_ThreadUniqueValue; 174 } IsInitialized()175 bool IsInitialized() const 176 { 177 return m_LockCount >= 0; 178 } 179 180 private: 181 SimpleLock m_Lock; 182 uptr m_ThreadUniqueValue; 183 s32 m_LockCount; 184 }; 185 186 NN_UTIL_DETAIL_DEFINE_SCOPED_LOCK(CriticalSection, Enter(), Leave()); 187 188 }} // namespace nn::os 189 190 #endif // __cplusplus 191 192 // Below is the C declaration 193 194 #include <nn/util/detail/util_CLibImpl.h> 195 196 #define NN_OS_CRITICALSECTION_SIZE 12 197 198 /* Please see man pages for details 199 200 201 202 203 204 205 206 207 */ 208 209 /* Please see man pages for details 210 211 212 213 214 */ 215 NN_UTIL_DETAIL_CLIBIMPL_DEFINE_BUFFER_CLASS(nnosCriticalSection, nn::os::CriticalSection, NN_OS_CRITICALSECTION_SIZE, u32); 216 217 /* Please see man pages for details 218 219 */ 220 NN_EXTERN_C void nnosCriticalSectionInitialize(nnosCriticalSection* this_); 221 222 /* Please see man pages for details 223 224 */ 225 NN_EXTERN_C bool nnosCriticalSectionTryInitialize(nnosCriticalSection* this_); 226 227 /* Please see man pages for details 228 229 */ 230 NN_EXTERN_C void nnosCriticalSectionEnter(nnosCriticalSection* this_); 231 232 /* Please see man pages for details 233 234 */ 235 NN_EXTERN_C bool nnosCriticalSectionTryEnter(nnosCriticalSection* this_); 236 237 /* Please see man pages for details 238 239 */ 240 NN_EXTERN_C void nnosCriticalSectionLeave(nnosCriticalSection* this_); 241 242 /* Please see man pages for details 243 244 */ 245 NN_EXTERN_C void nnosCriticalSectionFinalize(nnosCriticalSection* this_); 246 247 /* 248 249 250 251 */ 252 253 #endif 254