Clean up the nxmutex library

- Remove the redundant holder, as nxsem now manages hoder TID
- Remove DEBUGASSERTIONS which are managed in nxsem
- Remove the "reset" handling logic, as it is now managed in nxsem
- Inline the simplest functions

Signed-off-by: Jukka Laitinen <jukka.laitinen@tii.ae>
This commit is contained in:
Jukka Laitinen 2025-04-23 19:23:22 +03:00 committed by Xiang Xiao
parent ffb49a25fb
commit 156469f158
5 changed files with 501 additions and 918 deletions

View file

@ -36,10 +36,8 @@
* Pre-processor Definitions
****************************************************************************/
#define NXMUTEX_NO_HOLDER ((pid_t)-1)
#define NXMUTEX_INITIALIZER { \
NXSEM_INITIALIZER(NXSEM_NO_MHOLDER, SEM_TYPE_MUTEX | SEM_PRIO_INHERIT), \
NXMUTEX_NO_HOLDER}
#define NXMUTEX_INITIALIZER \
{NXSEM_INITIALIZER(NXSEM_NO_MHOLDER, SEM_TYPE_MUTEX | SEM_PRIO_INHERIT)}
#define NXRMUTEX_INITIALIZER {NXMUTEX_INITIALIZER, 0}
@ -50,7 +48,6 @@
struct mutex_s
{
sem_t sem;
pid_t holder;
#if CONFIG_LIBC_MUTEX_BACKTRACE > 0
FAR void *backtrace[CONFIG_LIBC_MUTEX_BACKTRACE];
#endif
@ -80,6 +77,25 @@ extern "C"
#define EXTERN extern
#endif
/****************************************************************************
* Name: nxmutex_add_backtrace
*
* Description:
* This function add the backtrace of the holder of the mutex.
*
* Parameters:
* mutex - mutex descriptor.
*
* Return Value:
*
****************************************************************************/
#if CONFIG_LIBC_MUTEX_BACKTRACE > 0
void nxmutex_add_backtrace(FAR mutex_t *mutex);
#else
# define nxmutex_add_backtrace(mutex)
#endif
/****************************************************************************
* Name: nxmutex_init
*
@ -101,27 +117,6 @@ extern "C"
int nxmutex_init(FAR mutex_t *mutex);
/****************************************************************************
* Name: nxmutex_destroy
*
* Description:
* This function initializes the UNNAMED mutex. Following a
* successful call to nxmutex_init(), the mutex may be used in subsequent
* calls to nxmutex_lock(), nxmutex_unlock(), and nxmutex_trylock(). The
* mutex remains usable until it is destroyed.
*
* Parameters:
* mutex - Semaphore to be destroyed
*
* Return Value:
* This is an internal OS interface and should not be used by applications.
* It follows the NuttX internal error return policy: Zero (OK) is
* returned on success. A negated errno value is returned on failure.
*
****************************************************************************/
int nxmutex_destroy(FAR mutex_t *mutex);
/****************************************************************************
* Name: nxmutex_is_hold
*
@ -138,85 +133,6 @@ int nxmutex_destroy(FAR mutex_t *mutex);
bool nxmutex_is_hold(FAR mutex_t *mutex);
/****************************************************************************
* Name: nxmutex_get_holder
*
* Description:
* This function get the holder of the mutex referenced by 'mutex'.
* Note that this is inherently racy unless the calling thread is
* holding the mutex.
*
* Parameters:
* mutex - mutex descriptor.
*
* Return Value:
*
****************************************************************************/
int nxmutex_get_holder(FAR mutex_t *mutex);
/****************************************************************************
* Name: nxmutex_is_locked
*
* Description:
* This function get the lock state the mutex referenced by 'mutex'.
* Note that this is inherently racy unless the calling thread is
* holding the mutex.
*
* Parameters:
* mutex - mutex descriptor.
*
* Return Value:
*
****************************************************************************/
bool nxmutex_is_locked(FAR mutex_t *mutex);
/****************************************************************************
* Name: nxmutex_lock
*
* Description:
* This function attempts to lock the mutex referenced by 'mutex'. The
* mutex is implemented with a semaphore, so if the semaphore value is
* (<=) zero, then the calling task will not return until it successfully
* acquires the lock.
*
* Parameters:
* mutex - mutex descriptor.
*
* Return Value:
* This is an internal OS interface and should not be used by applications.
* It follows the NuttX internal error return policy: Zero (OK) is
* returned on success. A negated errno value is returned on failure.
* Possible returned errors:
*
****************************************************************************/
int nxmutex_lock(FAR mutex_t *mutex);
/****************************************************************************
* Name: nxmutex_trylock
*
* Description:
* This function locks the mutex only if the mutex is currently not locked.
* If the mutex has been locked already, the call returns without blocking.
*
* Parameters:
* mutex - mutex descriptor.
*
* Return Value:
* This is an internal OS interface and should not be used by applications.
* It follows the NuttX internal error return policy: Zero (OK) is
* returned on success. A negated errno value is returned on failure.
* Possible returned errors:
*
* -EINVAL - Invalid attempt to lock the mutex
* -EAGAIN - The mutex is not available.
*
****************************************************************************/
int nxmutex_trylock(FAR mutex_t *mutex);
/****************************************************************************
* Name: nxmutex_ticklock
*
@ -299,252 +215,6 @@ int nxmutex_clocklock(FAR mutex_t *mutex, clockid_t clockid,
int nxmutex_timedlock(FAR mutex_t *mutex, unsigned int timeout);
/****************************************************************************
* Name: nxmutex_unlock
*
* Description:
* This function attempts to unlock the mutex referenced by 'mutex'.
*
* Parameters:
* mutex - mutex descriptor.
*
* Return Value:
* This is an internal OS interface and should not be used by applications.
* It follows the NuttX internal error return policy: Zero (OK) is
* returned on success. A negated errno value is returned on failure.
* Possible returned errors:
*
* Assumptions:
* This function may be called from an interrupt handler.
*
****************************************************************************/
int nxmutex_unlock(FAR mutex_t *mutex);
/****************************************************************************
* Name: nxmutex_reset
*
* Description:
* This function reset lock state.
*
* Parameters:
* mutex - mutex descriptor.
*
****************************************************************************/
#if defined(CONFIG_BUILD_FLAT) || defined(__KERNEL__)
void nxmutex_reset(FAR mutex_t *mutex);
#endif
/****************************************************************************
* Name: nxmutex_breaklock
*
* Description:
* This function attempts to break the mutex
*
* Parameters:
* mutex - Mutex descriptor.
* locked - Is the mutex break success
*
* Return Value:
* This is an internal OS interface and should not be used by applications.
* It follows the NuttX internal error return policy: Zero (OK) is
* returned on success. A negated errno value is returned on failure.
* Possible returned errors:
*
****************************************************************************/
int nxmutex_breaklock(FAR mutex_t *mutex, FAR unsigned int *locked);
/****************************************************************************
* Name: nxmutex_restorelock
*
* Description:
* This function attempts to restore the mutex.
*
* Parameters:
* mutex - mutex descriptor.
* locked - true: it's mean that the mutex is broke success
*
* Return Value:
* This is an internal OS interface and should not be used by applications.
* It follows the NuttX internal error return policy: Zero (OK) is
* returned on success. A negated errno value is returned on failure
*
****************************************************************************/
int nxmutex_restorelock(FAR mutex_t *mutex, unsigned int locked);
/****************************************************************************
* Name: nxmutex_set_protocol
*
* Description:
* This function attempts to set the priority protocol of a mutex.
*
* Parameters:
* mutex - mutex descriptor.
* protocol - mutex protocol value to set.
*
* Return Value:
* This is an internal OS interface and should not be used by applications.
* It follows the NuttX internal error return policy: Zero (OK) is
* returned on success. A negated errno value is returned on failure
*
****************************************************************************/
int nxmutex_set_protocol(FAR mutex_t *mutex, int protocol);
/****************************************************************************
* Name: nxmutex_getprioceiling
*
* Description:
* This function attempts to get the priority ceiling of a mutex.
*
* Parameters:
* mutex - mutex descriptor.
* prioceiling - location to return the mutex priority ceiling.
*
* Return Value:
* This is an internal OS interface and should not be used by applications.
* It follows the NuttX internal error return policy: Zero (OK) is
* returned on success. A negated errno value is returned on failure
*
****************************************************************************/
int nxmutex_getprioceiling(FAR const mutex_t *mutex, FAR int *prioceiling);
/****************************************************************************
* Name: nxmutex_setprioceiling
*
* Description:
* This function attempts to set the priority ceiling of a mutex.
*
* Parameters:
* mutex - mutex descriptor.
* prioceiling - mutex priority ceiling value to set.
* old_ceiling - location to return the mutex ceiling priority set before.
*
* Return Value:
* This is an internal OS interface and should not be used by applications.
* It follows the NuttX internal error return policy: Zero (OK) is
* returned on success. A negated errno value is returned on failure
*
****************************************************************************/
int nxmutex_setprioceiling(FAR mutex_t *mutex, int prioceiling,
FAR int *old_ceiling);
/****************************************************************************
* Name: nxrmutex_init
*
* Description:
* This function initializes the UNNAMED recursive mutex. Following a
* successful call to nxrmutex_init(), the recursive mutex may be used in
* subsequent calls to nxrmutex_lock(), nxrmutex_unlock(),
* and nxrmutex_trylock(). The recursive mutex remains usable
* until it is destroyed.
*
* Parameters:
* rmutex - Recursive mutex to be initialized
*
* Return Value:
* This is an internal OS interface and should not be used by applications.
* It follows the NuttX internal error return policy: Zero (OK) is
* returned on success. A negated errno value is returned on failure.
*
****************************************************************************/
int nxrmutex_init(FAR rmutex_t *rmutex);
/****************************************************************************
* Name: nxrmutex_destroy
*
* Description:
* This function destroy the UNNAMED recursive mutex.
*
* Parameters:
* rmutex - Recursive mutex to be destroyed
*
* Return Value:
* This is an internal OS interface and should not be used by applications.
* It follows the NuttX internal error return policy: Zero (OK) is
* returned on success. A negated errno value is returned on failure.
*
****************************************************************************/
int nxrmutex_destroy(FAR rmutex_t *rmutex);
/****************************************************************************
* Name: nxrmutex_is_hold
*
* Description:
* This function check whether the calling thread hold the recursive mutex
* referenced by 'rmutex'.
*
* Parameters:
* rmutex - Recursive mutex descriptor.
*
* Return Value:
*
****************************************************************************/
bool nxrmutex_is_hold(FAR rmutex_t *rmutex);
/****************************************************************************
* Name: nxrmutex_is_recursive
*
* Description:
* This function check whether the recursive mutex is currently held
* recursively. That is, whether it's locked more than once by the
* current holder.
* Note that this is inherently racy unless the calling thread is
* holding the mutex.
*
* Parameters:
* rmutex - Recursive mutex descriptor.
*
* Return Value:
* If rmutex has returned to True recursively, otherwise returns false.
*
****************************************************************************/
bool nxrmutex_is_recursive(FAR rmutex_t *rmutex);
/****************************************************************************
* Name: nxrmutex_get_holder
*
* Description:
* This function get the holder of the mutex referenced by 'mutex'.
* Note that this is inherently racy unless the calling thread is
* holding the mutex.
*
* Parameters:
* rmutex - Rmutex descriptor.
*
* Return Value:
*
****************************************************************************/
int nxrmutex_get_holder(FAR rmutex_t *rmutex);
/****************************************************************************
* Name: nxrmutex_is_locked
*
* Description:
* This function get the lock state the recursive mutex
* referenced by 'rmutex'.
* Note that this is inherently racy unless the calling thread is
* holding the mutex.
*
* Parameters:
* rmutex - Recursive mutex descriptor.
*
* Return Value:
*
****************************************************************************/
bool nxrmutex_is_locked(FAR rmutex_t *rmutex);
/****************************************************************************
* Name: nrxmutex_lock
*
@ -697,20 +367,6 @@ int nxrmutex_timedlock(FAR rmutex_t *rmutex, unsigned int timeout);
int nxrmutex_unlock(FAR rmutex_t *rmutex);
/****************************************************************************
* Name: nxrmutex_reset
*
* Description:
* This function reset lock state.
*
* Parameters:
* rmutex - rmutex descriptor.
*
****************************************************************************/
#if defined(CONFIG_BUILD_FLAT) || defined(__KERNEL__)
void nxrmutex_reset(FAR rmutex_t *rmutex);
#endif
/****************************************************************************
* Name: nrxmutex_breaklock
*
@ -756,6 +412,472 @@ int nxrmutex_restorelock(FAR rmutex_t *rmutex, unsigned int count);
#define nxrmutex_setprioceiling(rmutex, prioceiling, old_ceiling) \
nxmutex_setprioceiling(&(rmutex)->mutex, prioceiling, old_ceiling)
/****************************************************************************
* Inline functions
****************************************************************************/
/****************************************************************************
* Name: nxmutex_get_holder
*
* Description:
* This function get the holder of the mutex referenced by 'mutex'.
* Note that this is inherently racy unless the calling thread is
* holding the mutex.
*
* Parameters:
* mutex - mutex descriptor.
*
* Return Value:
*
****************************************************************************/
static inline_function pid_t nxmutex_get_holder(FAR mutex_t *mutex)
{
uint32_t mholder = mutex->sem.val.mholder & ~NXSEM_MBLOCKING_BIT;
return NXSEM_MACQUIRED(mholder) ? (pid_t)mholder : -1;
}
/****************************************************************************
* Name: nxmutex_is_locked
*
* Description:
* This function get the lock state the mutex referenced by 'mutex'.
* Note that this is inherently racy unless the calling thread is
* holding the mutex.
*
* Parameters:
* mutex - mutex descriptor.
*
* Return Value:
*
****************************************************************************/
static inline_function bool nxmutex_is_locked(FAR mutex_t *mutex)
{
return NXSEM_MACQUIRED(mutex->sem.val.mholder);
}
/****************************************************************************
* Name: nxmutex_destroy
*
* Description:
* This function initializes the UNNAMED mutex. Following a
* successful call to nxmutex_init(), the mutex may be used in subsequent
* calls to nxmutex_lock(), nxmutex_unlock(), and nxmutex_trylock(). The
* mutex remains usable until it is destroyed.
*
* Parameters:
* mutex - Semaphore to be destroyed
*
* Return Value:
* This is an internal OS interface and should not be used by applications.
* It follows the NuttX internal error return policy: Zero (OK) is
* returned on success. A negated errno value is returned on failure.
*
****************************************************************************/
static inline_function int nxmutex_destroy(FAR mutex_t *mutex)
{
return nxsem_destroy(&mutex->sem);
}
/****************************************************************************
* Name: nxmutex_lock
*
* Description:
* This function attempts to lock the mutex referenced by 'mutex'. The
* mutex is implemented with a semaphore, so if the semaphore value is
* (<=) zero, then the calling task will not return until it successfully
* acquires the lock.
*
* Parameters:
* mutex - mutex descriptor.
*
* Return Value:
* This is an internal OS interface and should not be used by applications.
* It follows the NuttX internal error return policy: Zero (OK) is
* returned on success. A negated errno value is returned on failure.
* Possible returned errors:
*
****************************************************************************/
static inline_function int nxmutex_lock(FAR mutex_t *mutex)
{
int ret;
ret = nxsem_wait(&mutex->sem);
if (ret >= 0)
{
nxmutex_add_backtrace(mutex);
}
return ret;
}
/****************************************************************************
* Name: nxmutex_trylock
*
* Description:
* This function locks the mutex only if the mutex is currently not locked.
* If the mutex has been locked already, the call returns without blocking.
*
* Parameters:
* mutex - mutex descriptor.
*
* Return Value:
* This is an internal OS interface and should not be used by applications.
* It follows the NuttX internal error return policy: Zero (OK) is
* returned on success. A negated errno value is returned on failure.
* Possible returned errors:
*
* -EINVAL - Invalid attempt to lock the mutex
* -EAGAIN - The mutex is not available.
*
****************************************************************************/
static inline_function int nxmutex_trylock(FAR mutex_t *mutex)
{
int ret;
ret = nxsem_trywait(&mutex->sem);
if (ret >= 0)
{
nxmutex_add_backtrace(mutex);
}
return ret;
}
/****************************************************************************
* Name: nxmutex_unlock
*
* Description:
* This function attempts to unlock the mutex referenced by 'mutex'.
*
* Parameters:
* mutex - mutex descriptor.
*
* Return Value:
* This is an internal OS interface and should not be used by applications.
* It follows the NuttX internal error return policy: Zero (OK) is
* returned on success. A negated errno value is returned on failure.
* Possible returned errors:
*
* Assumptions:
* This function may be called from an interrupt handler.
*
****************************************************************************/
static inline_function int nxmutex_unlock(FAR mutex_t *mutex)
{
return nxsem_post(&mutex->sem);
}
/****************************************************************************
* Name: nxmutex_reset
*
* Description:
* This function reset lock state.
*
* Parameters:
* mutex - mutex descriptor.
*
****************************************************************************/
#if defined(CONFIG_BUILD_FLAT) || defined(__KERNEL__)
static inline_function void nxmutex_reset(FAR mutex_t *mutex)
{
nxsem_reset(&mutex->sem, 1);
}
#endif
/****************************************************************************
* Name: nxmutex_breaklock
*
* Description:
* This function attempts to break the mutex
*
* Parameters:
* mutex - Mutex descriptor.
* locked - Is the mutex break success
*
* Return Value:
* This is an internal OS interface and should not be used by applications.
* It follows the NuttX internal error return policy: Zero (OK) is
* returned on success. A negated errno value is returned on failure.
* Possible returned errors:
*
****************************************************************************/
static inline_function int nxmutex_breaklock(FAR mutex_t *mutex,
FAR unsigned int *locked)
{
int ret = OK;
*locked = false;
ret = nxmutex_unlock(mutex);
if (ret >= 0)
{
*locked = true;
}
return ret;
}
/****************************************************************************
* Name: nxmutex_restorelock
*
* Description:
* This function attempts to restore the mutex.
*
* Parameters:
* mutex - mutex descriptor.
* locked - true: it's mean that the mutex is broke success
*
* Return Value:
* This is an internal OS interface and should not be used by applications.
* It follows the NuttX internal error return policy: Zero (OK) is
* returned on success. A negated errno value is returned on failure
*
****************************************************************************/
static inline_function int nxmutex_restorelock(FAR mutex_t *mutex,
unsigned int locked)
{
return locked ? nxmutex_lock(mutex) : OK;
}
/****************************************************************************
* Name: nxmutex_set_protocol
*
* Description:
* This function attempts to set the priority protocol of a mutex.
*
* Parameters:
* mutex - mutex descriptor.
* protocol - mutex protocol value to set.
*
* Return Value:
* This is an internal OS interface and should not be used by applications.
* It follows the NuttX internal error return policy: Zero (OK) is
* returned on success. A negated errno value is returned on failure
*
****************************************************************************/
static inline_function int nxmutex_set_protocol(FAR mutex_t *mutex,
int protocol)
{
return nxsem_set_protocol(&mutex->sem, protocol);
}
/****************************************************************************
* Name: nxmutex_getprioceiling
*
* Description:
* This function attempts to get the priority ceiling of a mutex.
*
* Parameters:
* mutex - mutex descriptor.
* prioceiling - location to return the mutex priority ceiling.
*
* Return Value:
* This is an internal OS interface and should not be used by applications.
* It follows the NuttX internal error return policy: Zero (OK) is
* returned on success. A negated errno value is returned on failure
*
****************************************************************************/
#ifdef CONFIG_PRIORITY_PROTECT
static inline_function int nxmutex_getprioceiling(FAR const mutex_t *mutex,
FAR int *prioceiling)
{
return nxsem_getprioceiling(&mutex->sem, prioceiling);
}
#endif
/****************************************************************************
* Name: nxmutex_setprioceiling
*
* Description:
* This function attempts to set the priority ceiling of a mutex.
*
* Parameters:
* mutex - mutex descriptor.
* prioceiling - mutex priority ceiling value to set.
* old_ceiling - location to return the mutex ceiling priority set before.
*
* Return Value:
* This is an internal OS interface and should not be used by applications.
* It follows the NuttX internal error return policy: Zero (OK) is
* returned on success. A negated errno value is returned on failure
*
****************************************************************************/
#ifdef CONFIG_PRIORITY_PROTECT
static inline_function int nxmutex_setprioceiling(FAR mutex_t *mutex,
int prioceiling,
FAR int *old_ceiling)
{
return nxsem_setprioceiling(&mutex->sem, prioceiling, old_ceiling);
}
#endif
/****************************************************************************
* Name: nxrmutex_init
*
* Description:
* This function initializes the UNNAMED recursive mutex. Following a
* successful call to nxrmutex_init(), the recursive mutex may be used in
* subsequent calls to nxrmutex_lock(), nxrmutex_unlock(),
* and nxrmutex_trylock(). The recursive mutex remains usable
* until it is destroyed.
*
* Parameters:
* rmutex - Recursive mutex to be initialized
*
* Return Value:
* This is an internal OS interface and should not be used by applications.
* It follows the NuttX internal error return policy: Zero (OK) is
* returned on success. A negated errno value is returned on failure.
*
****************************************************************************/
static inline_function int nxrmutex_init(FAR rmutex_t *rmutex)
{
rmutex->count = 0;
return nxmutex_init(&rmutex->mutex);
}
/****************************************************************************
* Name: nxrmutex_destroy
*
* Description:
* This function destroy the UNNAMED recursive mutex.
*
* Parameters:
* rmutex - Recursive mutex to be destroyed
*
* Return Value:
* This is an internal OS interface and should not be used by applications.
* It follows the NuttX internal error return policy: Zero (OK) is
* returned on success. A negated errno value is returned on failure.
*
****************************************************************************/
static inline_function int nxrmutex_destroy(FAR rmutex_t *rmutex)
{
int ret = nxmutex_destroy(&rmutex->mutex);
if (ret >= 0)
{
rmutex->count = 0;
}
return ret;
}
/****************************************************************************
* Name: nxrmutex_is_hold
*
* Description:
* This function check whether the calling thread hold the recursive mutex
* referenced by 'rmutex'.
*
* Parameters:
* rmutex - Recursive mutex descriptor.
*
* Return Value:
*
****************************************************************************/
static inline_function bool nxrmutex_is_hold(FAR rmutex_t *rmutex)
{
return nxmutex_is_hold(&rmutex->mutex);
}
/****************************************************************************
* Name: nxrmutex_is_recursive
*
* Description:
* This function check whether the recursive mutex is currently held
* recursively. That is, whether it's locked more than once by the
* current holder.
* Note that this is inherently racy unless the calling thread is
* holding the mutex.
*
* Parameters:
* rmutex - Recursive mutex descriptor.
*
* Return Value:
* If rmutex has returned to True recursively, otherwise returns false.
*
****************************************************************************/
static inline_function bool nxrmutex_is_recursive(FAR rmutex_t *rmutex)
{
return rmutex->count > 1;
}
/****************************************************************************
* Name: nxrmutex_get_holder
*
* Description:
* This function get the holder of the mutex referenced by 'mutex'.
* Note that this is inherently racy unless the calling thread is
* holding the mutex.
*
* Parameters:
* rmutex - Rmutex descriptor.
*
* Return Value:
*
****************************************************************************/
static inline_function int nxrmutex_get_holder(FAR rmutex_t *rmutex)
{
return nxmutex_get_holder(&rmutex->mutex);
}
/****************************************************************************
* Name: nxrmutex_is_locked
*
* Description:
* This function get the lock state the recursive mutex
* referenced by 'rmutex'.
* Note that this is inherently racy unless the calling thread is
* holding the mutex.
*
* Parameters:
* rmutex - Recursive mutex descriptor.
*
* Return Value:
*
****************************************************************************/
static inline_function bool nxrmutex_is_locked(FAR rmutex_t *rmutex)
{
return nxmutex_is_locked(&rmutex->mutex);
}
/****************************************************************************
* Name: nxrmutex_reset
*
* Description:
* This function reset lock state.
*
* Parameters:
* rmutex - rmutex descriptor.
*
****************************************************************************/
#if defined(CONFIG_BUILD_FLAT) || defined(__KERNEL__)
static inline_function void nxrmutex_reset(FAR rmutex_t *rmutex)
{
rmutex->count = 0;
nxmutex_reset(&rmutex->mutex);
}
#endif
#undef EXTERN
#ifdef __cplusplus
}

