/* libcr_ipc/mutex.c - Simple mutexes for libcr * * Copyright (C) 2024-2025 Luke T. Shumaker * SPDX-License-Identifier: AGPL-3.0-or-later */ #include /* for cid_t, cr_* */ #define IMPLEMENTATION_FOR_LIBCR_IPC_MUTEX_H YES #include #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; }