sched: add mutex_holder and mutex_clocklock API

Signed-off-by: yinshengkai <yinshengkai@xiaomi.com>
This commit is contained in:
yinshengkai 2024-05-06 15:54:51 +08:00 committed by Xiang Xiao
parent 4af6db7c80
commit 01864d262c
2 changed files with 213 additions and 13 deletions

View File

@ -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
*

View File

@ -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
*