|
8 | 8 | * thread 2: 4
|
9 | 9 | */
|
10 | 10 |
|
11 |
| -#include <condition_variable> |
12 |
| -#include <iostream> |
13 |
| -#include <mutex> |
14 |
| -#include <thread> |
| 11 | +#include "tests.h" |
15 | 12 |
|
| 13 | +/* =========================================================================== |
| 14 | + * Algorithms implementation |
| 15 | + * =========================================================================== |
| 16 | + */ |
| 17 | + |
| 18 | +#define _th_oe_MutexCondVar_desc "Mutex & Conditional Variable" |
| 19 | + |
| 20 | +namespace MutexCondVar |
| 21 | +{ |
16 | 22 | /* threads synchronization primitives */
|
17 |
| -std::mutex mx; |
18 |
| -std::condition_variable cv; |
| 23 | +mutex mx; |
| 24 | +condition_variable cv; |
19 | 25 |
|
20 | 26 | /* shared data between threads */
|
21 | 27 | static int sd = 1;
|
22 | 28 |
|
23 | 29 | #define MAX_DATA 10
|
24 | 30 |
|
25 | 31 | /* cv.wait() predicate objects don't take args */
|
26 |
| -static inline bool is_odd() { return sd % 2; } |
27 |
| -static inline bool is_even() { return !is_odd(); } |
| 32 | +static bool is_odd() { return sd % 2; } |
| 33 | +static bool is_even() { return !is_odd(); } |
28 | 34 |
|
29 |
| -void print_odd(int tidx) |
| 35 | +using Predicate = function<bool()>; |
| 36 | +vpi_t a; |
| 37 | + |
| 38 | +void print(int tidx, Predicate pred) |
30 | 39 | {
|
31 | 40 | while (sd < MAX_DATA) {
|
32 |
| - std::unique_lock<std::mutex> lk(mx); |
| 41 | + unique_lock<mutex> lk(mx); |
33 | 42 | /* cv.wait(lock, predicate) handles spurious wake up */
|
34 |
| - cv.wait(lk, is_even); |
35 |
| - if (getenv("SHOW_TEST_OUTPUT")) |
36 |
| - std::cout << " thread " << tidx << ": " << sd |
37 |
| - << "\n"; |
| 43 | + cv.wait(lk, pred); |
| 44 | + a.emplace_back(tidx, sd); |
38 | 45 | sd++;
|
39 | 46 | cv.notify_one();
|
40 | 47 | }
|
41 | 48 | }
|
| 49 | +} // namespace MutexCondVar |
| 50 | + |
| 51 | +// TODO namespace Semaphores |
42 | 52 |
|
43 |
| -void print_even(int tidx) |
| 53 | +/* =========================================================================== |
| 54 | + * Test code |
| 55 | + * =========================================================================== |
| 56 | + */ |
| 57 | +ostream &operator<<(ostream &out, const vpi_t &c) |
44 | 58 | {
|
45 |
| - while (sd < MAX_DATA) { |
46 |
| - std::unique_lock<std::mutex> lk(mx); |
47 |
| - /* cv.wait(lock, predicate) handles spurious wake up */ |
48 |
| - cv.wait(lk, is_odd); |
49 |
| - if (getenv("SHOW_TEST_OUTPUT")) |
50 |
| - std::cout << " thread " << tidx << ": " << sd |
51 |
| - << "\n"; |
52 |
| - sd++; |
53 |
| - cv.notify_one(); |
| 59 | + int n = size(c); |
| 60 | + fii (i, n) { |
| 61 | + int _tidx = c[i].first, _sd = c[i].second; |
| 62 | + out << format("\n thread {}: {}", _tidx, _sd); |
54 | 63 | }
|
| 64 | + return out; |
55 | 65 | }
|
56 | 66 |
|
57 |
| -int main(int, char **) |
58 |
| -{ |
59 |
| - int tidx[2] = {0, 1}; |
| 67 | +#define _th_oe_desc_prefix "Threads odd even" |
60 | 68 |
|
61 |
| - if (getenv("SHOW_TEST_OUTPUT")) |
62 |
| - std::cout << "Testing implementation " << 1 << " " |
63 |
| - << "sync 2 threads to print odd & even numbers" |
64 |
| - << "\n"; |
| 69 | +#define _TH_OE_NAME(var) var |
| 70 | +#define _TH_OE_DESC(var) _th_oe_desc_prefix " - " _th_oe_##var##_desc |
65 | 71 |
|
66 |
| - std::thread t1(print_odd, tidx[0]); |
67 |
| - std::thread t2(print_even, tidx[1]); |
68 |
| - t1.join(); |
69 |
| - t2.join(); |
| 72 | +#define _TH_OE_TEST(var) \ |
| 73 | + TEST(_TH_OE_NAME(var), _TH_OE_DESC(var)) \ |
| 74 | + { \ |
| 75 | + using namespace _TH_OE_NAME(var); \ |
| 76 | + vpi_t e; \ |
| 77 | + int n = MAX_DATA; \ |
| 78 | + fii (i, n) e.emplace_back(i % 2, i + 1); \ |
| 79 | + int t = 0; \ |
| 80 | + vector<thread> th; \ |
| 81 | + th.emplace_back(move(thread(print, t++, is_odd))); \ |
| 82 | + th.emplace_back(move(thread(print, t++, is_even))); \ |
| 83 | + for (auto &x : th) x.join(); \ |
| 84 | + CHECK_EQ(e, a); \ |
| 85 | + SHOW_OUTPUT(n, a); \ |
| 86 | + } |
70 | 87 |
|
71 |
| - std::cout << "Executed " << 1 << " implementations" |
72 |
| - << " with " << 1 << " tests." << std::endl; |
73 |
| - return 0; |
74 |
| -} |
| 88 | +_TH_OE_TEST(MutexCondVar); |
| 89 | + |
| 90 | +INIT_TEST_MAIN(); |
0 commit comments