Skip to content

Instantly share code, notes, and snippets.

@alphaKAI
Created June 9, 2020 10:33
Show Gist options
  • Save alphaKAI/11aa9b5afccf68642b9a4c2a6005d81a to your computer and use it in GitHub Desktop.
Save alphaKAI/11aa9b5afccf68642b9a4c2a6005d81a to your computer and use it in GitHub Desktop.
context switching using ucontext_t and context family functions
#include <stdio.h>
#include <stdio.h>
#include <stdlib.h>
#include <ucontext.h>
#include <sys/time.h>
#include <stdbool.h>
void *xmalloc(size_t size) {
void *ptr = malloc(size);
if (ptr == NULL) {
fprintf(stderr, "[Fatal Error] Failed to allocate memory\n");
exit(EXIT_FAILURE);
}
return ptr;
}
#define WORKER_STACK_SIZE 8192
#define WORKERS 4
ucontext_t main_ctx;
ucontext_t worker_ctxs[WORKERS];
bool worker_finished[WORKERS];
static void worker(int id) {
printf("worker<id: %d> <1>\n", id);
// back to main ctx
swapcontext(&worker_ctxs[id], &main_ctx);
printf("worker<id: %d> <2>\n", id);
// back to main ctx
swapcontext(&worker_ctxs[id], &main_ctx);
printf("worker<id: %d> <3>\n", id);
// back to main ctx
swapcontext(&worker_ctxs[id], &main_ctx);
worker_finished[id] = true;
}
bool all_worker_finished(void) {
bool ret = true;
for (int id = 0; id < WORKERS; id++) {
ret &= worker_finished[id];
}
return ret;
}
int main(int argc, char const* argv[]) {
for (int id = 0; id < WORKERS; id++) {
worker_finished[id] = false;
if (getcontext(&worker_ctxs[id]) == 1) {
abort();
}
worker_ctxs[id].uc_link = &main_ctx;
worker_ctxs[id].uc_stack.ss_sp = xmalloc(WORKER_STACK_SIZE);
worker_ctxs[id].uc_stack.ss_size = WORKER_STACK_SIZE;
makecontext(&worker_ctxs[id], (void (*)(void))worker, 1, id);
}
int id = 0;
while (!all_worker_finished()) {
swapcontext(&main_ctx, &worker_ctxs[id]);
id++;
id %= WORKERS;
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment