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 28, 2021
1 parent 47a97dc commit a8e5c18
Show file tree
Hide file tree
Showing 39 changed files with 1,460 additions and 41 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
4 changes: 4 additions & 0 deletions .github/workflows/macos.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,18 +53,22 @@ jobs:
git submodule update --init --jobs 8
- name: Hosted Unittests
if: always()
run: |
(cd test && make run-hosted-darwin)
- name: Hosted Examples
if: always()
run: |
(cd examples && ../tools/scripts/examples_compile.py linux)
- name: Compile STM32 Examples
if: always()
run: |
(cd examples && ../tools/scripts/examples_compile.py nucleo_f031k6 nucleo_f103rb nucleo_f303re nucleo_f411re nucleo_f746zg)
(cd examples && ../tools/scripts/examples_compile.py nucleo_g071rb nucleo_l031k6 nucleo_l152re nucleo_l476rg nucleo_g474re)
- name: Compile AVR Examples
if: always()
run: |
(cd examples && ../tools/scripts/examples_compile.py avr)
3 changes: 2 additions & 1 deletion .github/workflows/windows_hosted.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,10 @@ 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()
shell: bash
run: |
(cd test && make run-hosted-windows)
89 changes: 89 additions & 0 deletions examples/avr/fiber/main.cpp
Original file line number Diff line number Diff line change
@@ -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 <modm/board.hpp>
#include <modm/debug/logger.hpp>
#include <modm/processing.hpp>

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;
}
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:__fibers">yes</option>
</options>
<modules>
<module>modm:build:scons</module>
<module>modm:processing:timer</module>
<module>modm:processing:fiber</module>
</modules>
</library>
89 changes: 89 additions & 0 deletions examples/generic/fiber/main.cpp
Original file line number Diff line number Diff line change
@@ -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 <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(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<2048> stack1;
modm::fiber::Stack<2048> stack2;
modm::fiber::Stack<2048> stack3;
modm::fiber::Stack<2048> 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(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;
}
13 changes: 13 additions & 0 deletions examples/generic/fiber/project.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<library>
<!-- <extends>modm:nucleo-f429zi</extends> -->
<extends>modm:nucleo-g071rb</extends>
<options>
<option name="modm:build:build.path">../../../build/generic/fiber</option>
<option name="modm:__fibers">yes</option>
</options>
<modules>
<module>modm:build:scons</module>
<module>modm:processing:timer</module>
<module>modm:processing:fiber</module>
</modules>
</library>
51 changes: 51 additions & 0 deletions examples/linux/fiber/main.cpp
Original file line number Diff line number Diff line change
@@ -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 <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(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;
}
14 changes: 14 additions & 0 deletions examples/linux/fiber/project.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<library>
<!-- CI: run -->
<options>
<option name="modm:target">hosted-linux</option>
<option name="modm:build:build.path">../../../build/linux/fiber</option>
<option name="modm:__fibers">yes</option>
</options>
<modules>
<module>modm:debug</module>
<module>modm:platform:core</module>
<module>modm:processing:fiber</module>
<module>modm:build:scons</module>
</modules>
</library>
1 change: 1 addition & 0 deletions examples/stm32f469_discovery/game_of_life/project.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
<extends>modm:disco-f469ni</extends>
<options>
<option name="modm:build:build.path">../../../build/stm32f469_discovery/game_of_life</option>
<option name="modm:platform:cortex-m:vector_table_location">ram</option>
</options>
<modules>
<module>modm:architecture:memory</module>
Expand Down
4 changes: 4 additions & 0 deletions repo.lb
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,10 @@ def init(repo):
description=descr_target,
enumeration=devices))

# Invisible option guarding the Fiber API until it is ready
repo.add_option(BooleanOption(name="__fibers", default=False,
description="Enable unstable fiber API."))

def prepare(repo, options):
repo.add_modules_recursive("ext", modulefile="*.lb")
repo.add_modules_recursive("src", modulefile="*.lb")
Expand Down
8 changes: 8 additions & 0 deletions src/modm/architecture/utils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,11 @@
/// @note This memory location may not be DMA-able!
#define modm_fastdata

/// Places an array into the fastest accessible memory *with* DMA access:
/// data cache, core coupled memory or SRAM as fallback.
/// @note This memory location is DMA-able, but uninitialized!
#define modm_faststack

/// This branch is more likely to execute.
#define modm_likely(x) (x)

Expand Down Expand Up @@ -129,6 +134,7 @@
#define modm_fallthrough __attribute__((fallthrough))
#define modm_noreturn __attribute__((noreturn))
#define modm_warn_unused_result __attribute__((warn_unused_result))
#define modm_naked __attribute__((naked))

#ifdef MODM_COMPILER_MINGW
// FIXME: Windows Object Format PE does not support weak symbols
Expand All @@ -144,10 +150,12 @@
# define modm_fastcode
# define modm_ramcode
# define modm_fastdata
# define modm_faststack
#else
# define modm_fastcode modm_section(".fastcode")
# define modm_ramcode modm_fastcode
# define modm_fastdata modm_section(".fastdata")
# define modm_faststack modm_section(".faststack")
#endif

#ifdef __cplusplus
Expand Down
2 changes: 1 addition & 1 deletion src/modm/platform/core/cortex/ram.ld.in
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ SECTIONS

{{ linker.section_ram(cont_ram_regions[0].cont_name|upper, "FLASH", table_copy, table_zero,
sections_data=["fastdata", "fastcode", "data_" + cont_ram_regions[0].contains[0].name],
sections_bss=["bss_" + cont_ram_regions[0].contains[0].name]) }}
sections_bss=["faststack", "bss_" + cont_ram_regions[0].contains[0].name]) }}

{{ linker.all_heap_sections(table_copy, table_zero, table_heap) }}

Expand Down
1 change: 0 additions & 1 deletion src/modm/platform/core/cortex/vectors.c.in
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ typedef void (* const FunctionPointer)(void);

// defined in the linkerscript
extern uint32_t __main_stack_top[];
extern uint32_t __process_stack_top[];

// Define the vector table
modm_section(".vector_rom")
Expand Down
2 changes: 1 addition & 1 deletion src/modm/platform/core/stm32/dccm.ld.in
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ SECTIONS

{{ linker.section_ram(cont_ram_regions[0].cont_name|upper, "FLASH", table_copy, table_zero,
sections_data=["fastcode", "data_" + cont_ram_regions[0].contains[0].name],
sections_bss=["bss_" + cont_ram_regions[0].contains[0].name]) }}
sections_bss=["faststack", "bss_" + cont_ram_regions[0].contains[0].name]) }}

{{ linker.all_heap_sections(table_copy, table_zero, table_heap) }}

Expand Down
Loading

0 comments on commit a8e5c18

Please sign in to comment.