Skip to content

Commit 54d42bd

Browse files
committed
Dining philosophers test or toy benchmark
1 parent 8469938 commit 54d42bd

File tree

1 file changed

+49
-0
lines changed

1 file changed

+49
-0
lines changed

internals/testing/dining_test.cpp

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
#include "trade_v1/trade.hpp"
2+
3+
#include "testing_v1/test.hpp"
4+
5+
#include <thread>
6+
7+
using namespace trade_v1;
8+
using namespace testing_v1;
9+
10+
constexpr size_t n_to_eat = 100000;
11+
constexpr size_t n_philosophers = 5;
12+
13+
struct fork {
14+
fork() : on_table(true) {}
15+
16+
alignas(64) atom<bool> on_table;
17+
};
18+
19+
auto dining_test = test([]() {
20+
atom<size_t> done = 0;
21+
22+
fork forks[n_philosophers];
23+
24+
for (size_t philosopher = 0; philosopher < n_philosophers; ++philosopher)
25+
std::thread([&, philosopher]() {
26+
auto &left = forks[philosopher];
27+
auto &right = forks[(philosopher + 1) % n_philosophers];
28+
29+
for (size_t e = 0; e < n_to_eat; ++e) {
30+
atomically([&]() {
31+
bool &left_on_table = left.on_table.ref();
32+
bool &right_on_table = right.on_table.ref();
33+
if (left_on_table && right_on_table)
34+
left_on_table = right_on_table = false;
35+
else
36+
retry();
37+
});
38+
39+
atomically([&]() { left.on_table = right.on_table = true; });
40+
}
41+
42+
atomically([&]() { ++done.ref(); });
43+
}).detach();
44+
45+
atomically([&]() {
46+
if (done != n_philosophers)
47+
retry();
48+
});
49+
});

0 commit comments

Comments
 (0)