5 class FollySyncTest_Sequential: public cds_test::stress_fixture {
7 // Simulate as the data protected by the lock.
8 static size_t locked_data;
9 static std::atomic<RcuData*> rcu_data;
11 static size_t s_nMicroLockPassCount;
13 static size_t s_nMicroSpinLockPassCount;
15 static size_t s_nPicoSpinLockPassCount;
17 static size_t s_nSharedMutexPassCount;
19 static size_t s_nRWSpinLockPassCount;
21 static size_t s_nRWTicketSpinLockPassCount;
23 static size_t s_nRcuSyncPassCount;
24 static size_t s_nRcuNoSyncPassCount;
25 static size_t s_nRcuReaderOnlyPassCount;
27 static void SetUpTestCase() {
28 const cds_test::config& cfg = get_config("SequentialFollySync");
29 GetConfigNonZeroExpected(MicroLockPassCount, 2000000000);
30 GetConfigNonZeroExpected(MicroSpinLockPassCount, 1500000000);
31 GetConfigNonZeroExpected(PicoSpinLockPassCount, 2700000000);
32 GetConfigNonZeroExpected(SharedMutexPassCount, 5000000);
33 GetConfigNonZeroExpected(RWSpinLockPassCount, 5000000);
34 GetConfigNonZeroExpected(RWTicketSpinLockPassCount, 5000000);
35 GetConfigNonZeroExpected(RcuSyncPassCount, 180000);
36 GetConfigNonZeroExpected(RcuNoSyncPassCount, 3500000);
37 GetConfigNonZeroExpected(RcuReaderOnlyPassCount, 3000000);
39 // Initialize the RCU protected data.
40 rcu_data.store(new RcuData(), std::memory_order_relaxed);
43 static void run_rcu_reader_only(size_t pass_count) {
45 for (size_t count = 0; count < pass_count; count++) {
47 auto *data = rcu_data.load(std::memory_order_consume);
48 sum += (data->d1 + data->d2);
53 static void run_rcu_sync(size_t pass_count) {
54 for (int write_percentage = 1; write_percentage <= 5; write_percentage += 1) {
56 for (size_t count = 0; count < pass_count; count++) {
57 for (int i = 0; i < 100; ++i) {
58 if (i < write_percentage) {
59 auto* old_data = rcu_data.load(std::memory_order_consume);
60 auto* new_data = new RcuData(*old_data);
63 rcu_data.store(new_data, std::memory_order_release);
64 folly::synchronize_rcu();
68 auto* data = rcu_data.load(std::memory_order_consume);
69 sum += (data->d1 + data->d2);
77 static void run_rcu_no_sync(size_t pass_count) {
78 for (int write_percentage = 1; write_percentage <= 5; write_percentage += 1) {
80 for (size_t count = 0; count < pass_count; count++) {
81 for (int i = 0; i < 100; ++i) {
82 if (i < write_percentage) {
83 auto* old_data = rcu_data.load(std::memory_order_consume);
84 auto* new_data = new RcuData(*old_data);
87 rcu_data.store(new_data, std::memory_order_release);
88 folly::rcu_retire(old_data);
91 auto* data = rcu_data.load(std::memory_order_consume);
92 sum += (data->d1 + data->d2);
100 template <typename Lock>
101 static void run_rw_lock(size_t pass_count) {
102 std::unique_ptr<Lock> l(new Lock());
103 for (int write_percentage = 5; write_percentage < 20; write_percentage += 5) {
106 size_t write_lock_cnt = 0;
107 for (size_t count = 0; count < pass_count; count++) {
108 for (int i = 0; i < 100; ++i) {
109 if (i < write_percentage) {
116 read_sum = locked_data;
121 EXPECT_EQ(write_lock_cnt, locked_data);
122 EXPECT_EQ(locked_data, read_sum);
126 template <typename Lock>
127 static void run_small_lock(size_t pass_count) {
128 std::unique_ptr<Lock> l(new Lock());
131 for (size_t count = 0; count < pass_count; count++) {
136 EXPECT_EQ(locked_data, pass_count);
140 size_t FollySyncTest_Sequential::locked_data;
141 std::atomic<RcuData*> FollySyncTest_Sequential::rcu_data;
142 size_t FollySyncTest_Sequential::s_nMicroLockPassCount;
143 size_t FollySyncTest_Sequential::s_nMicroSpinLockPassCount;
144 size_t FollySyncTest_Sequential::s_nPicoSpinLockPassCount;
145 size_t FollySyncTest_Sequential::s_nSharedMutexPassCount;
146 size_t FollySyncTest_Sequential::s_nRWSpinLockPassCount;
147 size_t FollySyncTest_Sequential::s_nRWTicketSpinLockPassCount;
148 size_t FollySyncTest_Sequential::s_nRcuSyncPassCount;
149 size_t FollySyncTest_Sequential::s_nRcuNoSyncPassCount;
150 size_t FollySyncTest_Sequential::s_nRcuReaderOnlyPassCount;
152 TEST_F(FollySyncTest_Sequential, FollyRCU_ReaderOnly) {
153 run_rcu_reader_only(s_nRcuReaderOnlyPassCount);
156 TEST_F(FollySyncTest_Sequential, FollyRCU_Sync) {
157 run_rcu_sync(s_nRcuSyncPassCount);
160 TEST_F(FollySyncTest_Sequential, FollyRCU_NoSync) {
161 run_rcu_no_sync(s_nRcuNoSyncPassCount);
164 TEST_F(FollySyncTest_Sequential, FollyMicroSpinLock) {
165 run_small_lock<MicroSpinLock>(s_nMicroSpinLockPassCount);
168 TEST_F(FollySyncTest_Sequential, FollyPicoSpinLock) {
169 run_small_lock<PicoSpinLock>(s_nPicoSpinLockPassCount);
172 TEST_F(FollySyncTest_Sequential, FollyMicroLock) {
173 run_small_lock<MicroLock>(s_nMicroLockPassCount);
176 TEST_F(FollySyncTest_Sequential, FollyRWTicketSpinLock_32) {
177 run_rw_lock<RWTicketSpinLock32>(s_nRWTicketSpinLockPassCount);
180 TEST_F(FollySyncTest_Sequential, FollyRWTicketSpinLock_64) {
181 run_rw_lock<RWTicketSpinLock64>(s_nRWTicketSpinLockPassCount);
184 TEST_F(FollySyncTest_Sequential, FollyRWSpinLock) {
185 run_rw_lock<RWSpinLock>(s_nRWSpinLockPassCount);
188 TEST_F(FollySyncTest_Sequential, FollySharedMutex_ReadPriority) {
189 run_rw_lock<SharedMutexReadPriority>(s_nSharedMutexPassCount);
192 TEST_F(FollySyncTest_Sequential, FollySharedMutex_WritePriority) {
193 run_rw_lock<SharedMutexWritePriority>(s_nSharedMutexPassCount);
196 } // namespace folly_test