// SPDX-License-Identifier: LGPL-3.0-or-later // Copyright © 2020 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 #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 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); sem->signalAndExit(); } 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(EXIT_SUCCESS); } 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); runtime.waitUntilFinished(); return 0; }