Skip to content

Commit

Permalink
[fiber] Adds the fiber processing library
Browse files Browse the repository at this point in the history
  • Loading branch information
salkinium committed Oct 13, 2021
1 parent 2ef7a29 commit 5b3b722
Show file tree
Hide file tree
Showing 41 changed files with 2,118 additions and 25 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ jobs:
- name: Compile AVR Unittests ATmega
if: always()
run: |
(cd test && make compile-mega-2560-pro)
(cd test && make compile-mega-2560-pro_A compile-mega-2560-pro_B)
- name: Quick compile HAL for AVR Devices
if: always()
run: |
Expand Down
59 changes: 59 additions & 0 deletions examples/avr/context/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
* 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 <modm/board.hpp>
#include <modm/debug/logger.hpp>
#include <modm/processing/fiber.hpp>

using namespace Board;
using namespace std::chrono_literals;

uint8_t stack1[512], stack2[512];
modm_context_t f1_ctx, f2_ctx, m_ctx;

void fiber_function1()
{
MODM_LOG_INFO << "f1: entered" << modm::endl;
MODM_LOG_INFO.flush();
while (1)
{
modm_context_jump(&(f1_ctx.sp), f2_ctx.sp);
}
}

void fiber_function2()
{
MODM_LOG_INFO << "f2: entered" << modm::endl;
MODM_LOG_INFO.flush();
while (1)
{
modm_context_jump(&(f2_ctx.sp), f1_ctx.sp);
}
}

int
main()
{
Board::initialize();

f1_ctx = modm_context_init((void**)stack1, sizeof(stack1), &fiber_function1, nullptr, 0, 0);
f2_ctx = modm_context_init((void**)stack2, sizeof(stack2), &fiber_function2, nullptr, 0, 0);

MODM_LOG_DEBUG << "main: Jumping to f1 with sp-addr: " << modm::hex << f1_ctx.sp
<< " and f-addr: " << modm::hex << *(uint16_t*)(f1_ctx.sp + 9) << modm::endl;
MODM_LOG_INFO.flush();
modm::delay(1s);

modm_context_jump(&(m_ctx.sp), f1_ctx.sp);

// Will never get here.
return 0;
}
11 changes: 11 additions & 0 deletions examples/avr/context/project.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<library>
<extends>modm:mega-2560-pro</extends>
<options>
<option name="modm:build:build.path">../../../build/avr/context</option>
<option name="modm:io:with_printf">yes</option>
</options>
<modules>
<module>modm:build:scons</module>
<module>modm:processing:fiber</module>
</modules>
</library>
90 changes: 90 additions & 0 deletions examples/avr/fiber/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/*
* 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 <modm/board.hpp>
#include <modm/debug/logger.hpp>
#include <modm/processing.hpp>

using namespace Board;
using namespace std::chrono_literals;

constexpr uint16_t cycles = 60'000;
volatile uint16_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(void* cyc)
{
// MODM_LOG_INFO << MODM_FILE_INFO << uint16_t(cyc) << modm::endl;
while (++f2counter < uint16_t(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(void* cyc)
{
// MODM_LOG_INFO << MODM_FILE_INFO << uint16_t(cyc) << modm::endl;
while (++f4counter < uint16_t(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, (void*)cycles);
modm::Fiber fiber3(stack3, &Test::fiber_function3, test);
modm::Fiber fiber4(stack4, &Test::fiber_function4, test, (void*)cycles);

// 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;
}
13 changes: 13 additions & 0 deletions examples/avr/fiber/project.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<library>
<extends>modm:mega-2560-pro</extends>
<!-- <extends>modm:arduino-nano</extends> -->
<options>
<option name="modm:build:build.path">../../../build/avr/fiber</option>
<option name="modm:io:with_printf">yes</option>
</options>
<modules>
<module>modm:build:scons</module>
<module>modm:processing:timer</module>
<module>modm:processing:fiber</module>
</modules>
</library>
90 changes: 90 additions & 0 deletions examples/generic/fiber/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/*
* 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 <modm/board.hpp>
#include <modm/debug/logger.hpp>
#include <modm/processing.hpp>

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(void* cyc)
{
MODM_LOG_INFO << MODM_FILE_INFO << modm::endl;
while (++f2counter < uint32_t(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(void* cyc)
{
MODM_LOG_INFO << MODM_FILE_INFO << modm::endl;
while (++f4counter < uint32_t(cyc)) { modm::fiber::yield(); total_counter++; }
}

volatile uint32_t f3counter{0};
volatile uint32_t f4counter{0};
} test;

modm_fastdata modm::fiber::Stack<2048> stack1;
modm_fastdata modm::fiber::Stack<2048> stack2;
modm_fastdata modm::fiber::Stack<2048> stack3;
modm_fastdata modm::fiber::Stack<2048> stack4;
modm_fastdata modm::Fiber fiber1(stack1, &fiber_function1);
modm_fastdata modm::Fiber fiber2(stack2, &fiber_function2, (void*)cycles);
modm_fastdata modm::Fiber fiber3(stack3, &Test::fiber_function3, test);
modm_fastdata modm::Fiber fiber4(stack4, &Test::fiber_function4, test, (void*)cycles);

// 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;
}
12 changes: 12 additions & 0 deletions examples/generic/fiber/project.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<library>
<!-- <extends>modm:nucleo-f429zi</extends> -->
<extends>modm:nucleo-g071rb</extends>
<options>
<option name="modm:build:build.path">../../../build/generic/fiber</option>
</options>
<modules>
<module>modm:build:scons</module>
<module>modm:processing:timer</module>
<module>modm:processing:fiber</module>
</modules>
</library>
49 changes: 49 additions & 0 deletions examples/linux/fiber/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* 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 <modm/debug.hpp>
#include <modm/processing.hpp>

void hello()
{
for(int ii=0; ii<10; ii++)
{
MODM_LOG_INFO << "Hello ";
modm::fiber::yield();
}
}

struct Test
{
void world(void *arg)
{
for(int ii=0; ii<10; ii++)
{
MODM_LOG_INFO << (char*)arg << modm::endl;
modm::fiber::yield();
}
}
} test;

modm::fiber::Stack<1024> stack1;
modm::Fiber fiber1(stack1, &hello);
// You can pass class methods and arguments as well
modm::fiber::Stack<1024> stack2;
modm::Fiber fiber2(stack2, &Test::world, test, (void*)"World");

int
main(void)
{
MODM_LOG_INFO << "Start" << modm::endl;
modm::fiber::scheduler.run();
MODM_LOG_INFO << "End" << modm::endl;
return 0;
}
12 changes: 12 additions & 0 deletions examples/linux/fiber/project.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<library>
<options>
<option name="modm:target">hosted-linux</option>
<option name="modm:build:build.path">../../../build/linux/fiber</option>
</options>
<modules>
<module>modm:debug</module>
<module>modm:platform:core</module>
<module>modm:processing:fiber</module>
<module>modm:build:scons</module>
</modules>
</library>
Loading

0 comments on commit 5b3b722

Please sign in to comment.