From 3936a28520b5032d705c5e53bd426d7020eec550 Mon Sep 17 00:00:00 2001 From: Niklas Hauser Date: Fri, 29 Oct 2021 02:56:30 +0200 Subject: [PATCH] [examples] Add fiber examples --- .github/workflows/windows_hosted.yml | 2 +- examples/avr/fiber/main.cpp | 89 ++++++++++++++++++++++++++++ examples/avr/fiber/project.xml | 13 ++++ examples/generic/fiber/main.cpp | 89 ++++++++++++++++++++++++++++ examples/generic/fiber/project.xml | 13 ++++ examples/linux/fiber/main.cpp | 51 ++++++++++++++++ examples/linux/fiber/project.xml | 14 +++++ 7 files changed, 270 insertions(+), 1 deletion(-) create mode 100644 examples/avr/fiber/main.cpp create mode 100644 examples/avr/fiber/project.xml create mode 100644 examples/generic/fiber/main.cpp create mode 100644 examples/generic/fiber/project.xml create mode 100644 examples/linux/fiber/main.cpp create mode 100644 examples/linux/fiber/project.xml diff --git a/.github/workflows/windows_hosted.yml b/.github/workflows/windows_hosted.yml index 4b247a1e48..a564262f90 100644 --- a/.github/workflows/windows_hosted.yml +++ b/.github/workflows/windows_hosted.yml @@ -56,7 +56,7 @@ jobs: - name: Hosted Examples shell: bash run: | - (cd examples && python ../tools/scripts/examples_compile.py linux/assert linux/block_device linux/build_info linux/git linux/logger linux/printf) + (cd examples && python ../tools/scripts/examples_compile.py linux/assert linux/block_device linux/build_info linux/git linux/logger linux/printf linux/etl linux/fiber) - name: Hosted Unittests if: always() diff --git a/examples/avr/fiber/main.cpp b/examples/avr/fiber/main.cpp new file mode 100644 index 0000000000..0a08a7c1cd --- /dev/null +++ b/examples/avr/fiber/main.cpp @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2020, Erik Henriksson + * + * This file is part of the modm project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +// ---------------------------------------------------------------------------- + +#include +#include +#include + +using namespace Board; +using namespace std::chrono_literals; + +constexpr uint32_t cycles = 100'000; +volatile uint32_t f1counter = 0, f2counter = 0; +uint32_t total_counter=0; + +void +fiber_function1() +{ + MODM_LOG_INFO << MODM_FILE_INFO << modm::endl; + while (++f1counter < cycles) { modm::fiber::yield(); total_counter++; } +} + +void +fiber_function2(uint32_t cyc) +{ + MODM_LOG_INFO << MODM_FILE_INFO << modm::endl; + while (++f2counter < cyc) { modm::fiber::yield(); total_counter++; } +} + +struct Test +{ + void + fiber_function3() + { + MODM_LOG_INFO << MODM_FILE_INFO << modm::endl; + while (++f3counter < cycles) { modm::fiber::yield(); total_counter++; } + } + + void + fiber_function4(uint32_t cyc) + { + MODM_LOG_INFO << MODM_FILE_INFO << modm::endl; + while (++f4counter < cyc) { modm::fiber::yield(); total_counter++; } + } + + volatile uint32_t f3counter{0}; + volatile uint32_t f4counter{0}; +} test; + +modm::fiber::Stack<128> stack1; +modm::fiber::Stack<128> stack2; +modm::fiber::Stack<128> stack3; +modm::fiber::Stack<128> stack4; +modm::Fiber fiber1(stack1, fiber_function1); +modm::Fiber fiber2(stack2, [](){ fiber_function2(cycles); }); +modm::Fiber fiber3(stack3, [](){ test.fiber_function3(); }); +modm::Fiber fiber4(stack4, [cyc=uint32_t(cycles)]() mutable { cyc++; test.fiber_function4(cyc); }); + +// ATmega2560@16MHz: 239996 yields in 2492668us, 96280 yields per second, 10386ns per yield +int +main() +{ + Board::initialize(); + Board::LedD13::setOutput(); + MODM_LOG_INFO << "Starting fiber modm::yield benchmark..." << modm::endl; + MODM_LOG_INFO.flush(); + + const modm::PreciseTimestamp start = modm::PreciseClock::now(); + modm::fiber::Scheduler::run(); + const auto diff = (modm::PreciseClock::now() - start); + + MODM_LOG_INFO << "Benchmark done!" << modm::endl; + MODM_LOG_INFO << "Executed " << total_counter << " yields in " << diff << modm::endl; + MODM_LOG_INFO << uint32_t((total_counter * 1'000'000ull) / std::chrono::microseconds(diff).count()); + MODM_LOG_INFO << " yields per second, "; + MODM_LOG_INFO << uint32_t(std::chrono::nanoseconds(diff).count() / total_counter); + MODM_LOG_INFO << "ns per yield" << modm::endl; + MODM_LOG_INFO.flush(); + + while(1) ; + return 0; +} diff --git a/examples/avr/fiber/project.xml b/examples/avr/fiber/project.xml new file mode 100644 index 0000000000..b098fe58bb --- /dev/null +++ b/examples/avr/fiber/project.xml @@ -0,0 +1,13 @@ + + modm:mega-2560-pro + + + + + + + modm:build:scons + modm:processing:timer + modm:processing:fiber + + diff --git a/examples/generic/fiber/main.cpp b/examples/generic/fiber/main.cpp new file mode 100644 index 0000000000..4bb894cc76 --- /dev/null +++ b/examples/generic/fiber/main.cpp @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2020, Erik Henriksson + * + * This file is part of the modm project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +// ---------------------------------------------------------------------------- + +#include +#include +#include + +using namespace Board; +using namespace std::chrono_literals; + +constexpr uint32_t cycles = 1'000'000; +volatile uint32_t f1counter = 0, f2counter = 0; +uint32_t total_counter=0; + +void +fiber_function1() +{ + MODM_LOG_INFO << MODM_FILE_INFO << modm::endl; + while (++f1counter < cycles) { modm::fiber::yield(); total_counter++; } +} + +void +fiber_function2(uint32_t cyc) +{ + MODM_LOG_INFO << MODM_FILE_INFO << modm::endl; + while (++f2counter < cyc) { modm::fiber::yield(); total_counter++; } +} + +struct Test +{ + void + fiber_function3() + { + MODM_LOG_INFO << MODM_FILE_INFO << modm::endl; + while (++f3counter < cycles) { modm::fiber::yield(); total_counter++; } + } + + void + fiber_function4(uint32_t cyc) + { + MODM_LOG_INFO << MODM_FILE_INFO << modm::endl; + while (++f4counter < cyc) { modm::fiber::yield(); total_counter++; } + } + + volatile uint32_t f3counter{0}; + volatile uint32_t f4counter{0}; +} test; + +modm_faststack modm::fiber::Stack<2048> stack1; +modm_faststack modm::fiber::Stack<2048> stack2; +modm_faststack modm::fiber::Stack<2048> stack3; +modm_faststack modm::fiber::Stack<2048> stack4; +modm_fastdata modm::Fiber fiber1(stack1, fiber_function1); +modm_fastdata modm::Fiber fiber2(stack2, [](){ fiber_function2(cycles); }); +modm_fastdata modm::Fiber fiber3(stack3, [](){ test.fiber_function3(); }); +modm_fastdata modm::Fiber fiber4(stack4, [cyc=uint32_t(0)]() mutable { cyc++; test.fiber_function4(cyc); }); + +// Blue pill (M3 72MHz): Executed 1000000 in 1098591us (910256.88 yields per second) +// Feather M0 (M0+ 48MHz): Executed 1000000 in 1944692us (514220.25 yields per second) +int +main() +{ + Board::initialize(); + MODM_LOG_INFO << "Starting fiber modm::yield benchmark..." << modm::endl; + MODM_LOG_INFO.flush(); + + const modm::PreciseTimestamp start = modm::PreciseClock::now(); + modm::fiber::Scheduler::run(); + const auto diff = (modm::PreciseClock::now() - start); + + MODM_LOG_INFO << "Benchmark done!" << modm::endl; + MODM_LOG_INFO << "Executed " << total_counter << " yields in " << diff << modm::endl; + MODM_LOG_INFO << ((total_counter * 1'000'000ull) / std::chrono::microseconds(diff).count()); + MODM_LOG_INFO << " yields per second, "; + MODM_LOG_INFO << (std::chrono::nanoseconds(diff).count() / total_counter); + MODM_LOG_INFO << "ns per yield" << modm::endl; + MODM_LOG_INFO.flush(); + + while(1) ; + return 0; +} diff --git a/examples/generic/fiber/project.xml b/examples/generic/fiber/project.xml new file mode 100644 index 0000000000..c56d1a430b --- /dev/null +++ b/examples/generic/fiber/project.xml @@ -0,0 +1,13 @@ + + modm:nucleo-f429zi + + + + + + + modm:build:scons + modm:processing:timer + modm:processing:fiber + + diff --git a/examples/linux/fiber/main.cpp b/examples/linux/fiber/main.cpp new file mode 100644 index 0000000000..9a611a60a5 --- /dev/null +++ b/examples/linux/fiber/main.cpp @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2021, Niklas Hauser + * + * This file is part of the modm project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +// ---------------------------------------------------------------------------- + +#include +#include + +void hello() +{ + for(int ii=0; ii<10; ii++) + { + MODM_LOG_INFO << "Hello "; + modm::fiber::yield(); + } +} + +struct Test +{ + void world(const char *arg) + { + for(int ii=0; ii<10; ii++) + { + MODM_LOG_INFO << arg << modm::endl; + modm::fiber::yield(); + } + } +} test; + +modm::fiber::Stack<1024> stack1; +modm::fiber::Stack<1024> stack2; +modm::Fiber fiber1(stack1, hello); + +int +main(void) +{ + const char *arg = "World"; + modm::Fiber fiber2(stack2, [=]() { test.world(arg); }); + + MODM_LOG_INFO << "Start" << modm::endl; + modm::fiber::Scheduler::run(); + MODM_LOG_INFO << "End" << modm::endl; + + return 0; +} diff --git a/examples/linux/fiber/project.xml b/examples/linux/fiber/project.xml new file mode 100644 index 0000000000..0ce537f337 --- /dev/null +++ b/examples/linux/fiber/project.xml @@ -0,0 +1,14 @@ + + + + + + + + + modm:debug + modm:platform:core + modm:processing:fiber + modm:build:scons + +