atomic_queue_test.cpp
1 #define msecsleep(x) (x)
2 
3 //#include "xtime.h"
4 
5 #include "support.h"
6 
7 #include <stdint.h>
8 #include <thread>
9 
10 
11 //#define HAVE_CAS_2
12 // fake cas2
13 //inline bool atomicCompareAndSet2(
14 // uint32_t oldv0, uint32_t oldv1,
15 // uint32_t newv0, uint32_t newv1, uint32_t *target ) {
16 // assert(oldv0 == target[0]);
17 // assert(oldv1 == target[1]);
18 // if(rand() > RAND_MAX/2) {
19 // target[0] = newv0;
20 // target[1] = newv1;
21 // return true;
22 // }
23 // return false;
24 // }
25 
26 #include "atomic_smart_ptr.h"
27 #include "atomic_queue.h"
28 #include "xthread.cpp"
29 
30 
31 #define SIZE 100000
32 #define NUM_THREADS 4
33 
35 atomic_pointer_queue<int, NUM_THREADS - 1> queue2;
36 atomic_queue_reserved<int, NUM_THREADS- 1> queue3;
37 typedef atomic_queue_reserved<int, NUM_THREADS- 1>::key atomic_queue_reserved_key;
38 
39 atomic<int> g_queue1_total = 0, g_queue2_total = 0, g_queue3_total = 0;
40 atomic<int> g_cnt = 0;
41 
42 void
43 start_routine(void) {
44  for(int j = 0; j < SIZE; j++) {
45  int i;
46  for(;;) {
47  i = g_cnt;
48  if(g_cnt.compare_set_strong(i, i+1)) break;
49  }
50 
51  try {
52  queue1.push(i);
53  g_queue1_total += i;
54  }
55  catch (...) {
56  printf("1");
57  }
58  try {
59  queue3.push(i);
60  g_queue3_total += i;
61  }
62  catch (...) {
63  printf("3");
64  }
65  try {
66  queue2.push(new int(i));
67  g_queue2_total += i;
68  }
69  catch (...) {
70  printf("2");
71  }
72  {// for(;;) {
73  int *t = (int*)queue2.atomicFront();
74  if(t) {
75  int x = *t;
76  if(queue2.atomicPop(t)) {
77  assert(x >= 0);
78  *t = -100;
79  g_queue2_total -= x;
80 // break;
81  }
82  }
83 // printf("2");
84  }
85  {// for(;;) {
86  int x;
87  atomic_queue_reserved_key key = queue3.atomicFront(&x);
88  if(key) {
89  if(queue3.atomicPop(key)) {
90  g_queue3_total -= x;
91 // break;
92  }
93  }
94 // printf("3");
95  }
96  }
97 }
98 
99 
100 int
101 main(int argc, char **argv)
102 {
103  for(int i = 0; i < NUM_THREADS; i++) {
104  try {
105  queue3.push(i);
106  g_queue3_total += i;
107  }
108  catch (...) {
109  printf("3");
110  }
111  try {
112  queue2.push(new int(i));
113  g_queue2_total += i;
114  }
115  catch (...) {
116  printf("2");
117  }
118  }
119  for(int i = 0; i < NUM_THREADS; i++) {
120  {// for(;;) {
121  const int *t =queue2.atomicFront();
122  if(t) {
123  const int x = *t;
124  if(queue2.atomicPop(t)) {
125  g_queue2_total -= x;
126 // break;
127  }
128  }
129  // printf("2");
130  }
131  {// for(;;) {
132  int x;
133  atomic_queue_reserved_key key =queue3.atomicFront(&x);
134  if(key) {
135  if(queue3.atomicPop(key)) {
136  g_queue3_total -= x;
137  // break;
138  }
139  }
140  //printf("3");
141  }
142  }
143 
144  if(!queue1.empty() || !queue2.empty() || !queue3.empty() ||
145  (g_queue1_total != 0) || (g_queue3_total != 0) || (g_queue2_total != 0)) {
146  printf("\ntest1:failed queue1size=%d, queue1total=%d, queue2size=%d, queue2total=%d, queue3size=%d, queue3total=%d\n",
147  queue1.size(), (int)g_queue1_total,
148  queue2.size(), (int)g_queue2_total,
149  queue3.size(), (int)g_queue3_total);
150  }
151 
152 std::thread threads[NUM_THREADS];
153 
154  for(int i = 0; i < NUM_THREADS; i++) {
155  std::thread th( &start_routine);
156  threads[i].swap(th);
157  }
158 
159  for(int i =0; i < SIZE * NUM_THREADS; i++) {
160  if(queue1.empty()) continue;
161  int x = queue1.front();
162  g_queue1_total -= x;
163  queue1.pop();
164  }
165 
166  for(int i = 0; i < NUM_THREADS; i++) {
167  threads[i].join();
168  }
169 
170  for(;;) {
171  if(queue1.empty()) break;
172  int x = queue1.front();
173  g_queue1_total -= x;
174  queue1.pop();
175  }
176 
177  for(;;) {
178  if(queue2.empty()) break;
179  int *x = queue2.front();
180  g_queue2_total -= *x;
181  queue2.pop();
182  }
183  for(;;) {
184  if(queue3.empty()) break;
185  int x = queue3.front();
186  g_queue3_total -= x;
187  queue3.pop();
188  }
189 
190 
191  if(!queue1.empty() || !queue2.empty() || !queue3.empty() ||
192  (g_queue1_total != 0) || (g_queue3_total != 0) || (g_queue2_total != 0)) {
193  printf("\ntest2:failed queue1size=%d, queue1total=%d, queue2size=%d, queue2total=%d, queue3size=%d, queue3total=%d\n",
194  queue1.size(), (int)g_queue1_total,
195  queue2.size(), (int)g_queue2_total,
196  queue3.size(), (int)g_queue3_total);
197  return -1;
198  }
199  else
200  printf("succeeded\n");
201 
202  return 0;
203 }

Generated for KAME4 by  doxygen 1.8.3