threads_runqueue.cpp File Reference
#include <cstdlib>
#include "main.h"
#include <Eigen/ThreadPool>

Macros

#define EIGEN_USE_THREADS
 

Functions

int rand_reentrant (unsigned int *s)
 
void test_basic_runqueue ()
 
void test_empty_runqueue ()
 
void test_stress_runqueue ()
 
 EIGEN_DECLARE_TEST (cxx11_runqueue)
 

Macro Definition Documentation

◆ EIGEN_USE_THREADS

#define EIGEN_USE_THREADS

Function Documentation

◆ EIGEN_DECLARE_TEST()

EIGEN_DECLARE_TEST ( cxx11_runqueue  )
226  {
230 }
#define CALL_SUBTEST_3(FUNC)
Definition: split_test_helper.h:16
#define CALL_SUBTEST_1(FUNC)
Definition: split_test_helper.h:4
#define CALL_SUBTEST_2(FUNC)
Definition: split_test_helper.h:10
void test_stress_runqueue()
Definition: threads_runqueue.cpp:157
void test_basic_runqueue()
Definition: threads_runqueue.cpp:27
void test_empty_runqueue()
Definition: threads_runqueue.cpp:118

References CALL_SUBTEST_1, CALL_SUBTEST_2, CALL_SUBTEST_3, test_basic_runqueue(), test_empty_runqueue(), and test_stress_runqueue().

◆ rand_reentrant()

int rand_reentrant ( unsigned int s)
18  {
19 #if EIGEN_COMP_MSVC_STRICT
21  return rand();
22 #else
23  return rand_r(s);
24 #endif
25 }
#define EIGEN_UNUSED_VARIABLE(var)
Definition: Macros.h:966
RealScalar s
Definition: level1_cplx_impl.h:130

References EIGEN_UNUSED_VARIABLE, and s.

Referenced by test_empty_runqueue().

◆ test_basic_runqueue()

