/* * Copyright (c) 2013-2017 Richard Braun. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef X15_MUTEX_PI #include #include #include #include void mutex_lock_slow(struct mutex *mutex) { struct sleepq *sleepq; unsigned int state; sleepq = sleepq_lend(mutex, false); for (;;) { state = atomic_swap_uint(&mutex->state, MUTEX_CONTENDED); if (state == MUTEX_UNLOCKED) { break; } sleepq_wait(sleepq, "mutex"); } if (sleepq_empty(sleepq)) { state = atomic_swap_uint(&mutex->state, MUTEX_LOCKED); assert(state == MUTEX_CONTENDED); } sleepq_return(sleepq); } void mutex_unlock_slow(struct mutex *mutex) { struct sleepq *sleepq; sleepq = sleepq_acquire(mutex, false); if (sleepq == NULL) { return; } sleepq_signal(sleepq); sleepq_release(sleepq); } #endif /* X15_MUTEX_PI */