/* libcr_ipc/tests/test_chan.c - Tests for * * Copyright (C) 2024-2025 Luke T. Shumaker * SPDX-License-Identifier: AGPL-3.0-or-later */ #include #include #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; }