+++ 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 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