/* 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 struct cr_mutex_waiter { lm_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(), }; lm_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(lm_sll_node_cast(struct cr_mutex_waiter, mu->waiters.front)->cid); lm_sll_pop_from_front(&mu->waiters); } else mu->locked = false; }