This is an automated email from the ASF dual-hosted git repository. xiaoxiang pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit 01864d262c80e4c0abb53094a4e7105fa6fc0f43 Author: yinshengkai <[email protected]> AuthorDate: Mon May 6 15:54:51 2024 +0800 sched: add mutex_holder and mutex_clocklock API Signed-off-by: yinshengkai <[email protected]> --- include/nuttx/mutex.h | 86 ++++++++++++++++++++++++++++ libs/libc/misc/lib_mutex.c | 140 ++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 213 insertions(+), 13 deletions(-) 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 * @@ -252,16 +270,17 @@ int nxmutex_trylock(FAR mutex_t *mutex) } /**************************************************************************** - * Name: nxmutex_timedlock + * Name: nxmutex_clocklock * * Description: - * This function attempts to lock the mutex . If the mutex value - * is (<=) zero,then the calling task will not return until it + * 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 - * timeout - The time when mutex lock timed out + * 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 @@ -275,22 +294,16 @@ int nxmutex_trylock(FAR mutex_t *mutex) * ****************************************************************************/ -int nxmutex_timedlock(FAR mutex_t *mutex, unsigned int timeout) +int nxmutex_clocklock(FAR mutex_t *mutex, clockid_t clockid, + FAR const struct timespec *abstime) { int ret; - struct timespec now; - struct timespec delay; - struct timespec rqtp; - - clock_gettime(CLOCK_MONOTONIC, &now); - clock_ticks2time(MSEC2TICK(timeout), &delay); - clock_timespec_add(&now, &delay, &rqtp); /* Wait until we get the lock or until the timeout expires */ do { - ret = nxsem_clockwait(&mutex->sem, CLOCK_MONOTONIC, &rqtp); + ret = nxsem_clockwait(&mutex->sem, clockid, abstime); } while (ret == -EINTR || ret == -ECANCELED); @@ -302,6 +315,45 @@ int nxmutex_timedlock(FAR mutex_t *mutex, unsigned int timeout) return ret; } +/**************************************************************************** + * Name: nxmutex_timedlock + * + * Description: + * This function attempts to lock the 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 + * timeout - The time when 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_timedlock(FAR mutex_t *mutex, unsigned int timeout) +{ + struct timespec now; + struct timespec delay; + struct timespec rqtp; + + clock_gettime(CLOCK_MONOTONIC, &now); + clock_ticks2time(MSEC2TICK(timeout), &delay); + clock_timespec_add(&now, &delay, &rqtp); + + /* Wait until we get the lock or until the timeout expires */ + + return nxmutex_clocklock(mutex, CLOCK_MONOTONIC, &rqtp); +} + /**************************************************************************** * Name: nxmutex_unlock * @@ -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 *
