Newer
Older
// SPDX-License-Identifier: LGPL-3.0-or-later
// Copyright © 2021 Florian Schmaus
#include <cstdlib> // for abort, exit, EXIT_SUCCESS
#include <iostream> // for operator<<, basic_ostream::o...
#include "BinaryPrivateSemaphore.hpp" // for BPS
#include "CountingPrivateSemaphore.hpp" // for CPS
#include "Debug.hpp" // for DBG
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#include "Fiber.hpp" // for Fiber
#include "PrivateSemaphore.hpp" // for PS
#include "Runtime.hpp" // for Runtime
#include "emper-common.h" // for UNUSED_ARG
#include "emper.hpp" // for async
#include "lib/sync/Semaphore.hpp"
using fibParams = struct {
int n;
int* result;
PS* sem;
};
static void fib(void* voidParams) {
auto* params = static_cast<fibParams*>(voidParams);
int n = params->n;
int* result = params->result;
if (!result) {
std::cerr << "voidParams: " << voidParams << " n: " << params->n << " sem: " << params->sem
<< std::endl;
abort();
}
PS* sem = params->sem;
if (n < 2) {
*result = n;
} else {
CPS newSem(2);
int a, b;
fibParams newParams1;
newParams1.n = n - 1;
newParams1.result = &a;
newParams1.sem = &newSem;
fibParams newParams2;
newParams2.n = n - 2;
newParams2.result = &b;
newParams2.sem = &newSem;
Fiber* f1 = Fiber::from(&fib, &newParams1);
Fiber* f2 = Fiber::from(&fib, &newParams2);
Runtime* runtime = Runtime::getRuntime();
runtime->schedule(*f1);
runtime->schedule(*f2);
DBG("fib: Calling wait for n=" << n);
newSem.wait();
*result = a + b;
}
DBG("fib: Calling signalAndExit for n=" << n);
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
sem->signalAndExit();
}
static emper::lib::sync::Semaphore exit_semaphore;
static void fibKickoff() {
const int fibNum = 2;
int result;
BPS sem;
fibParams params = {fibNum, &result, &sem};
Fiber* fibFiber = Fiber::from(fib, ¶ms);
async(fibFiber);
sem.wait();
std::cout << "fib(" << fibNum << ") = " << result << std::endl;
exit_semaphore.notify();
}
auto main(UNUSED_ARG int argc, UNUSED_ARG char* argv[]) -> int {
// const unsigned nthreads = std::thread::hardware_concurrency();
const unsigned nthreads = 2;
std::cout << "Number of threads: " << nthreads << std::endl;
Runtime runtime(nthreads);
Fiber* fibFiber = Fiber::from(&fibKickoff);
std::cout << "Just alloacted alpha fiber at " << fibFiber << std::endl;
runtime.scheduleFromAnywhere(*fibFiber);
exit_semaphore.wait();
// Once Runtime goes out of scope, it's desctructor will be called,
// which, in turn, terminates the runtime, and hence causes the
// behavior this test is checking.
return 0;
}