Skip to content

Commit c1af10d

Browse files
committed
[fiber] Refactor and document
- Fiber compound class with integrated stack. - Fibers can be restarted. - Fiber stack usage measurement. - Correct stack word type on AVRs. - Simpler context API.
1 parent 031731d commit c1af10d

File tree

17 files changed

+1093
-532
lines changed

17 files changed

+1093
-532
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,8 @@ git clone --recurse-submodules --jobs 8 https://github.com/modm-io/modm.git
6161
- UART, I<sup>2</sup>C, SPI, CAN and Ethernet.
6262
- Interfaces and drivers for many external I<sup>2</sup>C and SPI sensors and devices.
6363
- Debug/logging system with IOStream and printf interface.
64-
- Lightweight, stackless threads and resumable functions using cooperative multitasking.
64+
- Cooperative, stackless protothreads and resumable functions.
65+
- Cooperative, stackful fibers and scheduler.
6566
- Functional (partial) libstdc++ implementation for AVRs.
6667
- Useful filter, interpolation and geometric algorithms.
6768
- Lightweight unit testing system (suitable for AVRs).

src/modm/platform/core/rp/multicore.md

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -39,16 +39,3 @@ extern "C" void modm_initialize_core1()
3939
SCB->VTOR = custom_vector_table;
4040
}
4141
```
42-
43-
When using the `modm:processing:fiber` module you can now schedule fibers on
44-
both cores, each with their own scheduler:
45-
46-
```cpp
47-
modm_core0_noinit modm::fiber::Stack<256> stack0;
48-
modm_core0_data modm::Fiber fiber0(stack0, []() { function(); }, /* core= */0);
49-
50-
modm_core1_noinit modm::fiber::Stack<256> stack1;
51-
modm_core1_data modm::Fiber fiber1(stack1, []() { function(); }, /* core= */1);
52-
```
53-
54-

src/modm/processing/fiber.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,4 @@
1111

1212
#include "fiber/fiber.hpp"
1313
#include "fiber/scheduler.hpp"
14+
#include "fiber/functions.hpp"

src/modm/processing/fiber/context.h

Lines changed: 0 additions & 51 deletions
This file was deleted.
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
/*
2+
* Copyright (c) 2020, Erik Henriksson
3+
* Copyright (c) 2021, 2023, Niklas Hauser
4+
*
5+
* This file is part of the modm project.
6+
*
7+
* This Source Code Form is subject to the terms of the Mozilla Public
8+
* License, v. 2.0. If a copy of the MPL was not distributed with this
9+
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
10+
*/
11+
// ----------------------------------------------------------------------------
12+
13+
#pragma once
14+
15+
#include <stdint.h>
16+
#include <stddef.h>
17+
#include <stdbool.h>
18+
#include <modm/architecture/utils.hpp>
19+
20+
#ifdef __cplusplus
21+
extern "C"
22+
{
23+
#endif
24+
25+
/**
26+
* @ingroup modm_processing_fiber
27+
* @defgroup modm_processing_fiber_context Fiber Context Functions
28+
*
29+
* These functions implement the underlying architecture specific operations to
30+
* initialize, start, yield, and end fibers. These can be used to implement an
31+
* alternative scheduling strategy or use fibers outside of modm.
32+
* @{
33+
*/
34+
35+
/// The fiber context stores information about the stack.
36+
struct modm_context_t
37+
{
38+
uintptr_t *sp; ///< Stored stack pointer, only valid when *not* running!
39+
uintptr_t *bottom; ///< Bottom of stack
40+
uintptr_t *top; ///< Top of stack, one word beyond stack!
41+
};
42+
43+
/**
44+
* Initializes the context with the function pointer and argument stored at the
45+
* top. The `ctx->sp` is set to two `uintptr_t` below the top.
46+
* Must be called only once to initialize the stack.
47+
*
48+
* @param fn function pointer to a `void(*)(uintptr_t)` function.
49+
*/
50+
void
51+
modm_context_init(modm_context_t *ctx,
52+
uintptr_t *bottom, uintptr_t *top,
53+
uintptr_t fn, uintptr_t arg);
54+
55+
/**
56+
* Resets the context stack pointer to the correct offset in preparation for
57+
* jumping into the fiber. Must be called after initialization, but every time
58+
* the function is started from the beginning.
59+
*/
60+
void
61+
modm_context_reset(modm_context_t *ctx);
62+
63+
/**
64+
* Switches control from the main context to the fiber context. This initializes
65+
* the hardware and then jumps from the caller context into the `to` fiber.
66+
*/
67+
void
68+
modm_context_start(modm_context_t *to);
69+
70+
/**
71+
* Pushes the context onto the `from->sp` and pops the context from the `to->sp`
72+
* to jump from one fiber to the next.
73+
*/
74+
void
75+
modm_context_jump(modm_context_t *from, modm_context_t *to);
76+
77+
/**
78+
* Switches control from the fiber context back to the main context.
79+
* Control flow then continues in the main context by returning from the
80+
* `modm_context_start()` function.
81+
*/
82+
void modm_noreturn
83+
modm_context_end();
84+
85+
/**
86+
* Zeros the register file and watermarks the rest of the stack.
87+
* You may call this function before or after `modm_context_reset()`, however,
88+
* *NOT* while the fiber is running!
89+
*/
90+
void
91+
modm_context_watermark(modm_context_t *ctx);
92+
93+
/**
94+
* Returns the stack usage by searching from the bottom of the stack for the
95+
* watermark level. You may call this function at any point after calling
96+
* `modm_context_watermark()`.
97+
*/
98+
size_t
99+
modm_context_stack_usage(const modm_context_t *ctx);
100+
101+
/// A cheap way to check if the last word of the stack was written.
102+
bool
103+
modm_context_stack_overflow(const modm_context_t *ctx);
104+
/// @}
105+
106+
#ifdef __cplusplus
107+
}
108+
#endif

0 commit comments

Comments
 (0)