55 lines
1.2 KiB
C
55 lines
1.2 KiB
C
#include <fiber/fiber.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
typedef struct
|
|
{
|
|
Fiber *caller;
|
|
Fiber *self;
|
|
const char *str;
|
|
} Args;
|
|
|
|
/* invoked if coroutine is called after it finished */
|
|
void
|
|
guard(Fiber *self, void *null)
|
|
{
|
|
(void) self;
|
|
(void) null;
|
|
abort();
|
|
}
|
|
|
|
/* entry point */
|
|
void
|
|
coroutine(void *args0)
|
|
{
|
|
Args *args = (Args *) args0;
|
|
printf("From coroutine: %s\n", args->str);
|
|
fiber_switch(args->self, args->caller);
|
|
}
|
|
|
|
int
|
|
main()
|
|
{
|
|
Fiber main_fiber;
|
|
fiber_init_toplevel(&main_fiber);
|
|
Fiber crt;
|
|
/* allocate a stack of 16kb, additionally add an unmapped page to detect
|
|
* overflows */
|
|
(void) fiber_alloc(&crt, 1024 * 16, guard, NULL, FIBER_FLAG_GUARD_LO);
|
|
Args args;
|
|
args.caller = &main_fiber;
|
|
args.self = &crt;
|
|
args.str = "Hello";
|
|
/* push a new return stack frame, defines the entry point of our coroutine
|
|
*/
|
|
fiber_push_return(&crt, coroutine, &args, sizeof args);
|
|
/* arguments are copied into the coroutine, its safe to destroy them here */
|
|
memset(&args, 0, sizeof args);
|
|
/* run our coroutine */
|
|
fiber_switch(&main_fiber, &crt);
|
|
fiber_destroy(&crt);
|
|
/* main_fiber does not have to be destroyed */
|
|
return 0;
|
|
}
|