From cbe2a880f049b78ee0fac894efd3ddd8d2bd7091 Mon Sep 17 00:00:00 2001 From: Florian Fischer <florian.fl.fischer@fau.de> Date: Thu, 19 Nov 2020 17:29:45 +0100 Subject: [PATCH] [test] add AlarmActorTest Introduce a new Actor test using BinaryPrivateSemaphores and an Actor. Multiple fibers are created which create a BPS on the stack, submit it to the actor and wait on the semaphore. The Actor simply signals each semaphore it receives. --- tests/AlarmActorTest.cpp | 79 ++++++++++++++++++++++++++++++++++++++++ tests/meson.build | 5 +++ 2 files changed, 84 insertions(+) create mode 100644 tests/AlarmActorTest.cpp diff --git a/tests/AlarmActorTest.cpp b/tests/AlarmActorTest.cpp new file mode 100644 index 00000000..e83ac8ec --- /dev/null +++ b/tests/AlarmActorTest.cpp @@ -0,0 +1,79 @@ +// SPDX-License-Identifier: LGPL-3.0-or-later +// Copyright © 2020 Florian Fischer +#include <cstdlib> // for exit, EXIT_FAILURE, EXIT_SUC... +#include <iostream> // for operator<<, basic_ostream + +#include "Actor.hpp" // for Actor +#include "BinaryPrivateSemaphore.hpp" // for BPS +#include "CountingPrivateSemaphore.hpp" // for CPS +#include "Fiber.hpp" // for Fiber +#include "Runtime.hpp" // for Runtime +#include "emper.hpp" // for spawn + +class AlarmActor : public Actor<BPS*> { + protected: + void receive(BPS* sem) override { sem->signal(); } + + public: + AlarmActor(Runtime& runtime) : Actor(runtime) {} + void stop() { Actor::stop(); } +}; + +auto main(int argc, char* argv[]) -> int { + unsigned int sleeper_count = 10; + unsigned int sleeps = 1000; + + if (argc > 3) { + std::cerr << "Usage: " << argv[0] << " [fiber count] [block count]" << std::endl; + exit(EXIT_FAILURE); + } + + const int DECIMAL = 10; + if (argc > 1) { + sleeper_count = strtol(argv[1], nullptr, DECIMAL); + } + + if (argc > 2) { + sleeps = strtol(argv[2], nullptr, DECIMAL); + } + + Runtime runtime; + + AlarmActor alarmActor(runtime); + alarmActor.start(); + + Fiber* fiber = Fiber::from([&] { + CPS cps; + for (unsigned int i = 0; i < sleeper_count; ++i) { + spawn( + [&alarmActor, &sleeps] { + for (unsigned int i = 1; i <= sleeps; ++i) { + BPS sem; + alarmActor.tell(&sem); + sem.wait(); + } + }, + cps); + } + + // Wait for the sleeping fibers to finish + cps.wait(); + + // Wait for the actor to become idle. + bool actorIdle = alarmActor.waitUntilIdle(60 * 1000); + if (!actorIdle) { + std::cerr << "FAILURE: Actor did not went idle"; + exit(EXIT_FAILURE); + } + + alarmActor.stop(); + + exit(EXIT_SUCCESS); + }); + + runtime.schedule(*fiber); + + runtime.waitUntilFinished(); + + return EXIT_FAILURE; +} diff --git a/tests/meson.build b/tests/meson.build index 2ac875c0..7722aa1e 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -25,6 +25,11 @@ tests = { 'description': 'Simple Actor Test', }, + 'AlarmActorTest.cpp': + { + 'description': 'Use an Actor to unblock fibers using BPS', + }, + 'SimpleLawsTest.cpp': { 'description': 'Simple LAWS scheduling strategy test', -- GitLab