A
Andrey Popp
Hello, I started to experimenting with ucontext to implement basic cooperative multithreading and stuccoed with this piece of code:
#include <stdlib.h>
#include <stdio.h>
#include <ucontext.h>
static ucontext_t routine_main;
static ucontext_t routine1;
static ucontext_t routine2;
void runner(int n) {
fprintf(stderr, "runner %d\n", n);
while(1) {
fprintf(stderr, "runner %d\n", n);
if (n == 1)
swapcontext(&routine1, &routine2);
else
swapcontext(&routine2, &routine1);
}
}
int main(int argc, char **argv) {
char st1c[8192];
char st2c[8192];
if (getcontext(&routine1) == -1)
abort();
routine1.uc_link = &routine_main;
routine1.uc_stack.ss_sp = st1c;
routine1.uc_stack.ss_size = sizeof st1c;
makecontext(&routine1, (void(*)(void))runner, 1, 1);
if (getcontext(&routine2) == -1)
abort();
routine2.uc_link = &routine_main;
routine2.uc_stack.ss_sp = st2c;
routine2.uc_stack.ss_size = sizeof st2c;
makecontext(&routine1, (void(*)(void))runner, 1, 2);
fprintf(stderr, "start executing\n");
if (swapcontext(&routine_main, &routine1) == -1)
abort();
fprintf(stderr, "exiting\n");
return 0;
}
which doesn't work the way it should — it just constantly prints "start executing", which means it doesn't change execution context from routeine_main to routine1 but instead from routine_main to routine_main.
#include <stdlib.h>
#include <stdio.h>
#include <ucontext.h>
static ucontext_t routine_main;
static ucontext_t routine1;
static ucontext_t routine2;
void runner(int n) {
fprintf(stderr, "runner %d\n", n);
while(1) {
fprintf(stderr, "runner %d\n", n);
if (n == 1)
swapcontext(&routine1, &routine2);
else
swapcontext(&routine2, &routine1);
}
}
int main(int argc, char **argv) {
char st1c[8192];
char st2c[8192];
if (getcontext(&routine1) == -1)
abort();
routine1.uc_link = &routine_main;
routine1.uc_stack.ss_sp = st1c;
routine1.uc_stack.ss_size = sizeof st1c;
makecontext(&routine1, (void(*)(void))runner, 1, 1);
if (getcontext(&routine2) == -1)
abort();
routine2.uc_link = &routine_main;
routine2.uc_stack.ss_sp = st2c;
routine2.uc_stack.ss_size = sizeof st2c;
makecontext(&routine1, (void(*)(void))runner, 1, 2);
fprintf(stderr, "start executing\n");
if (swapcontext(&routine_main, &routine1) == -1)
abort();
fprintf(stderr, "exiting\n");
return 0;
}
which doesn't work the way it should — it just constantly prints "start executing", which means it doesn't change execution context from routeine_main to routine1 but instead from routine_main to routine_main.