Skip to content

🦘Use setjump and longjump to mock coroutine

Ref: https://tontinton.com/posts/scheduling-internals/

cpp
#include <stdbool.h>
#include <stdio.h>
#include <setjmp.h>

jmp_buf* current_buffer;
jmp_buf main_buffer;

#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof(arr[0]))
#define YIELD() { if (!setjmp(*current_buffer)) longjmp(main_buffer, 1); }

void task_0() {
    while (true) {
        printf("0\n");
        YIELD();
    }
}

void task_1() {
    while (true) {
        printf("1\n");
        YIELD();
    }
}

int main() {
    void(*tasks[])(void) = {task_0, task_1};
    jmp_buf buffers[ARRAY_SIZE(tasks)];
    bool started = false;

    while (true) {
        for (int i = 0; i < ARRAY_SIZE(tasks); i++) {
            if (setjmp(main_buffer)) {
                continue;
            }

            current_buffer = &buffers[i];
            if (!started) {
                tasks[i]();
            } else {
                longjmp(buffers[i], 1);
            }
        }

        started = true;
    }

    return 0;
}

Changelog

Just observe 👀