d2dfce90db47c7d64b5a06b03f91364429a2f881
[libcds.git] / test / stress / misc / rwlock_driver.cpp
1 #include <atomic>
2 #include <cds/gc/dhp.h>
3 #include <cds/gc/hp.h>
4 #include <cds/sync/rwlock.h>
5 #include <cds_test/stress_test.h>
6 #include <iostream>
7 #include <thread>
8
9 using namespace std;
10
11 namespace {
12
13 typedef cds_others::RWLock RWLock;
14 class RWLockTest : public cds_test::stress_fixture {
15 protected:
16   static int sum;
17   static int x;
18   static RWLock *rwlock;
19   static const int kReaderThreads = 0;
20   static const int kWriterThreads = 0;
21   static const int kReaderWriterThreads = 6;
22   static const int kWriterPercentage = 20;
23   static const int kRWPassCount = 20000;
24
25   static void SetUpTestCase() {}
26
27   static void ReaderThread() {
28     for (int i = 0; i < 10000; i++) {
29       for (int j = 0; j < 10; i++) {
30         if (rwlock->read_can_lock()) {
31           if (!rwlock->read_trylock()) {
32             rwlock->read_lock();
33           }
34           sum += x;
35           rwlock->read_unlock();
36         } else {
37           rwlock->read_lock();
38           sum += x;
39           rwlock->read_unlock();
40         }
41       }
42     }
43   }
44
45   static void WriterThread() {
46     for (int i = 0; i < 10000; i++) {
47       if (rwlock->write_can_lock()) {
48         if (!rwlock->write_trylock()) {
49           rwlock->write_lock();
50         }
51         x += 1;
52         rwlock->write_unlock();
53       } else {
54         rwlock->write_lock();
55         x += 1;
56         rwlock->write_unlock();
57       }
58     }
59   }
60
61   static void ReaderWriterThread() {
62     for (int i = 0; i < kRWPassCount; i++) {
63       for (int j = 0; j < kRWPassCount; j++) {
64         if (rand(100) < kWriterPercentage) {
65           if (rwlock->read_can_lock()) {
66             if (!rwlock->read_trylock()) {
67               rwlock->read_lock();
68             }
69             sum += x;
70             rwlock->read_unlock();
71           } else {
72             rwlock->read_lock();
73             sum += x;
74             rwlock->read_unlock();
75           }
76         } else {
77           if (rwlock->write_can_lock()) {
78             if (!rwlock->write_trylock()) {
79               rwlock->write_lock();
80             }
81             x += 1;
82             rwlock->write_unlock();
83           } else {
84             rwlock->write_lock();
85             x += 1;
86             rwlock->write_unlock();
87           }
88         }
89       }
90     }
91   }
92 };
93
94 int RWLockTest::x;
95 int RWLockTest::sum;
96 RWLock *RWLockTest::rwlock;
97 const int RWLockTest::kReaderThreads;
98 const int RWLockTest::kWriterThreads;
99 const int RWLockTest::kReaderWriterThreads;
100 const int RWLockTest::kRWPassCount;
101
102 TEST_F(RWLockTest, BasicLockUnlock) {
103   rwlock = new RWLock();
104   int num_threads = kReaderThreads + kWriterThreads + kReaderWriterThreads;
105   std::thread *threads = new std::thread[num_threads];
106   for (int i = 0; i < kReaderThreads; i++) {
107     threads[i] = std::thread(ReaderThread);
108   }
109   for (int i = kReaderThreads; i < (kReaderThreads + kWriterThreads); i++) {
110     threads[i] = std::thread(WriterThread);
111   }
112   for (int i = (kReaderThreads + kWriterThreads); i < num_threads; i++) {
113     threads[i] = std::thread(ReaderWriterThread);
114   }
115
116   for (int i = 0; i < num_threads; i++) {
117     threads[i].join();
118   }
119 }
120
121 } // namespace