void test_basic_runqueue ( )
27  {
29  // Check empty state.
30  VERIFY(q.Empty());
31  VERIFY_IS_EQUAL(0u, q.Size());
32  VERIFY_IS_EQUAL(0, q.PopFront());
33  std::vector<int> stolen;
34  VERIFY_IS_EQUAL(0u, q.PopBackHalf(&stolen));
35  VERIFY_IS_EQUAL(0u, stolen.size());
36  // Push one front, pop one front.
37  VERIFY_IS_EQUAL(0, q.PushFront(1));
38  VERIFY_IS_EQUAL(1u, q.Size());
39  VERIFY_IS_EQUAL(1, q.PopFront());
40  VERIFY_IS_EQUAL(0u, q.Size());
41  // Push front to overflow.
42  VERIFY_IS_EQUAL(0, q.PushFront(2));
43  VERIFY_IS_EQUAL(1u, q.Size());
44  VERIFY_IS_EQUAL(0, q.PushFront(3));
45  VERIFY_IS_EQUAL(2u, q.Size());
46  VERIFY_IS_EQUAL(0, q.PushFront(4));
47  VERIFY_IS_EQUAL(3u, q.Size());
48  VERIFY_IS_EQUAL(0, q.PushFront(5));
49  VERIFY_IS_EQUAL(4u, q.Size());
50  VERIFY_IS_EQUAL(6, q.PushFront(6));
51  VERIFY_IS_EQUAL(4u, q.Size());
52  VERIFY_IS_EQUAL(5, q.PopFront());
53  VERIFY_IS_EQUAL(3u, q.Size());
54  VERIFY_IS_EQUAL(4, q.PopFront());
55  VERIFY_IS_EQUAL(2u, q.Size());
56  VERIFY_IS_EQUAL(3, q.PopFront());
57  VERIFY_IS_EQUAL(1u, q.Size());
58  VERIFY_IS_EQUAL(2, q.PopFront());
59  VERIFY_IS_EQUAL(0u, q.Size());
60  VERIFY_IS_EQUAL(0, q.PopFront());
61  // Push one back, pop one back.
62  VERIFY_IS_EQUAL(0, q.PushBack(7));
63  VERIFY_IS_EQUAL(1u, q.Size());
64  VERIFY_IS_EQUAL(1u, q.PopBackHalf(&stolen));
65  VERIFY_IS_EQUAL(1u, stolen.size());
66  VERIFY_IS_EQUAL(7, stolen[0]);
67  VERIFY_IS_EQUAL(0u, q.Size());
68  stolen.clear();
69  // Push back to overflow.
70  VERIFY_IS_EQUAL(0, q.PushBack(8));
71  VERIFY_IS_EQUAL(1u, q.Size());
72  VERIFY_IS_EQUAL(0, q.PushBack(9));
73  VERIFY_IS_EQUAL(2u, q.Size());
74  VERIFY_IS_EQUAL(0, q.PushBack(10));
75  VERIFY_IS_EQUAL(3u, q.Size());
76  VERIFY_IS_EQUAL(0, q.PushBack(11));
77  VERIFY_IS_EQUAL(4u, q.Size());
78  VERIFY_IS_EQUAL(12, q.PushBack(12));
79  VERIFY_IS_EQUAL(4u, q.Size());
80  // Pop back in halves.
81  VERIFY_IS_EQUAL(2u, q.PopBackHalf(&stolen));
82  VERIFY_IS_EQUAL(2u, stolen.size());
83  VERIFY_IS_EQUAL(10, stolen[0]);
84  VERIFY_IS_EQUAL(11, stolen[1]);
85  VERIFY_IS_EQUAL(2u, q.Size());
86  stolen.clear();
87  VERIFY_IS_EQUAL(1u, q.PopBackHalf(&stolen));
88  VERIFY_IS_EQUAL(1u, stolen.size());
89  VERIFY_IS_EQUAL(9, stolen[0]);
90  VERIFY_IS_EQUAL(1u, q.Size());
91  stolen.clear();
92  VERIFY_IS_EQUAL(1u, q.PopBackHalf(&stolen));
93  VERIFY_IS_EQUAL(1u, stolen.size());
94  VERIFY_IS_EQUAL(8, stolen[0]);
95  stolen.clear();
96  VERIFY_IS_EQUAL(0u, q.PopBackHalf(&stolen));
97  VERIFY_IS_EQUAL(0u, stolen.size());
98  // Empty again.
99  VERIFY(q.Empty());
100  VERIFY_IS_EQUAL(0u, q.Size());
101  VERIFY_IS_EQUAL(0, q.PushFront(1));
102  VERIFY_IS_EQUAL(0, q.PushFront(2));
103  VERIFY_IS_EQUAL(0, q.PushFront(3));
104  VERIFY_IS_EQUAL(1, q.PopBack());
105  VERIFY_IS_EQUAL(2, q.PopBack());
106  VERIFY_IS_EQUAL(3, q.PopBack());
107  VERIFY(q.Empty());
108  VERIFY_IS_EQUAL(0u, q.Size());
109 }
Definition: RunQueue.h:41
#define VERIFY(a)
Definition: main.h:362
#define VERIFY_IS_EQUAL(a, b)
Definition: main.h:367
EIGEN_DEVICE_FUNC const Scalar & q
Definition: SpecialFunctionsImpl.h:2019

References Eigen::numext::q, VERIFY, and VERIFY_IS_EQUAL.

Referenced by EIGEN_DECLARE_TEST().

◆ test_empty_runqueue()

