/* 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 */ /* HAVE_* */ #include "config.h" /* printf, perror */ #include /* EXIT_SUCCESS, EXIT_FAILURE */ #include /* allocator_t, allocator_destroy */ #include /* default_allocator_get */ #include #ifdef HAVE_MMAP /* mmap_allocator_get */ # include #endif /* ... */ #include 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 deferred_puts(void *data) { puts(data); } static void *output_coroutine(coroutine_t *coro, void *data) { size_t *value = data; if (coroutine_defer(coro, deferred_puts, "deferred output 0")) { return NULL; } if (coroutine_defer(coro, deferred_puts, "deferred output 1")) { return NULL; } 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; (void) argc; (void) argv; printf("default allocator:\n"); allocator = default_allocator_get(); error = run(allocator); allocator_destroy(allocator); #ifdef HAVE_MMAP if (!error) { printf("mmap allocator:\n"); allocator = mmap_allocator_get(); error = run(allocator); allocator_destroy(allocator); } #endif return !error ? EXIT_SUCCESS : EXIT_FAILURE; }