threadless.io/test/coroutine.c

107 lines
2.2 KiB
C

/* threadless.io
* Copyright (c) 2016 Justin R. Cutler
* Licensed under the MIT License. See LICENSE file in the project root for
* full license information.
*/
/** @file
* coroutine interface test
* @author Justin R. Cutler <justin.r.cutler@gmail.com>
*/
/* printf, perror */
#include <stdio.h>
/* EXIT_SUCCESS, EXIT_FAILURE */
#include <stdlib.h>
/* allocator_t, allocator_get_default, allocator_destroy */
#include <threadless/default_allocator.h>
/* ... */
#include <threadless/coroutine.h>
static void *fibonacci_generator(coroutine_t *coro, void *data)
{
size_t x = 0;
size_t y = 1;
/* ignore initial input data */
(void) data;
/* generate Fibonacci sequence until overflow */
while (x <= y) {
size_t tmp = x;
/* yield next value, ignore new input data */
(void) coroutine_yield(coro, &tmp);
/* x, y = y, x + y */
tmp = y;
y += x;
x = tmp;
}
/* no more values */
return NULL;
}
static void *output_coroutine(coroutine_t *coro, void *data)
{
size_t *value = data;
while (NULL != value) {
printf("%zu\n", *value);
value = coroutine_yield(coro, value);
}
return NULL;
}
static int run(allocator_t *allocator)
{
int error = -1;
coroutine_t *fibonacci = NULL;
coroutine_t *output = NULL;
fibonacci = coroutine_create(allocator, fibonacci_generator, 4096);
if (NULL == fibonacci) {
perror("coroutine_create");
goto fail;
}
output = coroutine_create(allocator, output_coroutine, 4096);
if (NULL == output) {
perror("coroutine_create");
goto fail;
}
while (!(coroutine_ended(fibonacci) || coroutine_ended(output))) {
void *data;
data = coroutine_resume(fibonacci, NULL);
data = coroutine_resume(output, data);
}
error = 0;
fail:
coroutine_destroy(output);
coroutine_destroy(fibonacci);
return error;
}
int main(int argc, char *argv[])
{
int error;
allocator_t *allocator = allocator_get_default();
(void) argc;
(void) argv;
error = run(allocator);
allocator_destroy(allocator);
return !error ? EXIT_SUCCESS : EXIT_FAILURE;
}