/* 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_* */ #include #define IMPLEMENTATION_FOR_LIBCR_IPC_MUTEX_H YES #include struct cr_mutex_waiter { cid_t cid; }; SLIST_DECLARE_NODE(_cr_mutex_waiter_list, struct cr_mutex_waiter); 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_list_node self = { .val = { .cid = cr_getcid(), }}; slist_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(mu->waiters.front->val.cid); slist_pop_from_front(&mu->waiters); } else mu->locked = false; }