1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2025-12-26 15:03:53 +01:00

Merge pull request #15462 from maribu/mutex_split_block

core/mutex: Minor cleanup
This commit is contained in:
benpicco 2020-11-18 15:01:26 +01:00 committed by GitHub
commit 36f1a9d4a8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 44 additions and 29 deletions

View File

@ -187,15 +187,13 @@ static inline int mutex_trylock(mutex_t *mutex)
*
* @param[in,out] mutex Mutex object to lock.
*
* @retval 0 The mutex was locked by the caller
*
* @pre @p mutex is not `NULL`
* @pre Mutex at @p mutex has been initialized
* @pre Must be called in thread context
*
* @post The mutex @p is locked and held by the calling thread.
*/
int mutex_lock(mutex_t *mutex);
void mutex_lock(mutex_t *mutex);
/**
* @brief Unlocks the mutex.

View File

@ -33,24 +33,23 @@
#define ENABLE_DEBUG 0
#include "debug.h"
int mutex_lock(mutex_t *mutex)
/**
* @brief Block waiting for a locked mutex
* @pre IRQs are disabled
* @post IRQs are restored to @p irq_state
* @post The calling thread is no longer waiting for the mutex, either
* because it got the mutex, or because the operation was cancelled
* (only possible for @ref mutex_lock_cancelable)
*
* Most applications don't use @ref mutex_lock_cancelable. Inlining this
* function into both @ref mutex_lock and @ref mutex_lock_cancelable is,
* therefore, beneficial for the majority of applications.
*/
static inline __attribute__((always_inline)) void _block(mutex_t *mutex, unsigned irq_state)
{
unsigned irq_state = irq_disable();
DEBUG("PID[%" PRIkernel_pid "]: Mutex in use.\n", thread_getpid());
if (mutex->queue.next == NULL) {
/* mutex is unlocked. */
mutex->queue.next = MUTEX_LOCKED;
DEBUG("PID[%" PRIkernel_pid "]: mutex_wait_and_lock early out.\n",
thread_getpid());
irq_restore(irq_state);
return 0;
}
thread_t *me = thread_get_active();
DEBUG("PID[%" PRIkernel_pid "]: Adding node to mutex queue: prio: %"
PRIu32 "\n", thread_getpid(), (uint32_t)me->priority);
DEBUG("PID[%" PRIkernel_pid "] mutex_lock() Adding node to mutex queue: "
"prio: %" PRIu32 "\n", thread_getpid(), (uint32_t)me->priority);
sched_set_status(me, STATUS_MUTEX_BLOCKED);
if (mutex->queue.next == MUTEX_LOCKED) {
mutex->queue.next = (list_node_t *)&me->rq_entry;
@ -60,19 +59,35 @@ int mutex_lock(mutex_t *mutex)
thread_add_to_list(&mutex->queue, me);
}
irq_restore(irq_state);
thread_yield_higher();
/* We were woken up by scheduler. Waker removed us from queue. */
return 0;
}
void mutex_lock(mutex_t *mutex)
{
unsigned irq_state = irq_disable();
DEBUG("PID[%" PRIkernel_pid "] mutex_lock().\n", thread_getpid());
if (mutex->queue.next == NULL) {
/* mutex is unlocked. */
mutex->queue.next = MUTEX_LOCKED;
DEBUG("PID[%" PRIkernel_pid "] mutex_lock(): early out.\n",
thread_getpid());
irq_restore(irq_state);
}
else {
_block(mutex, irq_state);
}
}
void mutex_unlock(mutex_t *mutex)
{
unsigned irqstate = irq_disable();
DEBUG("mutex_unlock(): queue.next: %p pid: %" PRIkernel_pid "\n",
(void *)mutex->queue.next, thread_getpid());
DEBUG("PID[%" PRIkernel_pid "] mutex_unlock(): queue.next: %p\n",
thread_getpid(), (void *)mutex->queue.next);
if (mutex->queue.next == NULL) {
/* the mutex was not locked */
@ -91,8 +106,8 @@ void mutex_unlock(mutex_t *mutex)
thread_t *process = container_of((clist_node_t *)next, thread_t, rq_entry);
DEBUG("mutex_unlock: waking up waiting thread %" PRIkernel_pid "\n",
process->pid);
DEBUG("PID[%" PRIkernel_pid "] mutex_unlock(): waking up waiting thread %"
PRIkernel_pid "\n", thread_getpid(), process->pid);
sched_set_status(process, STATUS_PENDING);
if (!mutex->queue.next) {
@ -106,8 +121,8 @@ void mutex_unlock(mutex_t *mutex)
void mutex_unlock_and_sleep(mutex_t *mutex)
{
DEBUG("PID[%" PRIkernel_pid "]: unlocking mutex. queue.next: %p, and "
"taking a nap\n", thread_getpid(), (void *)mutex->queue.next);
DEBUG("PID[%" PRIkernel_pid "] mutex_unlock_and_sleep(): queue.next: %p\n",
thread_getpid(), (void *)mutex->queue.next);
unsigned irqstate = irq_disable();
if (mutex->queue.next) {
@ -118,7 +133,8 @@ void mutex_unlock_and_sleep(mutex_t *mutex)
list_node_t *next = list_remove_head(&mutex->queue);
thread_t *process = container_of((clist_node_t *)next, thread_t,
rq_entry);
DEBUG("PID[%" PRIkernel_pid "]: waking up waiter.\n", process->pid);
DEBUG("PID[%" PRIkernel_pid "] mutex_unlock_and_sleep(): waking up "
"waiter.\n", process->pid);
sched_set_status(process, STATUS_PENDING);
if (!mutex->queue.next) {
mutex->queue.next = MUTEX_LOCKED;
@ -126,7 +142,8 @@ void mutex_unlock_and_sleep(mutex_t *mutex)
}
}
DEBUG("PID[%" PRIkernel_pid "]: going to sleep.\n", thread_getpid());
DEBUG("PID[%" PRIkernel_pid "] mutex_unlock_and_sleep(): going to sleep.\n",
thread_getpid());
sched_set_status(thread_get_active(), STATUS_SLEEPING);
irq_restore(irqstate);
thread_yield_higher();