b1b0e95cbe65771a35e854d127abf43c43126419
[libcds.git] / test / stress / misc / spinlock_driver.cpp
1 #include "common.h"
2 #include <atomic>
3 #include <cds/gc/dhp.h>
4 #include <cds/gc/hp.h>
5 #include <cds/sync/spinlock.h>
6 #include <cds/sync/ticket_lock.h>
7 #include <cds_test/stress_test.h>
8 #include <iostream>
9 #include <iostream>
10 #include <thread>
11
12 using namespace std;
13
14 namespace {
15
16 typedef cds_others::TicketLock TicketLock;
17 typedef cds::sync::spin SpinLock;
18 typedef cds::sync::reentrant_spin32 Reentrant32;
19 typedef cds::sync::reentrant_spin64 Reentrant64;
20 static size_t s_nSpinLockThreadCount = 6;
21 static size_t s_nSpinLockPassCount = 2500000000;
22 static size_t s_nTicketLockPassCount = 4000000;
23
24 #define TASK(lock_type, lock_ptr, pass_cnt)                                    \
25   static void Thread##lock_type() {                                            \
26     for (int i = 0; i < pass_cnt; i++) {                                       \
27       for (int j = 0; j < pass_cnt; j++) {                                     \
28         lock_ptr->lock();                                                      \
29         x = i + j;                                                             \
30         lock_ptr->unlock();                                                    \
31       }                                                                        \
32     }                                                                          \
33   }
34
35 #define LOCK_TEST(lock_type, lock_ptr)                                         \
36   TEST_F(SpinLockTest, lock_type) {                                            \
37     lock_ptr = new lock_type();                                                \
38     std::thread *threads = new std::thread[s_nSpinLockThreadCount];            \
39     for (int i = 0; i < s_nSpinLockThreadCount; i++) {                         \
40       threads[i] = std::thread(Thread##lock_type);                             \
41     }                                                                          \
42     for (int i = 0; i < s_nSpinLockThreadCount; i++) {                         \
43       threads[i].join();                                                       \
44     }                                                                          \
45   }
46
47 class SpinLockTest : public cds_test::stress_fixture {
48 protected:
49   static int x;
50   static TicketLock *ticket_mutex;
51   static SpinLock *spin_mutex;
52   static Reentrant32 *reentrant_mutex32;
53   static Reentrant64 *reentrant_mutex64;
54
55   static void SetUpTestCase() {
56     cds_test::config const &cfg = get_config("Misc");
57     GetConfig(SpinLockThreadCount);
58     GetConfig(SpinLockPassCount);
59     GetConfig(TicketLockPassCount);
60   }
61
62   TASK(TicketLock, ticket_mutex, s_nTicketLockPassCount)
63   TASK(SpinLock, spin_mutex, s_nSpinLockPassCount)
64   TASK(Reentrant32, reentrant_mutex32, s_nSpinLockPassCount)
65   TASK(Reentrant64, reentrant_mutex64, s_nSpinLockPassCount)
66 };
67
68 int SpinLockTest::x;
69 TicketLock *SpinLockTest::ticket_mutex;
70 SpinLock *SpinLockTest::spin_mutex;
71 Reentrant32 *SpinLockTest::reentrant_mutex32;
72 Reentrant64 *SpinLockTest::reentrant_mutex64;
73
74 LOCK_TEST(TicketLock, ticket_mutex)
75 LOCK_TEST(SpinLock, spin_mutex)
76 LOCK_TEST(Reentrant32, reentrant_mutex32)
77 LOCK_TEST(Reentrant64, reentrant_mutex64)
78
79 } // namespace