diff options
author | Luke T. Shumaker <lukeshu@lukeshu.com> | 2025-04-07 00:09:00 -0600 |
---|---|---|
committer | Luke T. Shumaker <lukeshu@lukeshu.com> | 2025-04-07 01:55:23 -0600 |
commit | 4d5a8b2f99be5e04954c5067080d1725af8c0ae7 (patch) | |
tree | 2b1d87719555eeb2159e7e79dcac5605dbb45c74 /libcr_ipc/mutex.c | |
parent | 599c887d12d406296f356a02b1088f04ffe1f26e (diff) |
libcr_ipc: Pull as much as possible from public .h to .c files
Diffstat (limited to 'libcr_ipc/mutex.c')
-rw-r--r-- | libcr_ipc/mutex.c | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/libcr_ipc/mutex.c b/libcr_ipc/mutex.c new file mode 100644 index 0000000..28debba --- /dev/null +++ b/libcr_ipc/mutex.c @@ -0,0 +1,45 @@ +/* libcr_ipc/mutex.c - Simple mutexes for libcr + * + * Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com> + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +#include <libcr/coroutine.h> /* for cid_t, cr_* */ + +#define IMPLEMENTATION_FOR_LIBCR_IPC_MUTEX_H YES +#include <libcr_ipc/mutex.h> + +#include "_linkedlist.h" + +struct cr_mutex_waiter { + cr_ipc_sll_node; + cid_t cid; +}; + +void cr_mutex_lock(cr_mutex_t *mu) { + assert(mu); + cr_assert_in_coroutine(); + + if (!mu->locked) /* non-blocking fast-path */ + mu->locked = true; + else { /* blocking slow-path */ + struct cr_mutex_waiter self = { + .cid = cr_getcid(), + }; + cr_ipc_sll_push_to_rear(&mu->waiters, &self); + cr_pause_and_yield(); + } + assert(mu->locked); +} + +void cr_mutex_unlock(cr_mutex_t *mu) { + assert(mu); + cr_assert_in_coroutine(); + + assert(mu->locked); + if (mu->waiters.front) { + cr_unpause(cr_ipc_sll_node_cast(struct cr_mutex_waiter, mu->waiters.front)->cid); + cr_ipc_sll_pop_from_front(&mu->waiters); + } else + mu->locked = false; +} |