threadless.io/test/coroutine.c

139 lines
2.8 KiB
C
Raw Normal View History

/* threadless.io
* Copyright (c) 2016 Justin R. Cutler
* Licensed under the MIT License. See LICENSE file in the project root for
* full license information.
*/
2016-04-02 20:37:31 +00:00
/** @file
* coroutine interface test
* @author Justin R. Cutler <justin.r.cutler@gmail.com>
*/
2016-04-04 02:54:57 +00:00
/* HAVE_* */
#include "config.h"
/* printf, perror */
#include <stdio.h>
/* EXIT_SUCCESS, EXIT_FAILURE */
#include <stdlib.h>
/* allocator_t, allocator_destroy */
#include <threadless/allocation.h>
/* default_allocator_get */
#include <threadless/default_allocator.h>
2016-04-04 02:54:57 +00:00
#ifdef HAVE_MMAP
/* mmap_allocator_get */
2016-04-04 02:54:57 +00:00
# include <threadless/mmap_allocator.h>
#endif
/* ... */
#include <threadless/coroutine.h>
2016-04-02 20:35:45 +00:00
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;
}
2016-04-11 01:45:20 +00:00
static void deferred_puts(void *data)
{
puts(data);
}
2016-04-02 20:35:45 +00:00
static void *output_coroutine(coroutine_t *coro, void *data)
{
size_t *value = data;
2016-04-11 01:45:20 +00:00
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;
2016-04-02 20:35:45 +00:00
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))) {
2016-04-01 13:12:14 +00:00
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;
2016-04-04 02:54:57 +00:00
allocator_t *allocator;
(void) argc;
(void) argv;
2016-04-04 02:54:57 +00:00
printf("default allocator:\n");
allocator = default_allocator_get();
error = run(allocator);
allocator_destroy(allocator);
2016-04-04 02:54:57 +00:00
#ifdef HAVE_MMAP
if (!error) {
printf("mmap allocator:\n");
allocator = mmap_allocator_get();
2016-04-04 02:54:57 +00:00
error = run(allocator);
allocator_destroy(allocator);
}
#endif
return !error ? EXIT_SUCCESS : EXIT_FAILURE;
}