Skip to content

Instantly share code, notes, and snippets.

@aprell
Created March 1, 2012 17:39
Show Gist options
  • Save aprell/1951598 to your computer and use it in GitHub Desktop.
Save aprell/1951598 to your computer and use it in GitHub Desktop.
Switching between coroutines/tasks: GNU Pth (separate stacks)
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <assert.h>
#include <unistd.h>
#include <time.h>
#include <pth.h>
#include "list.h"
struct task {
pth_t tid;
struct list_head list;
};
static LIST_HEAD(tasklist);
static void (*tasks[2])(void *);
static int ntasks;
static void task_create(struct list_head *tasklist, void *(*fn)(void *), void *args)
{
struct task *t = malloc(sizeof(*t));
list_add(&t->list, tasklist);
t->tid = pth_spawn(PTH_ATTR_DEFAULT, fn, args);
pth_yield(t->tid);
}
static void task_join(struct list_head *tasklist)
{
while (!list_empty(tasklist)) {
struct task *t = list_first_entry(tasklist, struct task, list);
list_del(&t->list);
pth_join(t->tid, NULL);
free(t);
}
}
void schedule(void)
{
int i;
srand(time(NULL));
for (i = 0; i < ntasks; i++) {
int n = rand() % 5;
task_create(&tasklist, (void *(*)(void *))tasks[i], &n);
}
task_join(&tasklist);
}
// A task yields control n times
void task0(void *arg)
{
int n = *(int *)arg, i;
printf("Task 0: n = %d\n", n);
for (i = 0; i < n; i++) {
// Assume we block and yield control
pth_yield(NULL);
printf("Task 0: resume\n");
}
printf("Task 0: complete\n");
}
void task1(void *arg)
{
int n = *(int *)arg, i;
printf("Task 1: n = %d\n", n);
for (i = 0; i < n; i++) {
// Assume we block and yield control
pth_yield(NULL);
printf("Task 1: resume\n");
}
printf("Task 1: complete\n");
}
int main(void)
{
pth_init();
tasks[0] = task0;
tasks[1] = task1;
ntasks = 2;
schedule();
pth_kill();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment