da84edb437d7499f98a061b8e5db9c62fceb0a4b
[libcds.git] / test / stress / misc / deque_driver.cpp
1 #include "common.h"
2 #include <cds/container/chase-lev-deque.h>
3 #include <cds_test/stress_test.h>
4 #include <cstdlib>
5 #include <ctime>
6 #include <iostream>
7 #include <thread>
8
9 using namespace std;
10
11 namespace {
12
13 typedef cds_others::ChaseLevDeque Deque;
14 static size_t s_nDequeStealerThreadCount = 5;
15 static size_t s_nDequeMainPassCount = 100000000;
16
17 class ChaseLevDequeTest : public cds_test::stress_fixture {
18 protected:
19   static Deque *deque;
20   static atomic_int terminate_stealer;
21   static ullong *sums;
22   static ullong *succ_counts;
23   static ullong push_sum;
24   static ullong push_count;
25
26   static void SetUpTestCase() {
27     cds_test::config const &cfg = get_config("Misc");
28     GetConfig(DequeStealerThreadCount);
29     GetConfig(DequeMainPassCount);
30   }
31
32   static void StealerThread(int index) {
33     while (!terminate_stealer.load(memory_order_relaxed)) {
34       int res = deque->steal();
35       if (res != EMPTY && res != ABORT) {
36         sums[index] += res;
37         succ_counts[index]++;
38       }
39     }
40   }
41
42   static void MainThread(int index, int push_percentage) {
43     for (ullong i = 0; i < s_nDequeMainPassCount; i++) {
44       if ((::rand() % 100) < push_percentage) {
45         int item = ::rand() % 100;
46         deque->push(item);
47         push_sum += item;
48         push_count++;
49       } else {
50         int res = deque->take();
51         if (res != EMPTY) {
52           sums[index] += res;
53           succ_counts[index]++;
54         }
55       }
56     }
57     //    while (true) {
58     //      int res = deque->take();
59     //      if (res != EMPTY) {
60     //        sums[index] += res;
61     //        succ_counts[index]++;
62     //      } else {
63     //        break;
64     //      }
65     //    }
66   }
67 };
68
69 atomic_int ChaseLevDequeTest::terminate_stealer;
70 ullong *ChaseLevDequeTest::sums;
71 ullong *ChaseLevDequeTest::succ_counts;
72 ullong ChaseLevDequeTest::push_count;
73 ullong ChaseLevDequeTest::push_sum;
74 Deque *ChaseLevDequeTest::deque;
75
76 TEST_F(ChaseLevDequeTest, DequePushPopTake) {
77   deque = new Deque();
78   push_sum = 0;
79   sums = (ullong *)calloc(1, sizeof(ullong) * (s_nDequeStealerThreadCount + 1));
80   succ_counts =
81       (ullong *)calloc(1, sizeof(ullong) * (s_nDequeStealerThreadCount + 1));
82   srand(time(NULL));
83
84   // Stealer threads
85   std::thread *threads = new std::thread[s_nDequeStealerThreadCount];
86   for (ullong i = 0; i < s_nDequeStealerThreadCount; i++) {
87     threads[i] = std::thread(StealerThread, i);
88   }
89
90   for (int i = 90; i > 0; i -= 10) {
91     MainThread(s_nDequeStealerThreadCount, i);
92   }
93
94   terminate_stealer.store(1, memory_order_relaxed);
95   for (ullong i = 0; i < s_nDequeStealerThreadCount; i++) {
96     threads[i].join();
97   }
98
99   // Result analysis
100   ullong received_sum = 0;
101   ullong overall_count = 0;
102   for (ullong i = 0; i <= s_nDequeStealerThreadCount; i++) {
103     received_sum += sums[i];
104     overall_count += succ_counts[i];
105   }
106   cout << "Sum of push: " << push_sum << "\n";
107   cout << "Received sum:" << received_sum << "\n";
108   cout << "overall_count:" << overall_count << "\n";
109   cout << "push_count=" << push_count << "\n";
110 }
111
112 } // namespace