diff --git a/include/nuttx/mutex.h b/include/nuttx/mutex.h index f92a9d344b..e69017e807 100644 --- a/include/nuttx/mutex.h +++ b/include/nuttx/mutex.h @@ -131,6 +131,21 @@ 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'. + * + * Parameters: + * mutex - mutex descriptor. + * + * Return Value: + * + ****************************************************************************/ + +int nxmutex_get_holder(FAR mutex_t *mutex); + /**************************************************************************** * Name: nxmutex_is_locked * @@ -191,6 +206,34 @@ int nxmutex_lock(FAR mutex_t *mutex); int nxmutex_trylock(FAR mutex_t *mutex); +/**************************************************************************** + * Name: nxmutex_clocklock + * + * Description: + * This function attempts to lock the mutex referenced by 'mutex'. If the + * mutex value is (<=) zero, then the calling task will not return until it + * successfully acquires the lock or timed out + * + * Input Parameters: + * mutex - Mutex object + * clockid - The clock to be used as the time base + * abstime - The absolute time when the mutex lock timed out + * + * Returned Value: + * OK The mutex successfully acquires + * EINVAL The mutex argument does not refer to a valid mutex. Or the + * thread would have blocked, and the abstime parameter specified + * a nanoseconds field value less than zero or greater than or + * equal to 1000 million. + * ETIMEDOUT The mutex could not be locked before the specified timeout + * expired. + * EDEADLK A deadlock condition was detected. + * + ****************************************************************************/ + +int nxmutex_clocklock(FAR mutex_t *mutex, clockid_t clockid, + FAR const struct timespec *abstime); + /**************************************************************************** * Name: nxmutex_timedlock * @@ -349,6 +392,21 @@ int nxrmutex_destroy(FAR rmutex_t *rmutex); bool nxrmutex_is_hold(FAR rmutex_t *rmutex); +/**************************************************************************** + * Name: nxrmutex_get_holder + * + * Description: + * This function get the holder of the mutex referenced by 'mutex'. + * + * Parameters: + * rmutex - Rmutex descriptor. + * + * Return Value: + * + ****************************************************************************/ + +int nxrmutex_get_holder(FAR rmutex_t *rmutex); + /**************************************************************************** * Name: nxrmutex_is_locked * @@ -411,6 +469,34 @@ int nxrmutex_lock(FAR rmutex_t *rmutex); int nxrmutex_trylock(FAR rmutex_t *rmutex); +/**************************************************************************** + * Name: nxrmutex_clocklock + * + * Description: + * This function attempts to lock the mutex referenced by 'mutex'. If the + * mutex value is (<=) zero, then the calling task will not return until it + * successfully acquires the lock or timed out + * + * Input Parameters: + * rmutex - Rmutex object + * clockid - The clock to be used as the time base + * abstime - The absolute time when the mutex lock timed out + * + * Returned Value: + * OK The mutex successfully acquires + * EINVAL The mutex argument does not refer to a valid mutex. Or the + * thread would have blocked, and the abstime parameter specified + * a nanoseconds field value less than zero or greater than or + * equal to 1000 million. + * ETIMEDOUT The mutex could not be locked before the specified timeout + * expired. + * EDEADLK A deadlock condition was detected. + * + ****************************************************************************/ + +int nxrmutex_clocklock(FAR rmutex_t *rmutex, clockid_t clockid, + FAR const struct timespec *abstime); + /**************************************************************************** * Name: nxrmutex_timedlock * diff --git a/libs/libc/misc/lib_mutex.c b/libs/libc/misc/lib_mutex.c index 379c812d06..6c2aac6cf4 100644 --- a/libs/libc/misc/lib_mutex.c +++ b/libs/libc/misc/lib_mutex.c @@ -149,6 +149,24 @@ 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'. + * + * Parameters: + * mutex - mutex descriptor. + * + * Return Value: + * + ****************************************************************************/ + +int nxmutex_get_holder(FAR mutex_t *mutex) +{ + return mutex->holder; +} + /**************************************************************************** * Name: nxmutex_is_locked * @@ -251,6 +269,52 @@ int nxmutex_trylock(FAR mutex_t *mutex) return ret; } +/**************************************************************************** + * Name: nxmutex_clocklock + * + * Description: + * This function attempts to lock the mutex referenced by 'mutex'. If the + * mutex value is (<=) zero, then the calling task will not return until it + * successfully acquires the lock or timed out + * + * Input Parameters: + * mutex - Mutex object + * clockid - The clock to be used as the time base + * abstime - The absolute time when the mutex lock timed out + * + * Returned Value: + * OK The mutex successfully acquires + * EINVAL The mutex argument does not refer to a valid mutex. Or the + * thread would have blocked, and the abstime parameter specified + * a nanoseconds field value less than zero or greater than or + * equal to 1000 million. + * ETIMEDOUT The mutex could not be locked before the specified timeout + * expired. + * EDEADLK A deadlock condition was detected. + * + ****************************************************************************/ + +int nxmutex_clocklock(FAR mutex_t *mutex, clockid_t clockid, + FAR const struct timespec *abstime) +{ + int ret; + + /* Wait until we get the lock or until the timeout expires */ + + do + { + ret = nxsem_clockwait(&mutex->sem, clockid, abstime); + } + while (ret == -EINTR || ret == -ECANCELED); + + if (ret >= 0) + { + mutex->holder = _SCHED_GETTID(); + } + + return ret; +} + /**************************************************************************** * Name: nxmutex_timedlock * @@ -277,7 +341,6 @@ int nxmutex_trylock(FAR mutex_t *mutex) int nxmutex_timedlock(FAR mutex_t *mutex, unsigned int timeout) { - int ret; struct timespec now; struct timespec delay; struct timespec rqtp; @@ -288,18 +351,7 @@ int nxmutex_timedlock(FAR mutex_t *mutex, unsigned int timeout) /* Wait until we get the lock or until the timeout expires */ - do - { - ret = nxsem_clockwait(&mutex->sem, CLOCK_MONOTONIC, &rqtp); - } - while (ret == -EINTR || ret == -ECANCELED); - - if (ret >= 0) - { - mutex->holder = _SCHED_GETTID(); - } - - return ret; + return nxmutex_clocklock(mutex, CLOCK_MONOTONIC, &rqtp); } /**************************************************************************** @@ -494,6 +546,24 @@ bool nxrmutex_is_hold(FAR rmutex_t *rmutex) return nxmutex_is_hold(&rmutex->mutex); } +/**************************************************************************** + * Name: nxrmutex_get_holder + * + * Description: + * This function get the holder of the mutex referenced by '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 * @@ -591,6 +661,50 @@ int nxrmutex_trylock(FAR rmutex_t *rmutex) return ret; } +/**************************************************************************** + * Name: nxrmutex_clocklock + * + * Description: + * This function attempts to lock the mutex referenced by 'mutex'. If the + * mutex value is (<=) zero, then the calling task will not return until it + * successfully acquires the lock or timed out + * + * Input Parameters: + * rmutex - Rmutex object + * clockid - The clock to be used as the time base + * abstime - The absolute time when the mutex lock timed out + * + * Returned Value: + * OK The mutex successfully acquires + * EINVAL The mutex argument does not refer to a valid mutex. Or the + * thread would have blocked, and the abstime parameter specified + * a nanoseconds field value less than zero or greater than or + * equal to 1000 million. + * ETIMEDOUT The mutex could not be locked before the specified timeout + * expired. + * EDEADLK A deadlock condition was detected. + * + ****************************************************************************/ + +int nxrmutex_clocklock(FAR rmutex_t *rmutex, clockid_t clockid, + FAR const struct timespec *abstime) +{ + int ret = OK; + + if (!nxrmutex_is_hold(rmutex)) + { + ret = nxmutex_clocklock(&rmutex->mutex, clockid, abstime); + } + + if (ret >= 0) + { + DEBUGASSERT(rmutex->count < UINT_MAX); + ++rmutex->count; + } + + return ret; +} + /**************************************************************************** * Name: nxrmutex_timedlock *