Lumiera 0.pre.04
»edit your freedom«
Loading...
Searching...
No Matches
sync-barrier-test.cpp
Go to the documentation of this file.
1/*
2 SyncBarrier(Test) - verify yield-waiting synchronisation latch
3
4 Copyright (C)
5 2023, Hermann Vosseler <Ichthyostega@web.de>
6
7  **Lumiera** is free software; you can redistribute it and/or modify it
8  under the terms of the GNU General Public License as published by the
9  Free Software Foundation; either version 2 of the License, or (at your
10  option) any later version. See the file COPYING for further details.
11
12* *****************************************************************/
13
19#include "lib/test/run.hpp"
20#include "lib/sync-barrier.hpp"
21#include "lib/iter-explorer.hpp"
22#include "lib/thread.hpp"
23
24#include <chrono>
25#include <atomic>
26#include <array>
27
28using test::Test;
29using lib::explore;
30using std::array;
31
32using std::atomic_uint;
33using std::this_thread::sleep_for;
34using namespace std::chrono_literals;
35
36
37namespace lib {
38namespace test {
39
40 namespace {// Test setup for a concurrent calculation with checksum....
41
42 const uint NUM_THREADS = 256;
43
44 atomic_uint stage1{0};
45 atomic_uint stage2{0};
46 atomic_uint finish{0};
47
48 SyncBarrier interThread{NUM_THREADS };
49 SyncBarrier afterThread{NUM_THREADS+1};
50
58 : public lib::Thread
59 {
60 public:
62 : Thread{"Load Test"
63 ,[&, ran=lib::Random{seedFromDefaultGen()}]
64 () mutable
65 { //-STAGE-1------------------------------
66 localSum = ran.i(1000); // generate local value
67 stage1.fetch_add (localSum); // book in local value
68 interThread.sync(); // wait for all other threads to have booked in
69
70 //-STAGE-2------------------------------
71 uint sync = stage1; // pick up compounded sum from STAGE-1
72 localSum += ran.i(1000); // add further local value for STAGE-2
73 stage2.fetch_add (localSum+sync); // book in both local values and synced sum
74 afterThread.sync(); // wait for other threads and supervisor
75
76 finish.fetch_add(1); // mark completion of this thread
77 }}
78 { }
79
80 uint localSum; // *deliberately* not initialised to avoid race
81 };
82
83
85 template<class CON>
86 uint
87 sumLocals (CON const& threads)
88 {
89 return explore (threads)
90 .reduce ([&](TestThread const& t){ return t.localSum; });
91 }
92 }//(End)Test setup
93
94
95
96
97 /*******************************************************************/
106 class SyncBarrier_test : public Test
107 {
108
109 virtual void
110 run (Arg)
111 {
112 seedRand();
113 // Launch several TestThread
114 array<TestThread,NUM_THREADS> threads;
115
116 CHECK (0 == finish);
117 CHECK (explore(threads).and_all());
118
119 afterThread.sync();
120 sleep_for (5ms); // give the threads a chance to terminate
121
122 CHECK (NUM_THREADS == finish); // all threads have passed out....
123 CHECK (0 < stage1);
124 CHECK (stage1 < stage2);
125 CHECK (stage2 > sumLocals(threads));
126 CHECK (stage2 == sumLocals(threads) + NUM_THREADS*stage1); // this holds only if all threads waited to get the complete stage1 sum
127 }
128 };
129
130
131
133 LAUNCHER (SyncBarrier_test, "function common");
134
135
136
137}} // namespace lib::test
A one time N-fold mutual synchronisation barrier.
A thin convenience wrapper to simplify thread-handling.
Definition thread.hpp:650
A test thread to perform a summation protocol including synchronisation points.
Abstract Base Class for all testcases.
Definition run.hpp:54
unsigned int uint
Definition integral.hpp:29
Building tree expanding and backtracking evaluations within hierarchical scopes.
uint sumLocals(CON const &threads)
sum up all localSum fields from all TestThread instances in a container
Implementation namespace for support and library code.
SeedNucleus & seedFromDefaultGen()
draw seed another Generator from the default RandomSequencer
Definition random.cpp:74
auto explore(IT &&srcSeq)
start building a IterExplorer by suitably wrapping the given iterable source.
Test runner and basic definitions for tests.
Simplistic test class runner.
#define LAUNCHER(_TEST_CLASS_, _GROUPS_)
Definition run.hpp:116
A N-fold synchronisation latch using yield-wait until fulfilment.
Convenience front-end to simplify and codify basic thread handling.