8a7a1d1fce2843996ed0c7fcde8de61459534157
[folly.git] / folly / stress-test / stress-sequential-folly-sync.cpp
1 #include "sync_test.h"
2
3 namespace folly_test {
4
5 class FollySyncTest_Sequential: public cds_test::stress_fixture {
6 protected:
7   // Simulate as the data protected by the lock.
8   static size_t locked_data;
9   // MicroLock
10   static size_t s_nMicroLockPassCount;
11   // MicroSpinLock
12   static size_t s_nMicroSpinLockPassCount;
13   // PicoSpinLock
14   static size_t s_nPicoSpinLockPassCount;
15   // SharedMutex
16   static size_t s_nSharedMutexPassCount;
17   // RWSpinLock
18   static size_t s_nRWSpinLockPassCount;
19   // RWTicketSpinLock
20   static size_t s_nRWTicketSpinLockPassCount;
21   // RCU
22   static size_t s_nRcuSyncPassCount;
23   static size_t s_nRcuNoSyncPassCount;
24
25   static void SetUpTestCase() {
26     const cds_test::config& cfg = get_config("SequentialFollySync");
27     GetConfigNonZeroExpected(MicroLockPassCount, 2000000000);
28     GetConfigNonZeroExpected(MicroSpinLockPassCount, 1500000000);
29     GetConfigNonZeroExpected(PicoSpinLockPassCount, 2700000000);
30     GetConfigNonZeroExpected(SharedMutexPassCount, 5000000);
31     GetConfigNonZeroExpected(RWSpinLockPassCount, 5000000);
32     GetConfigNonZeroExpected(RWTicketSpinLockPassCount, 5000000);
33     GetConfigNonZeroExpected(RcuSyncPassCount, 180000);
34     GetConfigNonZeroExpected(RcuNoSyncPassCount, 3500000);
35   }
36
37   static void run_rcu_sync(size_t pass_count) {
38     for (int write_percentage = 1; write_percentage <= 5; write_percentage += 1) {
39       for (size_t count = 0; count < pass_count; count++) {
40         for (int i = 0; i < 100; ++i) {
41           if (i < write_percentage) {
42             RcuData* data = new RcuData();
43             folly::rcu_retire(data);
44             folly::synchronize_rcu();
45           } else {
46             folly::rcu_reader g;
47           }
48         }
49       }
50     }
51   }
52
53   static void run_rcu_no_sync(size_t pass_count) {
54     for (int write_percentage = 1; write_percentage <= 5; write_percentage += 1) {
55       for (size_t count = 0; count < pass_count; count++) {
56         for (int i = 0; i < 100; ++i) {
57           if (i < write_percentage) {
58             RcuData* data = new RcuData();
59             folly::rcu_retire(data);
60           } else {
61             folly::rcu_reader g;
62           }
63         }
64       }
65     }
66   }
67
68   template <typename Lock>
69   static void run_rw_lock(size_t pass_count) {
70     std::unique_ptr<Lock> l(new Lock());
71     for (int write_percentage = 5; write_percentage < 20; write_percentage += 5) {
72       locked_data = 0;
73       size_t read_sum = 0;
74       size_t write_lock_cnt = 0;
75       for (size_t count = 0; count < pass_count; count++) {
76         for (int i = 0; i < 100; ++i) {
77           if (i < write_percentage) {
78             write_lock_cnt++;
79             l->lock();
80             locked_data++;
81             l->unlock();
82           } else {
83             l->lock_shared();
84             read_sum = locked_data;
85             l->unlock_shared();
86           }
87         }
88       }
89       EXPECT_EQ(write_lock_cnt, locked_data);
90       EXPECT_EQ(locked_data, read_sum);
91     }
92   }
93
94   template <typename Lock>
95   static void run_small_lock(size_t pass_count) {
96     std::unique_ptr<Lock> l(new Lock());
97     locked_data = 0;
98     l->init();
99     for (size_t count = 0; count < pass_count; count++) {
100       l->lock();
101       locked_data++;
102       l->unlock();
103     }
104     EXPECT_EQ(locked_data, pass_count);
105   }
106 };
107
108 size_t FollySyncTest_Sequential::locked_data;
109 size_t FollySyncTest_Sequential::s_nMicroLockPassCount;
110 size_t FollySyncTest_Sequential::s_nMicroSpinLockPassCount;
111 size_t FollySyncTest_Sequential::s_nPicoSpinLockPassCount;
112 size_t FollySyncTest_Sequential::s_nSharedMutexPassCount;
113 size_t FollySyncTest_Sequential::s_nRWSpinLockPassCount;
114 size_t FollySyncTest_Sequential::s_nRWTicketSpinLockPassCount;
115 size_t FollySyncTest_Sequential::s_nRcuSyncPassCount;
116 size_t FollySyncTest_Sequential::s_nRcuNoSyncPassCount;
117
118 TEST_F(FollySyncTest_Sequential, FollyMicroSpinLock) {
119   run_small_lock<MicroSpinLock>(s_nMicroSpinLockPassCount);
120 }
121
122 TEST_F(FollySyncTest_Sequential, FollyPicoSpinLock) {
123   run_small_lock<PicoSpinLock>(s_nPicoSpinLockPassCount);
124 }
125
126 TEST_F(FollySyncTest_Sequential, FollyMicroLock) {
127   run_small_lock<MicroLock>(s_nMicroLockPassCount);
128 }
129
130 TEST_F(FollySyncTest_Sequential, FollyRCU_Sync) {
131   run_rcu_sync(s_nRcuSyncPassCount);
132 }
133
134 TEST_F(FollySyncTest_Sequential, FollyRCU_NoSync) {
135   run_rcu_no_sync(s_nRcuNoSyncPassCount);
136 }
137
138 TEST_F(FollySyncTest_Sequential, FollyRWTicketSpinLock_32) {
139   run_rw_lock<RWTicketSpinLock32>(s_nRWTicketSpinLockPassCount);
140 }
141
142 TEST_F(FollySyncTest_Sequential, FollyRWTicketSpinLock_64) {
143   run_rw_lock<RWTicketSpinLock64>(s_nRWTicketSpinLockPassCount);
144 }
145
146 TEST_F(FollySyncTest_Sequential, FollyRWSpinLock) {
147   run_rw_lock<RWSpinLock>(s_nRWSpinLockPassCount);
148 }
149
150 TEST_F(FollySyncTest_Sequential, FollySharedMutex_ReadPriority) {
151   run_rw_lock<SharedMutexReadPriority>(s_nSharedMutexPassCount);
152 }
153
154 TEST_F(FollySyncTest_Sequential, FollySharedMutex_WritePriority) {
155   run_rw_lock<SharedMutexWritePriority>(s_nSharedMutexPassCount);
156 }
157
158 } // namespace folly_test