spsc-bugfix: duplicate the (buggy) spsc-queue
[model-checker-benchmarks.git] / queue / test_lock_free_q.cpp
1 // ============================================================================
2 /// @file  test_lock_free_q.cpp
3 /// @brief Benchmark lock free queue
4 // ============================================================================
5
6
7 #include <iostream>
8 #include <glib.h>  // GTimeVal + g_get_current_time
9 #include <omp.h>   // parallel processing support in gcc
10 #include "array_lock_free_queue.h"
11
12 #ifndef N_PRODUCERS
13 #define N_PRODUCERS         1
14 #endif
15
16 #ifndef N_CONSUMERS
17 #define N_CONSUMERS         1
18 #endif
19
20 #ifndef N_ITERATIONS
21 #define N_ITERATIONS 10000000
22 #endif
23
24 #ifndef QUEUE_SIZE
25 #define QUEUE_SIZE       1024
26 #endif
27
28 void TestLockFreeQueue()
29 {
30     ArrayLockFreeQueue<int, QUEUE_SIZE> theQueue;
31     GTimeVal iniTimestamp;
32     GTimeVal endTimestamp;
33
34     std::cout << "=== Start of testing lock-free queue ===" << std::endl;
35     g_get_current_time(&iniTimestamp);
36     #pragma omp parallel shared(theQueue) num_threads (2)
37     {
38         if (omp_get_thread_num() == 0)
39         {
40             //std::cout << "=== Testing Non blocking queue with " << omp_get_num_threads() << " threads ===" << std::endl;
41
42             if (!omp_get_nested())
43             {
44                 std::cerr << "WARNING: Nested parallel regions not supported. Working threads might have unexpected behaviour" << std::endl;
45                 std::cerr << "Are you running with \"OMP_NESTED=TRUE\"??" << std::endl;
46             }
47         }
48
49         #pragma omp sections //nowait
50         {
51             #pragma omp section
52             {
53                 // producer section
54                 #pragma omp parallel shared(theQueue) num_threads (N_PRODUCERS)
55                 {
56                     //if (omp_get_thread_num() == 0)
57                     //{
58                     //    std::cout << "\t Producers: " << omp_get_num_threads() << std::endl;
59                     //}
60                     int i;
61                     #pragma omp for schedule(static) private(i) nowait
62                     for (i = 0 ; i < N_ITERATIONS ; i++)
63                     {
64                         while(!theQueue.push(i))
65                         {
66                             // queue full
67                         }
68                     }
69                 }
70             }
71
72             #pragma omp section
73             {
74                 // consumer section
75                 #pragma omp parallel shared(theQueue) num_threads (N_CONSUMERS)
76                 {
77                     //if (omp_get_thread_num() == 0)
78                     //{
79                     //    std::cout << "\t Consumers: " << omp_get_num_threads() << std::endl;
80                     //}
81
82                     int i;
83                     int result;
84                     #pragma omp for schedule(static) private(i, result) nowait
85                     for (i = 0 ; i < N_ITERATIONS ; i++)
86                     {
87                         while (!theQueue.pop(result))
88                         {
89                             // queue empty
90                         }
91
92 #if (N_CONSUMERS == 1 && N_PRODUCERS == 1)
93                         if (i != result)
94                         {
95                             std::cout << "FAILED i=" << i << " result=" << result << std::endl;
96                         }
97 #endif
98                     }
99                 }
100             }
101         }
102
103     } // #pragma omp parallel
104
105     g_get_current_time(&endTimestamp);
106     
107     // calculate elapsed time
108     GTimeVal elapsedTime;
109     if (endTimestamp.tv_usec >= iniTimestamp.tv_usec)
110     {
111         elapsedTime.tv_sec  = endTimestamp.tv_sec  - iniTimestamp.tv_sec;
112         elapsedTime.tv_usec = endTimestamp.tv_usec - iniTimestamp.tv_usec;
113     }
114     else
115     {
116         elapsedTime.tv_sec  = endTimestamp.tv_sec  - iniTimestamp.tv_sec - 1;
117         elapsedTime.tv_usec = G_USEC_PER_SEC + endTimestamp.tv_usec - iniTimestamp.tv_usec;
118     }
119     
120     std::cout << "Elapsed: " << elapsedTime.tv_sec << "." << elapsedTime.tv_usec << std::endl;
121     std::cout << "=== End of testing lock-free queue ===" << std::endl;    
122 }
123
124 int main(int /*argc*/, char** /*argv*/)
125 {
126
127         TestLockFreeQueue();
128     std::cout << "Done!!!" << std::endl;
129
130         return 0;
131 }
132