summaryrefslogtreecommitdiff
path: root/libcr_ipc
diff options
context:
space:
mode:
Diffstat (limited to 'libcr_ipc')
-rw-r--r--libcr_ipc/include/libcr_ipc/_linkedlist.h2
-rw-r--r--libcr_ipc/include/libcr_ipc/select.h67
2 files changed, 12 insertions, 57 deletions
diff --git a/libcr_ipc/include/libcr_ipc/_linkedlist.h b/libcr_ipc/include/libcr_ipc/_linkedlist.h
index 43b7286..e5aa52a 100644
--- a/libcr_ipc/include/libcr_ipc/_linkedlist.h
+++ b/libcr_ipc/include/libcr_ipc/_linkedlist.h
@@ -7,7 +7,7 @@
#ifndef _LIBCR_IPC__LINKEDLIST_H_
#define _LIBCR_IPC__LINKEDLIST_H_
-#include <assert.h>
+#include <libmisc/assert.h>
/* singly linked list *********************************************************/
diff --git a/libcr_ipc/include/libcr_ipc/select.h b/libcr_ipc/include/libcr_ipc/select.h
index f094662..788bf53 100644
--- a/libcr_ipc/include/libcr_ipc/select.h
+++ b/libcr_ipc/include/libcr_ipc/select.h
@@ -5,10 +5,10 @@
*/
#include <alloca.h> /* for alloca() */
-#include <assert.h> /* for assert() */
-#include <stdarg.h> /* for va_* */
#include <stddef.h> /* for size_t */
-#include <stdlib.h> /* for random() */
+
+#include <libmisc/assert.h>
+#include <libmisc/rand.h>
#include <libcr_ipc/chan.h>
@@ -23,7 +23,6 @@
*/
struct cr_select_arg {
enum {
- _CR_SELECT_OP_NONE,
_CR_SELECT_OP_RECV,
_CR_SELECT_OP_SEND,
_CR_SELECT_OP_DEFAULT,
@@ -61,22 +60,9 @@ struct cr_select_arg {
((struct cr_select_arg){ \
.op = _CR_SELECT_OP_DEFAULT, \
})
-#define _CR_SELECT_END \
- ((struct cr_select_arg){ \
- .op = _CR_SELECT_OP_NONE, \
- })
/* cr_select_v(arg_cnt, arg_vec) **********************************************/
-static inline size_t _cr_select_pickone(size_t cnt) {
- long fair_cnt = (0x80000000L / cnt) * cnt;
- long rnd;
- do {
- rnd = random();
- } while (rnd >= fair_cnt);
- return rnd % cnt;
-}
-
enum _cr_select_class {
_CR_SELECT_CLASS_DEFAULT,
_CR_SELECT_CLASS_BLOCKING,
@@ -98,7 +84,7 @@ static inline enum _cr_select_class _cr_select_getclass(struct cr_select_arg arg
case _CR_SELECT_OP_DEFAULT:
return _CR_SELECT_CLASS_DEFAULT;
default:
- __builtin_unreachable();
+ assert_notreached("invalid arg.op");
}
}
@@ -139,7 +125,7 @@ static size_t cr_select_v(size_t arg_cnt, struct cr_select_arg arg_vec[]) {
}
if (cnt_nonblock) {
- size_t choice = _cr_select_pickone(cnt_nonblock);
+ size_t choice = rand_uint63n(cnt_nonblock);
for (size_t i = 0, seen = 0; i < arg_cnt; i++) {
if (_cr_select_getclass(arg_vec[i]) == _CR_SELECT_CLASS_NONBLOCK) {
if (seen == choice) {
@@ -154,14 +140,14 @@ static size_t cr_select_v(size_t arg_cnt, struct cr_select_arg arg_vec[]) {
seen++;
}
}
- __builtin_unreachable();
+ assert_notreached("should have returned from inside for() loop");
}
if (cnt_default) {
for (size_t i = 0; i < arg_cnt; i++)
if (_cr_select_getclass(arg_vec[i]) == _CR_SELECT_CLASS_DEFAULT)
return i;
- __builtin_unreachable();
+ assert_notreached("should have returned from inside for() loop");
}
struct _cr_select_waiters waiters = {
@@ -185,40 +171,9 @@ static size_t cr_select_v(size_t arg_cnt, struct cr_select_arg arg_vec[]) {
/* cr_select_l(arg1, arg2, arg3, ...) ******************************************/
-#define cr_select_l(...) _cr_selectl(__VA_ARGS__ __VA_OPT__(,) _CR_SELECT_END)
-static inline size_t _cr_select_l(struct cr_select_arg first_arg, ...) {
- va_list list;
-
- /* Pass 1: Count how many args we have. */
- size_t arg_cnt = 0;
- va_start(list, first_arg);
- for (;;) {
- struct cr_select_arg arg;
- if (arg_cnt == 0)
- arg = first_arg;
- else
- arg = va_arg(list, struct cr_select_arg);
- if (arg.op == _CR_SELECT_OP_NONE)
- break;
- arg_cnt++;
- }
- va_end(list);
-
- /* Pass 2: Copy the args to a simple vector on the stack. */
- struct cr_select_arg *arg_vec = alloca(sizeof(struct cr_select_arg) * arg_cnt);
- va_start(list, first_arg);
- for (size_t i = 0; i < arg_cnt; i++) {
- struct cr_select_arg arg;
- if (i == 0)
- arg = first_arg;
- else
- arg = va_arg(list, struct cr_select_arg);
- arg_vec[i] = arg;
- }
- va_end(list);
-
- /* Now pass that to cr_select_v() for the real work. */
- return cr_select_v(arg_cnt, arg_vec);
-}
+#define cr_select_l(...) ({ \
+ struct cr_select_arg _cr_select_args[] = { __VA_ARGS__ }; \
+ cr_select_v(sizeof(_cr_select_args)/sizeof(_cr_select_args[0])); \
+})
#endif /* _LIBCR_IPC_SELECT_H_ */