Advertisement
Guest User

Chris M. Thomasson

a guest
Oct 6th, 2010
494
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.47 KB | None | 0 0
  1. //#define RL_DEBUGBREAK_ON_ASSERT
  2. //#define RL_MSVC_OUTPUT
  3. //#define RL_FORCE_SEQ_CST
  4.  
  5.  
  6.  
  7.  
  8. #include <relacy/relacy_std.hpp>
  9. #include <cstdio>
  10. #include <cstddef>
  11. #include <climits>
  12. #include <cassert>
  13.  
  14.  
  15.  
  16.  
  17. #define mb_relaxed std::memory_order_relaxed
  18. #define mb_consume std::memory_order_consume
  19. #define mb_acquire std::memory_order_acquire
  20. #define mb_release std::memory_order_release
  21. #define mb_acq_rel std::memory_order_acq_rel
  22. #define mb_system FlushProcessWriteBuffers
  23. #define thread_yield SwitchToThread
  24.  
  25.  
  26.  
  27.  
  28. #if ! defined (NDEBUG)
  29. # define DBG_PRINTF(e) std::printf e
  30. #else
  31. # define DBG_PRINTF(e) ((void)0)
  32. #endif
  33.  
  34.  
  35.  
  36.  
  37. /*
  38. Condition Variable Algorithm By Michael Podolsky
  39.  
  40. http://groups.google.com/group/comp.programming.threads/msg/fe8217a6f3512fe4
  41. */
  42. class win_condvar
  43. {
  44. VAR_T(int) m_waiters;
  45. VAR_T(int) m_task;
  46. HANDLE m_turn1;
  47. HANDLE m_turn2;
  48. CRITICAL_SECTION m_mutex;
  49.  
  50.  
  51. private:
  52. void prv_signal(bool all)
  53. {
  54. WaitForSingleObject(m_turn1, INFINITE);
  55. EnterCriticalSection(&m_mutex);
  56. int waiters = VAR(m_waiters);
  57.  
  58. if (waiters)
  59. {
  60. if (all)
  61. {
  62. VAR(m_task) = 0;
  63. }
  64.  
  65. else
  66. {
  67. VAR(m_task) = waiters - 1;
  68. }
  69.  
  70. LeaveCriticalSection(&m_mutex);
  71. ReleaseSemaphore(m_turn2, 1, NULL);
  72. }
  73.  
  74. else
  75. {
  76. LeaveCriticalSection(&m_mutex);
  77. ReleaseSemaphore(m_turn1, 1, NULL);
  78. }
  79. }
  80.  
  81.  
  82. public:
  83. win_condvar()
  84. : m_waiters(0),
  85. m_task(0),
  86. m_turn1(CreateSemaphore(NULL, 1, LONG_MAX, NULL)),
  87. m_turn2(CreateSemaphore(NULL, 0, LONG_MAX, NULL))
  88. {
  89. InitializeCriticalSection(&m_mutex);
  90. }
  91.  
  92.  
  93. ~win_condvar()
  94. {
  95. DeleteCriticalSection(&m_mutex);
  96. CloseHandle(m_turn2);
  97. CloseHandle(m_turn1);
  98. }
  99.  
  100.  
  101. public:
  102. void wait(CRITICAL_SECTION& umutex)
  103. {
  104. WaitForSingleObject(m_turn1, INFINITE);
  105. EnterCriticalSection(&m_mutex);
  106. ++VAR(m_waiters);
  107. LeaveCriticalSection(&m_mutex);
  108. ReleaseSemaphore(m_turn1, 1, NULL);
  109.  
  110. LeaveCriticalSection(&umutex);
  111.  
  112. WaitForSingleObject(m_turn2, INFINITE);
  113.  
  114. EnterCriticalSection(&m_mutex);
  115. --VAR(m_waiters);
  116. bool last = VAR(m_waiters) == VAR(m_task) ? true : false;
  117. LeaveCriticalSection(&m_mutex);
  118.  
  119. if (last)
  120. {
  121. ReleaseSemaphore(m_turn1, 1, NULL);
  122. }
  123.  
  124. else
  125. {
  126. ReleaseSemaphore(m_turn2, 1, NULL);
  127. }
  128.  
  129. EnterCriticalSection(&umutex);
  130. }
  131.  
  132.  
  133. void signal()
  134. {
  135. prv_signal(false);
  136. }
  137.  
  138.  
  139. void broadcast()
  140. {
  141. prv_signal(true);
  142. }
  143. };
  144.  
  145.  
  146.  
  147.  
  148. #define ITERS 10
  149. #define THREADS 6
  150.  
  151.  
  152. struct win_condvar_test
  153. : rl::test_suite<win_condvar_test, THREADS>
  154. {
  155. win_condvar g_condvar;
  156. CRITICAL_SECTION g_mutex;
  157. VAR_T(int) g_state;
  158.  
  159.  
  160. void before()
  161. {
  162. InitializeCriticalSection(&g_mutex);
  163. VAR(g_state) = 0;
  164. }
  165.  
  166.  
  167. void after()
  168. {
  169. DeleteCriticalSection(&g_mutex);
  170. }
  171.  
  172.  
  173. void thread(unsigned tid)
  174. {
  175. DBG_PRINTF(("(%u)->win_condvar_test::thread - init\n", tid));
  176.  
  177. EnterCriticalSection(&g_mutex);
  178. unsigned state = VAR(g_state);
  179.  
  180. while (state != tid)
  181. {
  182. g_condvar.wait(g_mutex);
  183. state = VAR(g_state);
  184. }
  185.  
  186. VAR(g_state) = tid + 1;
  187.  
  188. if (! (tid % 2))
  189. {
  190. g_condvar.signal();
  191. g_condvar.broadcast();
  192. }
  193.  
  194. LeaveCriticalSection(&g_mutex);
  195.  
  196. if (tid % 2)
  197. {
  198. g_condvar.signal();
  199. g_condvar.broadcast();
  200. }
  201.  
  202. DBG_PRINTF(("(%u)->win_condvar_test::thread - fini\n", tid));
  203. }
  204. };
  205.  
  206.  
  207.  
  208.  
  209. int main()
  210. {
  211. {
  212. rl::test_params p;
  213.  
  214. //p.execution_depth_limit = 100000;
  215. //p.initial_state = "10000000";
  216. p.iteration_count = 60000000;
  217. //p.search_type = rl::sched_bound;
  218. //p.search_type = rl::fair_full_search_scheduler_type;
  219. //p.search_type = rl::fair_context_bound_scheduler_type;
  220. rl::simulate<win_condvar_test>(p);
  221. }
  222.  
  223. std::puts("\n\n____________________________________\n"
  224. "The program has completed!\n");
  225. std::fflush(stdout);
  226. std::getchar();
  227.  
  228. return 0;
  229. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement