diff options
Diffstat (limited to 'libcr_ipc/tests/test_chan.c')
-rw-r--r-- | libcr_ipc/tests/test_chan.c | 131 |
1 files changed, 131 insertions, 0 deletions
diff --git a/libcr_ipc/tests/test_chan.c b/libcr_ipc/tests/test_chan.c new file mode 100644 index 0000000..ee1751f --- /dev/null +++ b/libcr_ipc/tests/test_chan.c @@ -0,0 +1,131 @@ +/* libcr_ipc/tests/test_chan.c - Tests for <libcr_ipc/chan.h> + * + * Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com> + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +#include <libcr/coroutine.h> +#include <libcr_ipc/chan.h> + +#include "test.h" + +CR_CHAN_DECLARE(intchan, int); + +/* test 1 *********************************************************************/ + +COROUTINE test1_producer_cr(void *_ch) { + intchan_t *ch = _ch; + cr_begin(); + + cr_chan_send(ch, 1); + + while (!cr_chan_can_send(ch)) + cr_yield(); + + cr_chan_send(ch, 2); + + cr_end(); +} + +COROUTINE test1_consumer_cr(void *_ch) { + int x; + intchan_t *ch = _ch; + cr_begin(); + + x = cr_chan_recv(ch); + test_assert(x == 1); + + x = cr_chan_recv(ch); + test_assert(x == 2); + + cr_end(); +} + +/* test 2 *********************************************************************/ + +intchan_t test2_ch[10] = {}; +intchan_t test2_fch = {}; + +COROUTINE test2_consumer_cr(void *) { + cr_begin(); + + struct cr_select_arg args[11]; + + bool chdone[10] = {}; + int arg2ch[10]; + for (;;) { + int ret_ch; + int i_arg = 0; + for (int i_ch = 0; i_ch < 10; i_ch++) { + if (!chdone[i_ch]) { + args[i_arg] = CR_SELECT_RECV(&test2_ch[i_ch], &ret_ch); + arg2ch[i_arg] = i_ch; + i_arg++; + } + } + if (!i_arg) + break; + args[i_arg] = CR_SELECT_DEFAULT; /* check that default doesn't trigger */ + test_assert(i_arg <= 10); + int ret_arg = cr_select_v(i_arg+1, args); + test_assert(ret_arg < i_arg); + test_assert(arg2ch[ret_arg] == ret_ch); + chdone[ret_ch] = true; + } + int ret_ch, ret_arg; + args[0] = CR_SELECT_RECV(&test2_ch[0], &ret_ch); + args[1] = CR_SELECT_DEFAULT; + ret_arg = cr_select_v(2, args); + test_assert(ret_arg == 1); + + int send = 567; + args[0] = CR_SELECT_SEND(&test2_fch, &send); + args[1] = CR_SELECT_DEFAULT; + ret_arg = cr_select_v(2, args); + test_assert(ret_arg == 0); + + send = 890; + ret_arg = cr_select_l(CR_SELECT_SEND(&test2_fch, &send), + CR_SELECT_DEFAULT); + test_assert(ret_arg == 1); + + cr_end(); +} + +COROUTINE test2_producer_cr(void *_n) { + int n = *(int *)_n; + cr_begin(); + + cr_chan_send(&test2_ch[n], n); + + cr_end(); +} + +COROUTINE test2_final_cr(void *) { + cr_begin(); + + int ret = cr_chan_recv(&test2_fch); + printf("ret=%d\n", ret); + test_assert(ret == 567); + + cr_end(); +} + +/******************************************************************************/ + +int main() { + printf("== test 1 =========================================\n"); + intchan_t ch = {}; + coroutine_add("producer", test1_producer_cr, &ch); + coroutine_add("consumer", test1_consumer_cr, &ch); + coroutine_main(); + + printf("== test 2 =========================================\n"); + for (int i = 0; i < 10; i++) + coroutine_add("producer", test2_producer_cr, &i); + coroutine_add("consumer", test2_consumer_cr, NULL); + coroutine_add("final", test2_final_cr, NULL); + coroutine_main(); + + return 0; +} |