Skip to content
Snippets Groups Projects
RuntimeDestroyTest.cpp 2.51 KiB
Newer Older
  • Learn to ignore specific revisions
  • // 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 "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);
    
    	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, &params);
    	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;
    }