void test_empty_runqueue ( )
118  {
120  q.PushFront(1);
121  std::atomic<bool> done(false);
122  std::thread mutator([&q, &done]() {
123  unsigned rnd = 0;
124  std::vector<int> stolen;
125  for (int i = 0; i < 1 << 18; i++) {
126  if (rand_reentrant(&rnd) % 2)
127  VERIFY_IS_EQUAL(0, q.PushFront(1));
128  else
129  VERIFY_IS_EQUAL(0, q.PushBack(1));
130  if (rand_reentrant(&rnd) % 2)
131  VERIFY_IS_EQUAL(1, q.PopFront());
132  else {
133  for (;;) {
134  if (q.PopBackHalf(&stolen) == 1) {
135  stolen.clear();
136  break;
137  }
138  VERIFY_IS_EQUAL(0u, stolen.size());
139  }
140  }
141  }
142  done = true;
143  });
144  while (!done) {
145  VERIFY(!q.Empty());
146  int size = q.Size();
147  VERIFY_GE(size, 1);
148  VERIFY_LE(size, 2);
149  }
150  VERIFY_IS_EQUAL(1, q.PopFront());
151  mutator.join();
152 }
int i
Definition: BiCGSTAB_step_by_step.cpp:9
Scalar Scalar int size
Definition: benchVecAdd.cpp:17
if(UPLO(*uplo)==INVALID) info
Definition: level3_impl.h:428
#define VERIFY_GE(a, b)
Definition: main.h:364
#define VERIFY_LE(a, b)
Definition: main.h:365
int rand_reentrant(unsigned int *s)
Definition: threads_runqueue.cpp:18

References i, if(), Eigen::numext::q, rand_reentrant(), and VERIFY_IS_EQUAL.

Referenced by EIGEN_DECLARE_TEST().

◆ test_stress_runqueue()

void test_stress_runqueue ( )
157  {
158  static const int kEvents = 1 << 18;
160  std::atomic<int> total(0);
161  std::vector<std::unique_ptr<std::thread>> threads;
162  threads.emplace_back(new std::thread([&q, &total]() {
163  int sum = 0;
164  int pushed = 1;
165  int popped = 1;
166  while (pushed < kEvents || popped < kEvents) {
167  if (pushed < kEvents) {
168  if (q.PushFront(pushed) == 0) {
169  sum += pushed;
170  pushed++;
171  }
172  }
173  if (popped < kEvents) {
174  int v = q.PopFront();
175  if (v != 0) {
176  sum -= v;
177  popped++;
178  }
179  }
180  }
181  total += sum;
182  }));
183  for (int i = 0; i < 2; i++) {
184  threads.emplace_back(new std::thread([&q, &total]() {
185  int sum = 0;
186  for (int j = 1; j < kEvents; j++) {
187  if (q.PushBack(j) == 0) {
188  sum += j;
189  continue;
190  }
192  j--;
193  }
194  total += sum;
195  }));
196  threads.emplace_back(new std::thread([&q, &total]() {
197  int sum = 0;
198  std::vector<int> stolen;
199  for (int j = 1; j < kEvents;) {
200  if (q.PopBackHalf(&stolen) == 0) {
201  EIGEN_THREAD_YIELD();
202  continue;
203  }
204  while (stolen.size() && j < kEvents) {
205  int v = stolen.back();
206  stolen.pop_back();
207  VERIFY_IS_NOT_EQUAL(v, 0);
208  sum += v;
209  j++;
210  }
211  }
212  while (stolen.size()) {
213  int v = stolen.back();
214  stolen.pop_back();
215  VERIFY_IS_NOT_EQUAL(v, 0);
216  while ((v = q.PushBack(v)) != 0) EIGEN_THREAD_YIELD();
217  }
218  total -= sum;
219  }));
220  }
221  for (size_t i = 0; i < threads.size(); i++) threads[i]->join();
222  VERIFY(q.Empty());
223  VERIFY(total.load() == 0);
224 }
Array< int, Dynamic, 1 > v
Definition: Array_initializer_list_vector_cxx11.cpp:1
#define EIGEN_THREAD_YIELD()
Definition: ThreadYield.h:14
std::ptrdiff_t j
Definition: tut_arithmetic_redux_minmax.cpp:2

References EIGEN_THREAD_YIELD, i, j, Eigen::numext::q, v, and VERIFY.

Referenced by EIGEN_DECLARE_TEST().