View file

@ -350,8 +350,7 @@ typedef struct pthread_mutex_s pthread_mutex_t;
#define PTHREAD_NXMUTEX_INITIALIZER { \
NXSEM_INITIALIZER(NXSEM_NO_MHOLDER, \
SEM_TYPE_MUTEX | PTHREAD_MUTEX_DEFAULT_PRIO_FLAGS), \
NXMUTEX_NO_HOLDER}
SEM_TYPE_MUTEX | PTHREAD_MUTEX_DEFAULT_PRIO_FLAGS)}
#define PTHREAD_NXRMUTEX_INITIALIZER {PTHREAD_NXMUTEX_INITIALIZER, 0}
#if defined(CONFIG_PTHREAD_MUTEX_TYPES) && !defined(CONFIG_PTHREAD_MUTEX_UNSAFE)

View file

@ -32,33 +32,9 @@
#include <nuttx/semaphore.h>
/****************************************************************************
* Pre-processor Definitions
* Public Functions
****************************************************************************/
#define NXMUTEX_RESET ((pid_t)-2)
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: nxmutex_is_reset
*
* Description:
* This function check whether the mutex is reset
*
* Parameters:
* mutex - mutex descriptor.
*
* Return Value:
*
****************************************************************************/
static bool nxmutex_is_reset(FAR mutex_t *mutex)
{
return mutex->holder == NXMUTEX_RESET;
}
/****************************************************************************
* Name: nxmutex_add_backtrace
*
@ -73,25 +49,19 @@ static bool nxmutex_is_reset(FAR mutex_t *mutex)
****************************************************************************/
#if CONFIG_LIBC_MUTEX_BACKTRACE > 0
static void nxmutex_add_backtrace(FAR mutex_t *mutex)
void nxmutex_add_backtrace(FAR mutex_t *mutex)
{
int n;
n = sched_backtrace(mutex->holder, mutex->backtrace,
n = sched_backtrace(nxmutex_get_holder(&mutex), mutex->backtrace,
CONFIG_LIBC_MUTEX_BACKTRACE, 0);
if (n < CONFIG_LIBC_MUTEX_BACKTRACE)
{
mutex->backtrace[n] = NULL;
}
}
#else
# define nxmutex_add_backtrace(mutex)
#endif
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: nxmutex_init
*
@ -120,7 +90,6 @@ int nxmutex_init(FAR mutex_t *mutex)
return ret;
}
mutex->holder = NXMUTEX_NO_HOLDER;
#ifdef CONFIG_PRIORITY_INHERITANCE
nxsem_set_protocol(&mutex->sem, SEM_TYPE_MUTEX | SEM_PRIO_INHERIT);
#else
@ -129,38 +98,6 @@ int nxmutex_init(FAR mutex_t *mutex)
return ret;
}
/****************************************************************************
* Name: nxmutex_destroy
*
* Description:
* This function initializes the UNNAMED mutex. Following a
* successful call to nxmutex_init(), the mutex may be used in subsequent
* calls to nxmutex_lock(), nxmutex_unlock(), and nxmutex_trylock(). The
* mutex remains usable until it is destroyed.
*
* Parameters:
* mutex - Semaphore to be destroyed
*
* Return Value:
* This is an internal OS interface and should not be used by applications.
* It follows the NuttX internal error return policy: Zero (OK) is
* returned on success. A negated errno value is returned on failure.
*
****************************************************************************/
int nxmutex_destroy(FAR mutex_t *mutex)
{
int ret = nxsem_destroy(&mutex->sem);
if (ret < 0)
{
return ret;
}
mutex->holder = NXMUTEX_NO_HOLDER;
return ret;
}
/****************************************************************************
* Name: nxmutex_is_hold
*
@ -177,129 +114,7 @@ int nxmutex_destroy(FAR mutex_t *mutex)
bool nxmutex_is_hold(FAR mutex_t *mutex)
{
return mutex->holder == _SCHED_GETTID();
}
/****************************************************************************
* Name: nxmutex_get_holder
*
* Description:
* This function get the holder of the mutex referenced by 'mutex'.
* Note that this is inherently racy unless the calling thread is
* holding the mutex.
*
* Parameters:
* mutex - mutex descriptor.
*
* Return Value:
*
****************************************************************************/
int nxmutex_get_holder(FAR mutex_t *mutex)
{
return mutex->holder;
}
/****************************************************************************
* Name: nxmutex_is_locked
*
* Description:
* This function get the lock state the mutex referenced by 'mutex'.
* Note that this is inherently racy unless the calling thread is
* holding the mutex.
*
* Parameters:
* mutex - mutex descriptor.
*
* Return Value:
*
****************************************************************************/
bool nxmutex_is_locked(FAR mutex_t *mutex)
{
return NXSEM_MACQUIRED(mutex->sem.val.mholder);
}
/****************************************************************************
* Name: nxmutex_lock
*
* Description:
* This function attempts to lock the mutex referenced by 'mutex'. The
* mutex is implemented with a semaphore, so if the semaphore value is
* (<=) zero, then the calling task will not return until it successfully
* acquires the lock.
*
* Parameters:
* mutex - mutex descriptor.
*
* Return Value:
* This is an internal OS interface and should not be used by applications.
* It follows the NuttX internal error return policy: Zero (OK) is
* returned on success. A negated errno value is returned on failure.
* Possible returned errors:
*
****************************************************************************/
int nxmutex_lock(FAR mutex_t *mutex)
{
int ret;
DEBUGASSERT(!nxmutex_is_hold(mutex));
for (; ; )
{
/* Take the semaphore (perhaps waiting) */
ret = nxsem_wait(&mutex->sem);
if (ret >= 0)
{
mutex->holder = _SCHED_GETTID();
nxmutex_add_backtrace(mutex);
break;
}
else if (ret != -EINTR && ret != -ECANCELED)
{
break;
}
}
return ret;
}
/****************************************************************************
* Name: nxmutex_trylock
*
* Description:
* This function locks the mutex only if the mutex is currently not locked.
* If the mutex has been locked already, the call returns without blocking.
*
* Parameters:
* mutex - mutex descriptor.
*
* Return Value:
* This is an internal OS interface and should not be used by applications.
* It follows the NuttX internal error return policy: Zero (OK) is
* returned on success. A negated errno value is returned on failure.
* Possible returned errors:
*
* -EINVAL - Invalid attempt to lock the mutex
* -EAGAIN - The mutex is not available.
*
****************************************************************************/
int nxmutex_trylock(FAR mutex_t *mutex)
{
int ret;
ret = nxsem_trywait(&mutex->sem);
if (ret < 0)
{
return ret;
}
mutex->holder = _SCHED_GETTID();
nxmutex_add_backtrace(mutex);
return ret;
return nxmutex_get_holder(mutex) == _SCHED_GETTID();
}
/****************************************************************************
@ -345,7 +160,6 @@ int nxmutex_ticklock(FAR mutex_t *mutex, uint32_t delay)
if (ret >= 0)
{
mutex->holder = _SCHED_GETTID();
nxmutex_add_backtrace(mutex);
}
@ -384,22 +198,17 @@ int nxmutex_clocklock(FAR mutex_t *mutex, clockid_t clockid,
/* Wait until we get the lock or until the timeout expires */
do
if (abstime)
{
if (abstime)
{
ret = nxsem_clockwait(&mutex->sem, clockid, abstime);
}
else
{
ret = nxsem_wait(&mutex->sem);
}
ret = nxsem_clockwait(&mutex->sem, clockid, abstime);
}
else
{
ret = nxsem_wait(&mutex->sem);
}
while (ret == -EINTR || ret == -ECANCELED);
if (ret >= 0)
{
mutex->holder = _SCHED_GETTID();
nxmutex_add_backtrace(mutex);
}
@ -445,334 +254,6 @@ int nxmutex_timedlock(FAR mutex_t *mutex, unsigned int timeout)
return nxmutex_clocklock(mutex, CLOCK_MONOTONIC, &rqtp);
}
/****************************************************************************
* Name: nxmutex_unlock
*
* Description:
* This function attempts to unlock the mutex referenced by 'mutex'.
*
* Parameters:
* mutex - mutex descriptor.
*
* Return Value:
* This is an internal OS interface and should not be used by applications.
* It follows the NuttX internal error return policy: Zero (OK) is
* returned on success. A negated errno value is returned on failure.
* Possible returned errors:
*
* Assumptions:
* This function may be called from an interrupt handler.
*
****************************************************************************/
int nxmutex_unlock(FAR mutex_t *mutex)
{
int ret;
if (nxmutex_is_reset(mutex))
{
return OK;
}
DEBUGASSERT(nxmutex_is_hold(mutex));
mutex->holder = NXMUTEX_NO_HOLDER;
ret = nxsem_post(&mutex->sem);
if (ret < 0)
{
mutex->holder = _SCHED_GETTID();
}
return ret;
}
/****************************************************************************
* Name: nxmutex_reset
*
* Description:
* This function reset lock state.
*
* Parameters:
* mutex - mutex descriptor.
*
****************************************************************************/
#if defined(CONFIG_BUILD_FLAT) || defined(__KERNEL__)
void nxmutex_reset(FAR mutex_t *mutex)
{
mutex->holder = NXMUTEX_RESET;
nxsem_reset(&mutex->sem, 1);
}
#endif
/****************************************************************************
* Name: nxmutex_breaklock
*
* Description:
* This function attempts to break the mutex
*
* Parameters:
* mutex - Mutex descriptor.
* locked - Is the mutex break success
*
* Return Value:
* This is an internal OS interface and should not be used by applications.
* It follows the NuttX internal error return policy: Zero (OK) is
* returned on success. A negated errno value is returned on failure.
* Possible returned errors:
*
****************************************************************************/
int nxmutex_breaklock(FAR mutex_t *mutex, FAR unsigned int *locked)
{
int ret = OK;
*locked = false;
if (nxmutex_is_hold(mutex))
{
ret = nxmutex_unlock(mutex);
if (ret >= 0)
{
*locked = true;
}
}
return ret;
}
/****************************************************************************
* Name: nxmutex_restorelock
*
* Description:
* This function attempts to restore the mutex.
*
* Parameters:
* mutex - mutex descriptor.
* locked - true: it's mean that the mutex is broke success
*
* Return Value:
* This is an internal OS interface and should not be used by applications.
* It follows the NuttX internal error return policy: Zero (OK) is
* returned on success. A negated errno value is returned on failure
*
****************************************************************************/
int nxmutex_restorelock(FAR mutex_t *mutex, unsigned int locked)
{
return locked ? nxmutex_lock(mutex) : OK;
}
/****************************************************************************
* Name: nxmutex_set_protocol
*
* Description:
* This function attempts to set the priority protocol of a mutex.
*
* Parameters:
* mutex - mutex descriptor.
* protocol - mutex protocol value to set.
*
* Return Value:
* This is an internal OS interface and should not be used by applications.
* It follows the NuttX internal error return policy: Zero (OK) is
* returned on success. A negated errno value is returned on failure
*
****************************************************************************/
int nxmutex_set_protocol(FAR mutex_t *mutex, int protocol)
{
return nxsem_set_protocol(&mutex->sem, protocol);
}
/****************************************************************************
* Name: nxmutex_getprioceiling
*
* Description:
* This function attempts to get the priority ceiling of a mutex.
*
* Parameters:
* mutex - mutex descriptor.
* prioceiling - location to return the mutex priority ceiling.
*
* Return Value:
* This is an internal OS interface and should not be used by applications.
* It follows the NuttX internal error return policy: Zero (OK) is
* returned on success. A negated errno value is returned on failure
*
****************************************************************************/
#ifdef CONFIG_PRIORITY_PROTECT
int nxmutex_getprioceiling(FAR const mutex_t *mutex, FAR int *prioceiling)
{
return nxsem_getprioceiling(&mutex->sem, prioceiling);
}
#endif
/****************************************************************************
* Name: nxmutex_setprioceiling
*
* Description:
* This function attempts to set the priority ceiling of a mutex.
*
* Parameters:
* mutex - mutex descriptor.
* prioceiling - mutex priority ceiling value to set.
* old_ceiling - location to return the mutex ceiling priority set before.
*
* Return Value:
* This is an internal OS interface and should not be used by applications.
* It follows the NuttX internal error return policy: Zero (OK) is
* returned on success. A negated errno value is returned on failure
*
****************************************************************************/
#ifdef CONFIG_PRIORITY_PROTECT
int nxmutex_setprioceiling(FAR mutex_t *mutex, int prioceiling,
FAR int *old_ceiling)
{
return nxsem_setprioceiling(&mutex->sem, prioceiling, old_ceiling);
}
#endif
/****************************************************************************
* Name: nxrmutex_init
*
* Description:
* This function initializes the UNNAMED recursive mutex. Following a
* successful call to nxrmutex_init(), the recursive mutex may be used in
* subsequent calls to nxrmutex_lock(), nxrmutex_unlock(),
* and nxrmutex_trylock(). The recursive mutex remains usable
* until it is destroyed.
*
* Parameters:
* rmutex - Recursive mutex to be initialized
*
* Return Value:
* This is an internal OS interface and should not be used by applications.
* It follows the NuttX internal error return policy: Zero (OK) is
* returned on success. A negated errno value is returned on failure.
*
****************************************************************************/
int nxrmutex_init(FAR rmutex_t *rmutex)
{
rmutex->count = 0;
return nxmutex_init(&rmutex->mutex);
}
/****************************************************************************
* Name: nxrmutex_destroy
*
* Description:
* This function destroy the UNNAMED recursive mutex.
*
* Parameters:
* rmutex - Recursive mutex to be destroyed
*
* Return Value:
* This is an internal OS interface and should not be used by applications.
* It follows the NuttX internal error return policy: Zero (OK) is
* returned on success. A negated errno value is returned on failure.
*
****************************************************************************/
int nxrmutex_destroy(FAR rmutex_t *rmutex)
{
int ret = nxmutex_destroy(&rmutex->mutex);
if (ret >= 0)
{
rmutex->count = 0;
}
return ret;
}
/****************************************************************************
* Name: nxrmutex_is_hold
*
* Description:
* This function check whether the calling thread hold the recursive mutex
* referenced by 'rmutex'.
*
* Parameters:
* rmutex - Recursive mutex descriptor.
*
* Return Value:
*
****************************************************************************/
bool nxrmutex_is_hold(FAR rmutex_t *rmutex)
{
return nxmutex_is_hold(&rmutex->mutex);
}
/****************************************************************************
* Name: nxrmutex_is_recursive
*
* Description:
* This function check whether the recursive mutex is currently held
* recursively. That is, whether it's locked more than once by the
* current holder.
* Note that this is inherently racy unless the calling thread is
* holding the mutex.
*
* Parameters:
* rmutex - Recursive mutex descriptor.
*
* Return Value:
* If rmutex has returned to True recursively, otherwise returns false.
*
****************************************************************************/
bool nxrmutex_is_recursive(FAR rmutex_t *rmutex)
{
return rmutex->count > 1;
}
/****************************************************************************
* Name: nxrmutex_get_holder
*
* Description:
* This function get the holder of the mutex referenced by 'mutex'.
* Note that this is inherently racy unless the calling thread is
* holding the mutex.
*
* Parameters:
* rmutex - Rmutex descriptor.
*
* Return Value:
*
****************************************************************************/
int nxrmutex_get_holder(FAR rmutex_t *rmutex)
{
return nxmutex_get_holder(&rmutex->mutex);
}
/****************************************************************************
* Name: nxrmutex_is_locked
*
* Description:
* This function get the lock state the recursive mutex
* referenced by 'rmutex'.
* Note that this is inherently racy unless the calling thread is
* holding the mutex.
*
* Parameters:
* rmutex - Recursive mutex descriptor.
*
* Return Value:
*
****************************************************************************/
bool nxrmutex_is_locked(FAR rmutex_t *rmutex)
{
return nxmutex_is_locked(&rmutex->mutex);
}
/****************************************************************************
* Name: nrxmutex_lock
*
@ -1021,25 +502,6 @@ int nxrmutex_unlock(FAR rmutex_t *rmutex)
return ret;
}
/****************************************************************************
* Name: nxrmutex_reset
*
* Description:
* This function reset lock state.
*
* Parameters:
* rmutex - rmutex descriptor.
*
****************************************************************************/
#if defined(CONFIG_BUILD_FLAT) || defined(__KERNEL__)
void nxrmutex_reset(FAR rmutex_t *rmutex)
{
rmutex->count = 0;
nxmutex_reset(&rmutex->mutex);
}
#endif
/****************************************************************************
* Name: nrxmutex_breaklock
*

View file

@ -100,8 +100,8 @@ static void collect_deadlock(FAR struct tcb_s *tcb, FAR void *arg)
pid_t holder;
size_t i;
holder = mutex->holder;
if (holder == NXMUTEX_NO_HOLDER)
holder = nxmutex_get_holder(mutex);
if (holder < 0)
{
break;
}

View file

@ -101,7 +101,7 @@ void nxsched_get_stateinfo(FAR struct tcb_s *tcb, FAR char *state,
if (tcb->task_state == TSTATE_WAIT_SEM &&
((FAR sem_t *)(tcb->waitobj))->flags & SEM_TYPE_MUTEX)
{
pid_t holder = ((FAR mutex_t *)(tcb->waitobj))->holder;
pid_t holder = nxmutex_get_holder((FAR mutex_t *)tcb->waitobj);
leave_critical_section(flags);
snprintf(state, length, "Waiting,Mutex:%d", holder);