Merge pull request #15327 from maribu/mutex_cleanup_splitout
core/mutex: Cleanup
This commit is contained in:
commit
c4ef8b71e1
@ -105,7 +105,10 @@
|
|||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "irq.h"
|
||||||
|
#include "kernel_defines.h"
|
||||||
#include "list.h"
|
#include "list.h"
|
||||||
|
#include "thread.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@ -155,60 +158,62 @@ static inline void mutex_init(mutex_t *mutex)
|
|||||||
mutex->queue.next = NULL;
|
mutex->queue.next = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Lock a mutex, blocking or non-blocking.
|
|
||||||
*
|
|
||||||
* @details For commit purposes you should probably use mutex_trylock() and
|
|
||||||
* mutex_lock() instead.
|
|
||||||
*
|
|
||||||
* @param[in] mutex Mutex object to lock. Has to be initialized first.
|
|
||||||
* Must not be NULL.
|
|
||||||
* @param[in] blocking if true, block until mutex is available.
|
|
||||||
*
|
|
||||||
* @return 1 if mutex was unlocked, now it is locked.
|
|
||||||
* @return 0 if the mutex was locked.
|
|
||||||
*/
|
|
||||||
int _mutex_lock(mutex_t *mutex, volatile uint8_t *blocking);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Tries to get a mutex, non-blocking.
|
* @brief Tries to get a mutex, non-blocking.
|
||||||
*
|
*
|
||||||
* @param[in] mutex Mutex object to lock. Has to be initialized first. Must not
|
* @param[in,out] mutex Mutex object to lock.
|
||||||
* be NULL.
|
|
||||||
*
|
*
|
||||||
* @return 1 if mutex was unlocked, now it is locked.
|
* @retval 1 if mutex was unlocked, now it is locked.
|
||||||
* @return 0 if the mutex was locked.
|
* @retval 0 if the mutex was locked.
|
||||||
|
*
|
||||||
|
* @pre @p mutex is not `NULL`
|
||||||
|
* @pre Mutex at @p mutex has been initialized
|
||||||
|
* @pre Must be called in thread context
|
||||||
*/
|
*/
|
||||||
static inline int mutex_trylock(mutex_t *mutex)
|
static inline int mutex_trylock(mutex_t *mutex)
|
||||||
{
|
{
|
||||||
volatile uint8_t blocking = 0;
|
unsigned irq_state = irq_disable();
|
||||||
|
int retval = 0;
|
||||||
return _mutex_lock(mutex, &blocking);
|
if (mutex->queue.next == NULL) {
|
||||||
|
mutex->queue.next = MUTEX_LOCKED;
|
||||||
|
retval = 1;
|
||||||
|
};
|
||||||
|
irq_restore(irq_state);
|
||||||
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Locks a mutex, blocking.
|
* @brief Locks a mutex, blocking.
|
||||||
*
|
*
|
||||||
* @param[in] mutex Mutex object to lock. Has to be initialized first. Must not be NULL.
|
* @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.
|
||||||
*/
|
*/
|
||||||
static inline void mutex_lock(mutex_t *mutex)
|
int mutex_lock(mutex_t *mutex);
|
||||||
{
|
|
||||||
volatile uint8_t blocking = 1;
|
|
||||||
|
|
||||||
_mutex_lock(mutex, &blocking);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Unlocks the mutex.
|
* @brief Unlocks the mutex.
|
||||||
*
|
*
|
||||||
* @param[in] mutex Mutex object to unlock, must not be NULL.
|
* @param[in,out] mutex Mutex object to unlock.
|
||||||
|
*
|
||||||
|
* @pre @p mutex is not `NULL`
|
||||||
|
* @note It is safe to unlock a mutex held by a different thread.
|
||||||
|
* @note It is safe to call this function from IRQ context.
|
||||||
*/
|
*/
|
||||||
void mutex_unlock(mutex_t *mutex);
|
void mutex_unlock(mutex_t *mutex);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Unlocks the mutex and sends the current thread to sleep
|
* @brief Unlocks the mutex and sends the current thread to sleep
|
||||||
*
|
*
|
||||||
* @param[in] mutex Mutex object to unlock, must not be NULL.
|
* @param[in,out] mutex Mutex object to unlock.
|
||||||
|
* @pre @p mutex is not `NULL`
|
||||||
|
* @pre Must be called in thread context.
|
||||||
*/
|
*/
|
||||||
void mutex_unlock_and_sleep(mutex_t *mutex);
|
void mutex_unlock_and_sleep(mutex_t *mutex);
|
||||||
|
|
||||||
|
|||||||
27
core/mutex.c
27
core/mutex.c
@ -20,8 +20,9 @@
|
|||||||
* @}
|
* @}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <errno.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "mutex.h"
|
#include "mutex.h"
|
||||||
#include "thread.h"
|
#include "thread.h"
|
||||||
@ -32,21 +33,21 @@
|
|||||||
#define ENABLE_DEBUG 0
|
#define ENABLE_DEBUG 0
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
int _mutex_lock(mutex_t *mutex, volatile uint8_t *blocking)
|
int mutex_lock(mutex_t *mutex)
|
||||||
{
|
{
|
||||||
unsigned irqstate = irq_disable();
|
unsigned irq_state = irq_disable();
|
||||||
|
|
||||||
DEBUG("PID[%" PRIkernel_pid "]: Mutex in use.\n", thread_getpid());
|
DEBUG("PID[%" PRIkernel_pid "]: Mutex in use.\n", thread_getpid());
|
||||||
|
|
||||||
if (mutex->queue.next == NULL) {
|
if (mutex->queue.next == NULL) {
|
||||||
/* mutex is unlocked. */
|
/* mutex is unlocked. */
|
||||||
mutex->queue.next = MUTEX_LOCKED;
|
mutex->queue.next = MUTEX_LOCKED;
|
||||||
DEBUG("PID[%" PRIkernel_pid "]: mutex_wait early out.\n",
|
DEBUG("PID[%" PRIkernel_pid "]: mutex_wait_and_lock early out.\n",
|
||||||
thread_getpid());
|
thread_getpid());
|
||||||
irq_restore(irqstate);
|
irq_restore(irq_state);
|
||||||
return 1;
|
return 0;
|
||||||
}
|
}
|
||||||
else if (*blocking) {
|
|
||||||
thread_t *me = thread_get_active();
|
thread_t *me = thread_get_active();
|
||||||
DEBUG("PID[%" PRIkernel_pid "]: Adding node to mutex queue: prio: %"
|
DEBUG("PID[%" PRIkernel_pid "]: Adding node to mutex queue: prio: %"
|
||||||
PRIu32 "\n", thread_getpid(), (uint32_t)me->priority);
|
PRIu32 "\n", thread_getpid(), (uint32_t)me->priority);
|
||||||
@ -58,17 +59,13 @@ int _mutex_lock(mutex_t *mutex, volatile uint8_t *blocking)
|
|||||||
else {
|
else {
|
||||||
thread_add_to_list(&mutex->queue, me);
|
thread_add_to_list(&mutex->queue, me);
|
||||||
}
|
}
|
||||||
irq_restore(irqstate);
|
|
||||||
|
|
||||||
|
irq_restore(irq_state);
|
||||||
thread_yield_higher();
|
thread_yield_higher();
|
||||||
/* We were woken up by scheduler. Waker removed us from queue.
|
/* We were woken up by scheduler. Waker removed us from queue. */
|
||||||
* We have the mutex now. */
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
irq_restore(irqstate);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void mutex_unlock(mutex_t *mutex)
|
void mutex_unlock(mutex_t *mutex)
|
||||||
{
|
{
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user