Skip to content
Snippets Groups Projects
SimpleFibTest.cpp 1.63 KiB
// SPDX-License-Identifier: LGPL-3.0-or-later
// Copyright © 2020 Florian Schmaus
#include <stdlib.h>	 // for exit, EXIT_FAILURE, EXIT_SUC...

#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

typedef struct {
	int n;
	int* result;
	PS* sem;
} fibParams;

static void fib(void* voidParams) {
	fibParams* params = static_cast<fibParams*>(voidParams);
	int n = params->n;
	int* result = params->result;
	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);

		newSem.wait();

		*result = a + b;
	}

	sem->signalAndExit();
}

int main(UNUSED_ARG int argc, UNUSED_ARG char* argv[]) {
	Runtime runtime;

	Fiber* fibFiber = Fiber::from(
			[](UNUSED_ARG void* arg) {
				const int fibNum = 13;
				int result;
				BPS sem;
				fibParams params = {fibNum, &result, &sem};

				fib(&params);

				sem.wait();

				if (result != 233) {
					exit(EXIT_FAILURE);
				}

				exit(EXIT_SUCCESS);
			},
			nullptr);

	runtime.schedule(*fibFiber);

	runtime.waitUntilFinished();

	return EXIT_FAILURE;
}