diff --git a/core/src/main/resources/lib/cpp/reactor-cpp b/core/src/main/resources/lib/cpp/reactor-cpp index 521f1d852b..fa685f1db9 160000 --- a/core/src/main/resources/lib/cpp/reactor-cpp +++ b/core/src/main/resources/lib/cpp/reactor-cpp @@ -1 +1 @@ -Subproject commit 521f1d852b6b3dc5850d3dcfc669ea812296db94 +Subproject commit fa685f1db99b1652e39a5cf3c6356a8db26b52bb diff --git a/test/Cpp/src/ShutdownAsync.lf b/test/Cpp/src/ShutdownAsync.lf new file mode 100644 index 0000000000..c1ec5ed8e5 --- /dev/null +++ b/test/Cpp/src/ShutdownAsync.lf @@ -0,0 +1,28 @@ +target Cpp + +main reactor { + logical action check_shutdown + timer request_shutdown(1 ms) + timer after_shutdown(2 ms) + + reaction(request_shutdown) -> check_shutdown {= + // async_shutdown can be called from external threads to shutdown + // at the next possible tag. If it is called from a reaction, the + // next possible tag should always be the next microstep. + environment()->async_shutdown(); + check_shutdown.schedule(); + =} + + reaction(shutdown, check_shutdown) {= + if (!(shutdown.is_present() && check_shutdown.is_present())) { + reactor::log::Error() << "shutdown was not triggered at the expcetd tag"; + exit(1); + } + reactor::log::Info() << "Success!"; + =} + + reaction(after_shutdown) {= + reactor::log::Error() << "triggered a reaction after shutdown"; + exit(2); + =} +} diff --git a/test/Cpp/src/ShutdownSync.lf b/test/Cpp/src/ShutdownSync.lf new file mode 100644 index 0000000000..a07e4f2a59 --- /dev/null +++ b/test/Cpp/src/ShutdownSync.lf @@ -0,0 +1,25 @@ +target Cpp + +main reactor { + logical action check_shutdown + timer request_shutdown(1 ms) + timer after_shutdown(2 ms) + + reaction(request_shutdown) -> check_shutdown {= + environment()->sync_shutdown(); + check_shutdown.schedule(); + =} + + reaction(shutdown, check_shutdown) {= + if (!(shutdown.is_present() && check_shutdown.is_present())) { + reactor::log::Error() << "shutdown was not triggered at the expcetd tag"; + exit(1); + } + reactor::log::Info() << "Success!"; + =} + + reaction(after_shutdown) {= + reactor::log::Error() << "triggered a reaction after shutdown"; + exit(2); + =} +} diff --git a/test/Cpp/src/Starve.lf b/test/Cpp/src/Starve.lf new file mode 100644 index 0000000000..73f4e4ecfc --- /dev/null +++ b/test/Cpp/src/Starve.lf @@ -0,0 +1,24 @@ +target Cpp + +main reactor { + timer t(1 s) + logical action after_shutdown: void + + reaction(t) -> after_shutdown {= + reactor::log::Info() << "Timer triggered at " << get_tag(); + =} + + reaction(shutdown) -> after_shutdown {= + reactor::log::Info() << "Shutdown triggered at " << get_tag(); + if(get_elapsed_logical_time() != 1s || get_microstep() != 1) { + reactor::log::Error() << "Shutdown invoked at wrong tag"; + exit(2); + } + after_shutdown.schedule(); + =} + + reaction(after_shutdown) {= + reactor::log::Error() << "Executed a reaction after shutdown"; + exit(1); + =} +} diff --git a/test/Cpp/src/StarveZero.lf b/test/Cpp/src/StarveZero.lf new file mode 100644 index 0000000000..e7463f6424 --- /dev/null +++ b/test/Cpp/src/StarveZero.lf @@ -0,0 +1,19 @@ +target Cpp + +main reactor { + logical action after_shutdown: void + + reaction(shutdown) -> after_shutdown {= + reactor::log::Info() << "Shutdown triggered at " << get_tag(); + if(get_elapsed_logical_time() != 0s || get_microstep() != 1) { + reactor::log::Error() << "Shutdown invoked at wrong tag"; + exit(2); + } + after_shutdown.schedule(); + =} + + reaction(after_shutdown) {= + reactor::log::Error() << "Executed a reaction after shutdown"; + exit(1); + =} +} diff --git a/test/Cpp/src/TimeLimit.lf b/test/Cpp/src/TimeLimit.lf index 1d11882740..28cb3894ef 100644 --- a/test/Cpp/src/TimeLimit.lf +++ b/test/Cpp/src/TimeLimit.lf @@ -19,23 +19,39 @@ reactor Clock(offset: time = 0, period: time = 1 sec) { reactor Destination { input x: int state s: int = 1 + state shutdown_invoked: bool = false + input check_shutdown: void reaction(x) {= //std::cout << "Received " << *x.get() << '\n'; if (*x.get() != s) { - std::cerr << "Error: Expected " << s << " and got " << *x.get() << '\n'; + reactor::log::Error() << "Expected " << s << " and got " << *x.get(); exit(1); } + if (*x.get() == 12 && !shutdown_invoked) { + reactor::log::Error() << "Shutdown wasn't invoked!"; + } s++; =} reaction(shutdown) {= std::cout << "**** shutdown reaction invoked.\n"; + shutdown_invoked = true; + if(get_microstep() != 1) { + reactor::log::Error() << "Expected microstep == 1, but got " << get_microstep(); + exit(2); + } if (s != 12) { - std::cerr << "ERROR: Expected 12 but got " << s << '\n'; + reactor::log::Error() << "Expected 12 but got " << s; exit(1); } =} + + reaction(check_shutdown) {= + if (!shutdown_invoked) { + reactor::log::Error() << "Shutdown wasn't invoked!"; + } + =} } main reactor TimeLimit(period: time = 1 sec) { @@ -44,7 +60,14 @@ main reactor TimeLimit(period: time = 1 sec) { d = new Destination() c.y -> d.x - reaction(stop) {= + logical action check: void + + reaction(stop) -> check {= environment()->sync_shutdown(); + check.schedule(); + =} + + reaction(check) -> d.check_shutdown {= + d.check_shutdown.set(); =} } diff --git a/test/Cpp/src/Timeout_Test.lf b/test/Cpp/src/Timeout_Test.lf deleted file mode 100644 index aac8a04934..0000000000 --- a/test/Cpp/src/Timeout_Test.lf +++ /dev/null @@ -1,44 +0,0 @@ -/** - * A test for the timeout functionality in Lingua Franca. - * - * @author Maiko Brants TU Dresden - * - * Modeled after the C version of this test. - */ -target Cpp { - timeout: 11 msec -} - -import Sender from "lib/LoopedActionSender.lf" - -reactor Consumer { - input in: int - state success: bool = false - - reaction(in) {= - auto current{get_elapsed_logical_time()}; - if(current > 11ms ){ - reactor::log::Error() << "Received at: " << current.count() << ". Failed to enforce timeout."; - exit(1); - } else if(current == 11ms) { - success=true; - } - =} - - reaction(shutdown) {= - reactor::log::Info() << "Shutdown invoked at " << get_elapsed_logical_time(); - if((get_elapsed_logical_time() == 11ms ) && (success == true)){ - reactor::log::Info() << "SUCCESS: successfully enforced timeout."; - } else { - reactor::log::Error() << "Shutdown invoked at: " << get_elapsed_logical_time() << ". Failed to enforce timeout."; - exit(1); - } - =} -} - -main reactor Timeout_Test { - consumer = new Consumer() - producer = new Sender(take_a_break_after=10, break_interval = 1 msec) - - producer.out -> consumer.in -} diff --git a/test/Cpp/src/properties/Timeout.lf b/test/Cpp/src/properties/Timeout.lf index a278d6d712..95d60963f5 100644 --- a/test/Cpp/src/properties/Timeout.lf +++ b/test/Cpp/src/properties/Timeout.lf @@ -1,31 +1,65 @@ +/** + * A test for the timeout functionality in Lingua Franca. + * + * @author Maiko Brants TU Dresden + * + * Modeled after the C version of this test. + */ target Cpp { - timeout: 1 sec + timeout: 11 msec } -main reactor { - timer t(1 sec, 1 sec) +import Sender from "../lib/LoopedActionSender.lf" + +reactor Consumer { + input in: int + state success: bool = false - state triggered: bool = false + logical action after_shutdown: void - reaction(t) {= - triggered = true; - if (get_elapsed_logical_time() != 1s) { - std::cout << "ERROR: triggered reaction at an unexpected tag"; + timer check_shutdown(11 ms) + + reaction(in) {= + auto current{get_elapsed_logical_time()}; + if(current > 11ms ){ + reactor::log::Error() << "Received at: " << current.count() << ". Failed to enforce timeout."; exit(1); + } else if(current == 11ms) { + success=true; } =} - reaction(shutdown) {= - if (get_elapsed_logical_time() != 1s || get_microstep() != 0) { - std::cout << "ERROR: shutdown invoked at an unexpected tag"; - exit(2); + reaction(shutdown) -> after_shutdown {= + reactor::log::Info() << "Shutdown invoked at tag " << get_tag(); + if((get_elapsed_logical_time() == 11ms ) && get_microstep() == 0 && (success == true)){ + reactor::log::Info() << "SUCCESS: successfully enforced timeout."; + after_shutdown.schedule(); + } else { + reactor::log::Error() << "Failed to enforce timeout at the correct tag."; + exit(1); } + =} - if (triggered) { - std::cout << "SUCCESS!\n"; - } else { - std::cout << "ERROR: reaction was not invoked!\n"; + reaction(check_shutdown, shutdown) {= + if (check_shutdown.is_present() && !shutdown.is_present()) { + reactor::log::Error() << "Shutdown was not triggered at the expected tag"; exit(2); } + if (!check_shutdown.is_present() && shutdown.is_present()) { + reactor::log::Error() << "Shutdown was triggered at an unxpected tag: " << get_tag(); + exit(2); + } + =} + + reaction(after_shutdown) {= + reactor::log::Error() << "Executed a reaction after timeout."; + exit(2); =} } + +main reactor { + consumer = new Consumer() + producer = new Sender(take_a_break_after=10, break_interval = 1 msec) + + producer.out -> consumer.in +} diff --git a/test/Cpp/src/properties/TimeoutZero.lf b/test/Cpp/src/properties/TimeoutZero.lf index 3aa45c7203..7f32565788 100644 --- a/test/Cpp/src/properties/TimeoutZero.lf +++ b/test/Cpp/src/properties/TimeoutZero.lf @@ -1,31 +1,19 @@ target Cpp { - timeout: 0 sec + timeout: 0 s } main reactor { - timer t(0, 1 sec) + timer should_never_trigger(1 s) - state triggered: bool = false - - reaction(t) {= - triggered = true; - if (get_elapsed_logical_time() != 0s) { - std::cout << "ERROR: triggered reaction at an unexpected tag"; + reaction(startup, shutdown) {= + if (!(startup.is_present() && shutdown.is_present())) { + reactor::log::Error() << "Shutdown was not triggered at startup"; exit(1); } =} - reaction(shutdown) {= - if (get_elapsed_logical_time() != 0s || get_microstep() != 0) { - std::cout << "ERROR: shutdown invoked at an unexpected tag"; - exit(2); - } - - if (triggered) { - std::cout << "SUCCESS!\n"; - } else { - std::cout << "ERROR: reaction was not invoked!\n"; - exit(2); - } + reaction(should_never_trigger) {= + reactor::log::Error() << "Executed a reaction after timeout."; + exit(2); =} }