blob: 95003005ec978f28ee00777ac23bf16446d0e8ad (
plain) (
tree)
|
|
+++
title = "xpost: Cooperative-multitasking studies (matcha-threads)"
[taxonomies]
tags = ["threading", "linux", "x86", "arm", "riscv"]
+++
This is a cross post to a **cooperative-multitasking implementation** that I
did in the past and hosted on github [>> matcha-threads <<][matcha].
Cooperative-multitasking allows to perform the thread scheduling in user space.
Executing threads need to give the control back to the `scheduler` such that
other threads can run. Since control is returned explicitly to the scheduler,
threads need to **"cooperate"**.
The following code snippet shows an example of two such threads:
```cpp
#include "lib/executor.h"
#include "lib/thread.h"
#include <cstdio>
void like_tea(nMatcha::Yielder& y) {
std::puts("like");
y.yield();
std::puts("tea");
}
int main() {
nMatcha::Executor e;
e.spawn(nMatcha::FnThread::make(like_tea));
e.spawn(nMatcha::FnThread::make([](nMatcha::Yielder& y) {
std::puts("I");
y.yield();
std::puts("green");
}));
e.run();
return 0;
}
```
Which gives the following output when being run:
```txt
I
like
green
tea
```
The main focus of that project was to understand the fundamental mechanism
underlying cooperative-multitasking and implement such a `yield()` function as
shown in the example above.
Looking at the final implementation, the yield function does the following:
```txt
yield:
1. function prologue
2. push callee-saved regs to current stack
3. swap stack pointers (current - new)
4. pop callee-saved regs from new stack
5. function epilogue & return
```
Implementations for different ISAs are available here:
- [x86_64][yield-x86]
- [arm64][yield-arm64]
- [armv7a][yield-arm]
- [riscv64][yield-rv64]
[matcha]: https://github.com/johannst/matcha-threads
[yield-x86]: https://github.com/johannst/matcha-threads/blob/master/lib/arch/x86_64/yield.s
[yield-arm]: https://github.com/johannst/matcha-threads/blob/master/lib/arch/arm/yield.s
[yield-arm64]: https://github.com/johannst/matcha-threads/blob/master/lib/arch/arm64/yield.s
[yield-rv64]: https://github.com/johannst/matcha-threads/blob/master/lib/arch/riscv64/yield.s
|