/* libcr_ipc/tests/test_select.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); intchan_t ch[10] = {0}; intchan_t fch = {0}; COROUTINE cr_consumer(void *) { cr_begin(); struct cr_select_arg args[11]; bool chdone[10] = {0}; 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(&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(&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(&fch, &send); args[1] = CR_SELECT_DEFAULT; ret_arg = cr_select_v(2, args); test_assert(ret_arg == 0); send = 890; args[0] = CR_SELECT_SEND(&fch, &send); args[1] = CR_SELECT_DEFAULT; ret_arg = cr_select_v(2, args); test_assert(ret_arg == 1); cr_end(); } COROUTINE cr_producer(void *_n) { int n = *(int *)_n; cr_begin(); intchan_send(&ch[n], n); cr_end(); } COROUTINE cr_final(void *) { cr_begin(); int ret = intchan_recv(&fch); printf("ret=%d\n", ret); test_assert(ret == 567); cr_end(); } int main() { for (int i = 0; i < 10; i++) coroutine_add("producer", cr_producer, &i); coroutine_add("consumer", cr_consumer, NULL); coroutine_add("final", cr_final, NULL); coroutine_main(); return 0; }