Chris_M_Thomasson

"fast" mutex vs std::shared_mutex...

Feb 13th, 2019
252
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.73 KB | None | 0 0
  1. /* Simple, crude read/write mutex test
  2. by: Chris M. Thomasson
  3. __________________________________________*/
  4.  
  5.  
  6.  
  7. #include <thread>
  8. #include <atomic>
  9. #include <shared_mutex>
  10. #include <condition_variable>
  11. #include <iostream>
  12. #include <functional>
  13. #include <cassert>
  14. #include <cstdlib>
  15. #include <ctime>
  16.  
  17.  
  18. #define THREADS 16UL
  19. #define ITERS 10000000UL
  20. #define COUNT (THREADS * ITERS)
  21.  
  22.  
  23. // undefine to test std::shared_mutex
  24. #define CT_TEST_FAST_MUTEX 1
  25.  
  26.  
  27. // bin-sema
  28. struct ct_auto_reset_event
  29. {
  30. bool m_state;
  31. std::mutex m_mutex;
  32. std::condition_variable m_cond;
  33.  
  34. ct_auto_reset_event() : m_state(false) {}
  35.  
  36. void signal()
  37. {
  38. std::unique_lock<std::mutex> lock(m_mutex);
  39. m_state = true;
  40. m_cond.notify_one();
  41. }
  42.  
  43. void wait()
  44. {
  45. std::unique_lock<std::mutex> lock(m_mutex);
  46. while (m_state == false) m_cond.wait(lock);
  47. m_state = false; // auto-reset
  48. }
  49. };
  50.  
  51.  
  52. // just a layer over an auto-reset event
  53. struct ct_fast_mutex
  54. {
  55. std::atomic<unsigned int> m_state;
  56. ct_auto_reset_event m_waitset;
  57.  
  58. ct_fast_mutex() : m_state(0) {}
  59.  
  60. void lock()
  61. {
  62. if (m_state.exchange(1, std::memory_order_acquire))
  63. {
  64. while (m_state.exchange(2, std::memory_order_acquire))
  65. {
  66. m_waitset.wait();
  67. }
  68. }
  69. }
  70.  
  71. void unlock()
  72. {
  73. if (m_state.exchange(0, std::memory_order_release) == 2)
  74. {
  75. m_waitset.signal();
  76. }
  77. }
  78. };
  79.  
  80.  
  81. struct ct_shared
  82. {
  83. std::atomic<unsigned long> m_state;
  84.  
  85. #if defined (CT_TEST_FAST_MUTEX)
  86. ct_fast_mutex m_std_mutex;
  87. #else
  88. std::shared_mutex m_std_mutex;
  89. #endif
  90.  
  91. ct_shared() : m_state(0) {}
  92. };
  93.  
  94.  
  95. void ct_thread(ct_shared& shared, std::size_t index)
  96. {
  97. for (unsigned int i = 0; i < ITERS; ++i)
  98. {
  99. shared.m_std_mutex.lock();
  100. if (i % 256 == 0) std::this_thread::yield();
  101. shared.m_state += 1;
  102. shared.m_std_mutex.unlock();
  103. }
  104. }
  105.  
  106.  
  107. int main()
  108. {
  109. ct_shared shared;
  110.  
  111. {
  112. std::thread threads[THREADS];
  113.  
  114. std::clock_t start = std::clock();
  115.  
  116. for (std::size_t i = 0; i < THREADS; ++i)
  117. {
  118. threads[i] = std::thread(ct_thread, std::ref(shared), i);
  119. }
  120.  
  121. for (std::size_t i = 0; i < THREADS; ++i)
  122. {
  123. threads[i].join();
  124. }
  125.  
  126. std::clock_t diff = clock() - start;
  127.  
  128. unsigned long msec = diff * 1000 / CLOCKS_PER_SEC;
  129.  
  130. std::cout << "msec = " << msec << "\n";
  131. }
  132.  
  133. std::cout << "shared.m_state = " << shared.m_state << "\n";
  134. std::cout << "\n\nFin!\n";
  135.  
  136. assert(shared.m_state == COUNT);
  137.  
  138. return 0;
  139. }
Add Comment
Please, Sign In to add comment