diff options
Diffstat (limited to 'libcr_ipc/tests/test_chan.c')
-rw-r--r-- | libcr_ipc/tests/test_chan.c | 108 |
1 files changed, 95 insertions, 13 deletions
diff --git a/libcr_ipc/tests/test_chan.c b/libcr_ipc/tests/test_chan.c index 9d6eecf..ee1751f 100644 --- a/libcr_ipc/tests/test_chan.c +++ b/libcr_ipc/tests/test_chan.c @@ -1,6 +1,6 @@ /* libcr_ipc/tests/test_chan.c - Tests for <libcr_ipc/chan.h> * - * Copyright (C) 2024 Luke T. Shumaker <lukeshu@lukeshu.com> + * Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com> * SPDX-License-Identifier: AGPL-3.0-or-later */ @@ -9,41 +9,123 @@ #include "test.h" -CR_CHAN_DECLARE(intchan, int) +CR_CHAN_DECLARE(intchan, int); -COROUTINE cr_producer(void *_ch) { +/* test 1 *********************************************************************/ + +COROUTINE test1_producer_cr(void *_ch) { intchan_t *ch = _ch; cr_begin(); - intchan_send(ch, 1); + cr_chan_send(ch, 1); - while (!intchan_can_send(ch)) + while (!cr_chan_can_send(ch)) cr_yield(); - intchan_send(ch, 2); - + cr_chan_send(ch, 2); cr_end(); } -COROUTINE cr_consumer(void *_ch) { +COROUTINE test1_consumer_cr(void *_ch) { int x; intchan_t *ch = _ch; cr_begin(); - x = intchan_recv(ch); + x = cr_chan_recv(ch); test_assert(x == 1); - x = intchan_recv(ch); + 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() { - intchan_t ch = {0}; - coroutine_add("producer", cr_producer, &ch); - coroutine_add("consumer", cr_consumer, &ch); + 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; } |