hkCriticalSection.h
上传用户:yisoukefu
上传日期:2020-08-09
资源大小:39506k
文件大小:9k
源码类别:

其他游戏

开发平台:

Visual C++

  1. /* 
  2.  * 
  3.  * Confidential Information of Telekinesys Research Limited (t/a Havok). Not for disclosure or distribution without Havok's
  4.  * prior written consent. This software contains code, techniques and know-how which is confidential and proprietary to Havok.
  5.  * Level 2 and Level 3 source code contains trade secrets of Havok. Havok Software (C) Copyright 1999-2009 Telekinesys Research Limited t/a Havok. All Rights Reserved. Use of this software is subject to the terms of an end user license agreement.
  6.  * 
  7.  */
  8. #ifndef HKBASE_HK_CRITICAL_SECTION_H
  9. #define HKBASE_HK_CRITICAL_SECTION_H
  10. #include <Common/Base/Config/hkConfigThread.h>
  11. #include <Common/Base/Monitor/hkMonitorStream.h>
  12. # include <Common/Base/Fwd/hkwindows.h>
  13. #include <Common/Base/Thread/Thread/hkThreadLocalData.h>
  14. /// Set this define if you want a timer begin and timer end call 
  15. /// if a thread has to wait for a critical section
  16. /// You also have to call hkCriticalSection::setTimersEnabled()
  17. #define HK_TIME_CRITICAL_SECTION_LOCKS
  18. #if !defined (HK_TIME_CRITICAL_SECTION_LOCKS) && defined(HK_PLATFORM_SIM)
  19. # define HK_TIME_CRITICAL_SECTION_LOCKS
  20. #endif
  21. #define HK_PS3_CRITICAL_SECTION_SYSTEM_WAIT 1
  22. /// Critical section wrapper. This can be used to guard access
  23. /// to shared data structures between threads.
  24. /// Note that critical sections are fast but have serious drawbacks.
  25. /// Check windows help for details. 
  26. /// Note that including this file means including a system file, such as windows.h, 
  27. /// which makes compile time significantly slower.
  28. class hkCriticalSection
  29. {
  30. public:
  31. HK_DECLARE_NONVIRTUAL_CLASS_ALLOCATOR(HK_MEMORY_CLASS_BASE_CLASS, hkCriticalSection);
  32. # if !defined(HK_PLATFORM_PS3_SPU)
  33. /// Init a critical section with spin count. 
  34. /// Read MSDN help of InitializeCriticalSectionAndSpinCount for details.
  35. /// In short: positive spinCount value results in threads doing busy waiting and is good
  36. ///           when you know that the critical section will only be locked for a short period of time.
  37. ///           zero value causes the thread to immediately go back to the system when waiting.
  38. hkCriticalSection( int spinCount = 0, hkBool32 addToList = true );
  39. /// Quit a critical section
  40. inline ~hkCriticalSection();
  41. /// Lock a critical section
  42. inline void enter();
  43. /// Unlock a critical section
  44. inline void leave();
  45. /// Tell the critical section to time blocking locks. HK_TIME_CRITICAL_SECTION_LOCKS must be
  46. /// defined at compile time for this flag to have any effect
  47. static inline void HK_CALL setTimersEnabled();
  48. /// Stop timing blocking locks
  49. static inline void HK_CALL setTimersDisabled();
  50. /// adds a value to a variable in a thread safe way and returns the old value
  51. static HK_FORCE_INLINE hkUint32 HK_CALL atomicExchangeAdd(hkUint32* var, int value);
  52. # else
  53. inline hkCriticalSection(int spinCount=0) {}
  54. # endif
  55. public:
  56. #if HK_CONFIG_THREAD == HK_CONFIG_MULTI_THREADED
  57. # if defined(HK_PLATFORM_PS3_PPU) || defined(HK_PLATFORM_PS3_SPU) 
  58. // Busy wait mutex used on both PPU and SPU,  a uint32, 
  59. // not used as this data on SPU, but used through the ptr to the actual one in main mem.
  60. CellSyncMutex m_mutex; // 32bits
  61. hkInt32 m_recursiveLockCount;
  62. hkUint64 m_currentThread; // if this == current, then we have the lock already and just inc recursion count
  63. # if defined(HK_PS3_CRITICAL_SECTION_SYSTEM_WAIT)
  64. # if defined(HK_PLATFORM_PS3_PPU)// PPU  
  65. // have a kinder system level lock first, so that PPU threads
  66. // can sleep on locks with each other. ie, if this is locked, then a 
  67. // ppu thread has the lock, and we can sleep on it
  68. sys_lwmutex_t m_ppuMutex;
  69. # else  // SPU
  70. hkUint32 m_lwMutexPadding32[6];
  71. # endif
  72. # endif
  73. # elif defined(HK_PLATFORM_MACPPC) || defined(HK_PLATFORM_MAC386) || defined(HK_PLATFORM_UNIX) 
  74. pthread_mutex_t m_mutex;
  75. # else // other threaded platforms:
  76. CRITICAL_SECTION  m_section;
  77. # endif
  78. struct SectionList
  79. {
  80. # if !defined(HK_PLATFORM_PS3_SPU)
  81. SectionList( hkCriticalSection* section, int spinCount, hkBool32 addToList );
  82. ~SectionList();
  83. static inline bool isEmpty();
  84. # endif
  85. // The spin count value of created critical section.
  86. int m_spinCount;
  87. // Link to the previous critical section wrapper in the list.
  88. hkCriticalSection* m_prev;
  89. // Link to the next critical section wrapper in the list.
  90. hkCriticalSection* m_next;
  91. // Head of the critical section wrappers list.
  92. static hkCriticalSection s_listHead;
  93. };
  94. SectionList m_list;
  95. #endif
  96. };
  97. // move to static member when compiler support
  98. #if HK_CONFIG_THREAD == HK_CONFIG_MULTI_THREADED && defined(HK_TIME_CRITICAL_SECTION_LOCKS)
  99. extern HK_THREAD_LOCAL( int ) hkCriticalSection__m_timeLocks;
  100. #endif
  101. #if !defined(HK_PLATFORM_PS3_SPU) && (HK_CONFIG_THREAD == HK_CONFIG_MULTI_THREADED)
  102. inline hkCriticalSection::SectionList::SectionList(hkCriticalSection* self, int spinCount, hkBool32 addToList)
  103. : m_spinCount(spinCount), m_prev(HK_NULL), m_next(HK_NULL)
  104. {
  105. if( addToList )
  106. {
  107. s_listHead.enter();
  108. // add to the list
  109. m_next = s_listHead.m_list.m_next;
  110. if( m_next )
  111. {
  112. m_next->m_list.m_prev = self;
  113. }
  114. m_prev = &s_listHead;
  115. s_listHead.m_list.m_next = self;
  116. s_listHead.leave();
  117. }
  118. }
  119. inline hkCriticalSection::SectionList::~SectionList()
  120. {
  121. if( m_prev )
  122. {
  123. s_listHead.enter();
  124. // If you get crash here:
  125. // It seems some critical sections were not destroyed and removed
  126. // from the list of the critical section wrappers, and links are
  127. // referring to the already invalid objects.
  128. // To resolve the issue make sure there are no memory leaks of the
  129. // critical section wrappers.
  130. m_prev->m_list.m_next = m_next;
  131. if( m_next )
  132. {
  133. // If you get crash here:
  134. // It seems some critical sections were not destroyed and removed
  135. // from the list of the critical section wrappers, and links are
  136. // referring to the already invalid objects.
  137. // To resolve the issue make sure there are no memory leaks of the
  138. // critical section wrappers.
  139. m_next->m_list.m_prev = m_prev;
  140. }
  141. s_listHead.leave();
  142. }
  143. }
  144. inline bool hkCriticalSection::SectionList::isEmpty()
  145. {
  146. bool ret;
  147. s_listHead.enter();
  148. ret = (s_listHead.m_list.m_next == HK_NULL);
  149. s_listHead.leave();
  150. return ret;
  151. }
  152. #endif
  153. // include the inl before the hkCriticalSectionLock def so 
  154. // that gcc can inline the enter and leave properly
  155. #if HK_CONFIG_THREAD != HK_CONFIG_MULTI_THREADED 
  156. # include <Common/Base/Thread/CriticalSection/Empty/hkEmptyCriticalSection.inl>
  157. #else // HK_CONFIG_THREAD == HK_CONFIG_MULTI_THREADED 
  158. # include <Common/Base/Thread/Thread/hkThread.h>
  159. # define HK_INVALID_THREAD_ID (hkUint64(-1))
  160. # if defined(HK_PLATFORM_PS3_PPU) 
  161. # include <Common/Base/Thread/CriticalSection/Ps3/hkPs3CriticalSection.inl>
  162. # elif defined(HK_PLATFORM_PS3_SPU) 
  163. # include <Common/Base/Thread/CriticalSection/Ps3/hkPs3SpuCriticalSection.inl>
  164. #   elif defined(HK_PLATFORM_MACPPC) || defined(HK_PLATFORM_MAC386)
  165. # include <Common/Base/Thread/CriticalSection/Mac/hkMacCriticalSection.inl>
  166. # elif defined(HK_PLATFORM_UNIX)
  167. # include <Common/Base/Thread/Thread/Posix/hkPosixCheck.h>
  168. # include <Common/Base/Thread/CriticalSection/Posix/hkPosixCriticalSection.inl>
  169. # else
  170. # include <Common/Base/Thread/CriticalSection/Win32/hkWin32CriticalSection.inl>
  171. # endif
  172. #endif
  173. #if !defined(HK_PLATFORM_PS3_SPU)
  174. /// Helper class which locks a critical section as long is this object exists. 
  175. class hkCriticalSectionLock
  176. {
  177. public:
  178. HK_DECLARE_NONVIRTUAL_CLASS_ALLOCATOR(HK_MEMORY_CLASS_BASE_CLASS, hkCriticalSectionLock);
  179. /// Create a lock by entering a critical section.
  180. inline hkCriticalSectionLock( hkCriticalSection* section )
  181. {
  182. m_section = section;
  183. section->enter();
  184. }
  185. /// Destructor leaves the critical section
  186. inline ~hkCriticalSectionLock()
  187. {
  188. m_section->leave();
  189. }
  190. protected:
  191. hkCriticalSection* m_section;
  192. };
  193. #endif
  194. #endif // HKBASE_HK_CRITICAL_SECTION_H
  195. /*
  196. * Havok SDK - NO SOURCE PC DOWNLOAD, BUILD(#20090216)
  197. * Confidential Information of Havok.  (C) Copyright 1999-2009
  198. * Telekinesys Research Limited t/a Havok. All Rights Reserved. The Havok
  199. * Logo, and the Havok buzzsaw logo are trademarks of Havok.  Title, ownership
  200. * rights, and intellectual property rights in the Havok software remain in
  201. * Havok and/or its suppliers.
  202. * Use of this software for evaluation purposes is subject to and indicates
  203. * acceptance of the End User licence Agreement for this product. A copy of
  204. * the license is included with this software and is also available at www.havok.com/tryhavok.
  205. */