mutex.h 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. /*
  2. * Copyright 2010-2012 Branimir Karadzic. All rights reserved.
  3. * License: http://www.opensource.org/licenses/BSD-2-Clause
  4. */
  5. #ifndef __BX_MUTEX_H__
  6. #define __BX_MUTEX_H__
  7. #include "bx.h"
  8. #include "cpu.h"
  9. #include "sem.h"
  10. #if BX_PLATFORM_NACL || BX_PLATFORM_LINUX || BX_PLATFORM_ANDROID
  11. # include <pthread.h>
  12. #elif BX_PLATFORM_WINDOWS || BX_PLATFORM_XBOX360
  13. # include <errno.h>
  14. #endif // BX_PLATFORM_
  15. namespace bx
  16. {
  17. #if BX_PLATFORM_WINDOWS || BX_PLATFORM_XBOX360
  18. typedef CRITICAL_SECTION pthread_mutex_t;
  19. typedef unsigned pthread_mutexattr_t;
  20. inline int pthread_mutex_lock(pthread_mutex_t* _mutex)
  21. {
  22. EnterCriticalSection(_mutex);
  23. return 0;
  24. }
  25. inline int pthread_mutex_unlock(pthread_mutex_t* _mutex)
  26. {
  27. LeaveCriticalSection(_mutex);
  28. return 0;
  29. }
  30. inline int pthread_mutex_trylock(pthread_mutex_t* _mutex)
  31. {
  32. return TryEnterCriticalSection(_mutex) ? 0 : EBUSY;
  33. }
  34. inline int pthread_mutex_init(pthread_mutex_t* _mutex, pthread_mutexattr_t* /*_attr*/)
  35. {
  36. InitializeCriticalSection(_mutex);
  37. return 0;
  38. }
  39. inline int pthread_mutex_destroy(pthread_mutex_t* _mutex)
  40. {
  41. DeleteCriticalSection(_mutex);
  42. return 0;
  43. }
  44. #endif // BX_PLATFORM_
  45. class Mutex
  46. {
  47. public:
  48. Mutex()
  49. {
  50. pthread_mutex_init(&m_handle, NULL);
  51. }
  52. ~Mutex()
  53. {
  54. pthread_mutex_destroy(&m_handle);
  55. }
  56. void lock()
  57. {
  58. pthread_mutex_lock(&m_handle);
  59. }
  60. void unlock()
  61. {
  62. pthread_mutex_unlock(&m_handle);
  63. }
  64. private:
  65. Mutex(const Mutex& _rhs); // no copy constructor
  66. Mutex& operator=(const Mutex& _rhs); // no assignment operator
  67. pthread_mutex_t m_handle;
  68. };
  69. class MutexScope
  70. {
  71. public:
  72. MutexScope(Mutex& _mutex)
  73. : m_mutex(_mutex)
  74. {
  75. m_mutex.lock();
  76. }
  77. ~MutexScope()
  78. {
  79. m_mutex.unlock();
  80. }
  81. private:
  82. MutexScope(); // no default constructor
  83. MutexScope(const MutexScope& _rhs); // no copy constructor
  84. MutexScope& operator=(const MutexScope& _rhs); // no assignment operator
  85. Mutex& m_mutex;
  86. };
  87. #if 1
  88. typedef Mutex LwMutex;
  89. #else
  90. class LwMutex
  91. {
  92. public:
  93. LwMutex()
  94. : m_count(0)
  95. {
  96. }
  97. ~LwMutex()
  98. {
  99. }
  100. void lock()
  101. {
  102. if (atomicIncr(&m_count) > 1)
  103. {
  104. m_sem.wait();
  105. }
  106. }
  107. void unlock()
  108. {
  109. if (atomicDecr(&m_count) > 0)
  110. {
  111. m_sem.post();
  112. }
  113. }
  114. private:
  115. LwMutex(const LwMutex& _rhs); // no copy constructor
  116. LwMutex& operator=(const LwMutex& _rhs); // no assignment operator
  117. Semaphore m_sem;
  118. volatile int32_t m_count;
  119. };
  120. #endif // 0
  121. class LwMutexScope
  122. {
  123. public:
  124. LwMutexScope(LwMutex& _mutex)
  125. : m_mutex(_mutex)
  126. {
  127. m_mutex.lock();
  128. }
  129. ~LwMutexScope()
  130. {
  131. m_mutex.unlock();
  132. }
  133. private:
  134. LwMutexScope(); // no default constructor
  135. LwMutexScope(const LwMutexScope& _rhs); // no copy constructor
  136. LwMutexScope& operator=(const LwMutexScope& _rhs); // no assignment operator
  137. LwMutex& m_mutex;
  138. };
  139. } // namespace bx
  140. #endif // __BX_MUTEX_H__