diff options
author | Luke T. Shumaker <lukeshu@lukeshu.com> | 2025-04-07 20:29:35 -0600 |
---|---|---|
committer | Luke T. Shumaker <lukeshu@lukeshu.com> | 2025-04-07 20:29:35 -0600 |
commit | d053a0f6dffc575611324b81acaef0d1554bda6c (patch) | |
tree | 3eb702a06625ef1f6be0648f7fec311b628808e9 /libcr_ipc/mutex.c | |
parent | 33b7cf675238367db2fc0528dea103d7792eaa0e (diff) | |
parent | 062e063f76c5937be4dc8465f6471ff9b5eb7be9 (diff) |
Merge branch 'lukeshu/ipc'
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; +} |