Merged in leif_jakob/nuttx/pthread_mutex_timedlock (pull request #830)
support for pthread_mutex_timedlock Approved-by: Gregory Nutt <gnutt@nuttx.org>
This commit is contained in:
parent
0523e8a1d0
commit
58e387fc6f
@ -539,6 +539,8 @@ int pthread_mutex_init(FAR pthread_mutex_t *mutex,
|
|||||||
FAR const pthread_mutexattr_t *attr);
|
FAR const pthread_mutexattr_t *attr);
|
||||||
int pthread_mutex_destroy(FAR pthread_mutex_t *mutex);
|
int pthread_mutex_destroy(FAR pthread_mutex_t *mutex);
|
||||||
int pthread_mutex_lock(FAR pthread_mutex_t *mutex);
|
int pthread_mutex_lock(FAR pthread_mutex_t *mutex);
|
||||||
|
int pthread_mutex_timedlock(FAR pthread_mutex_t *mutex,
|
||||||
|
FAR const struct timespec *abs_timeout);
|
||||||
int pthread_mutex_trylock(FAR pthread_mutex_t *mutex);
|
int pthread_mutex_trylock(FAR pthread_mutex_t *mutex);
|
||||||
int pthread_mutex_unlock(FAR pthread_mutex_t *mutex);
|
int pthread_mutex_unlock(FAR pthread_mutex_t *mutex);
|
||||||
|
|
||||||
|
@ -108,21 +108,21 @@ FAR struct join_s *pthread_findjoininfo(FAR struct task_group_s *group,
|
|||||||
pid_t pid);
|
pid_t pid);
|
||||||
void pthread_release(FAR struct task_group_s *group);
|
void pthread_release(FAR struct task_group_s *group);
|
||||||
|
|
||||||
int pthread_sem_take(sem_t *sem, bool intr);
|
int pthread_sem_take(sem_t *sem, FAR const struct timespec *abs_timeout, bool intr);
|
||||||
#ifdef CONFIG_PTHREAD_MUTEX_UNSAFE
|
#ifdef CONFIG_PTHREAD_MUTEX_UNSAFE
|
||||||
int pthread_sem_trytake(sem_t *sem);
|
int pthread_sem_trytake(sem_t *sem);
|
||||||
#endif
|
#endif
|
||||||
int pthread_sem_give(sem_t *sem);
|
int pthread_sem_give(sem_t *sem);
|
||||||
|
|
||||||
#ifndef CONFIG_PTHREAD_MUTEX_UNSAFE
|
#ifndef CONFIG_PTHREAD_MUTEX_UNSAFE
|
||||||
int pthread_mutex_take(FAR struct pthread_mutex_s *mutex, bool intr);
|
int pthread_mutex_take(FAR struct pthread_mutex_s *mutex, FAR const struct timespec *abs_timeout, bool intr);
|
||||||
int pthread_mutex_trytake(FAR struct pthread_mutex_s *mutex);
|
int pthread_mutex_trytake(FAR struct pthread_mutex_s *mutex);
|
||||||
int pthread_mutex_give(FAR struct pthread_mutex_s *mutex);
|
int pthread_mutex_give(FAR struct pthread_mutex_s *mutex);
|
||||||
void pthread_mutex_inconsistent(FAR struct pthread_tcb_s *tcb);
|
void pthread_mutex_inconsistent(FAR struct pthread_tcb_s *tcb);
|
||||||
#else
|
#else
|
||||||
# define pthread_mutex_take(m,i) pthread_sem_take(&(m)->sem,(i))
|
# define pthread_mutex_take(m,abs_timeout,i) pthread_sem_take(&(m)->sem,(abs_timeout),(i))
|
||||||
# define pthread_mutex_trytake(m) pthread_sem_trytake(&(m)->sem)
|
# define pthread_mutex_trytake(m) pthread_sem_trytake(&(m)->sem)
|
||||||
# define pthread_mutex_give(m) pthread_sem_give(&(m)->sem)
|
# define pthread_mutex_give(m) pthread_sem_give(&(m)->sem)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_PTHREAD_MUTEX_TYPES
|
#ifdef CONFIG_PTHREAD_MUTEX_TYPES
|
||||||
|
@ -99,7 +99,7 @@ static bool pthread_notifywaiters(FAR struct join_s *pjoin)
|
|||||||
* value.
|
* value.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
(void)pthread_sem_take(&pjoin->data_sem, false);
|
(void)pthread_sem_take(&pjoin->data_sem, NULL, false);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -210,7 +210,7 @@ int pthread_completejoin(pid_t pid, FAR void *exit_value)
|
|||||||
|
|
||||||
/* First, find thread's structure in the private data set. */
|
/* First, find thread's structure in the private data set. */
|
||||||
|
|
||||||
(void)pthread_sem_take(&group->tg_joinsem, false);
|
(void)pthread_sem_take(&group->tg_joinsem, NULL, false);
|
||||||
pjoin = pthread_findjoininfo(group, pid);
|
pjoin = pthread_findjoininfo(group, pid);
|
||||||
if (!pjoin)
|
if (!pjoin)
|
||||||
{
|
{
|
||||||
|
@ -320,7 +320,7 @@ int pthread_cond_timedwait(FAR pthread_cond_t *cond, FAR pthread_mutex_t *mutex,
|
|||||||
|
|
||||||
sinfo("Re-locking...\n");
|
sinfo("Re-locking...\n");
|
||||||
|
|
||||||
status = pthread_mutex_take(mutex, false);
|
status = pthread_mutex_take(mutex, NULL, false);
|
||||||
if (status == OK)
|
if (status == OK)
|
||||||
{
|
{
|
||||||
mutex->pid = mypid;
|
mutex->pid = mypid;
|
||||||
|
@ -105,7 +105,7 @@ int pthread_cond_wait(FAR pthread_cond_t *cond, FAR pthread_mutex_t *mutex)
|
|||||||
|
|
||||||
/* Take the semaphore */
|
/* Take the semaphore */
|
||||||
|
|
||||||
status = pthread_sem_take((FAR sem_t *)&cond->sem, false);
|
status = pthread_sem_take((FAR sem_t *)&cond->sem, NULL, false);
|
||||||
if (ret == OK)
|
if (ret == OK)
|
||||||
{
|
{
|
||||||
/* Report the first failure that occurs */
|
/* Report the first failure that occurs */
|
||||||
@ -124,7 +124,7 @@ int pthread_cond_wait(FAR pthread_cond_t *cond, FAR pthread_mutex_t *mutex)
|
|||||||
|
|
||||||
sinfo("Reacquire mutex...\n");
|
sinfo("Reacquire mutex...\n");
|
||||||
|
|
||||||
status = pthread_mutex_take(mutex, false);
|
status = pthread_mutex_take(mutex, NULL, false);
|
||||||
if (ret == OK)
|
if (ret == OK)
|
||||||
{
|
{
|
||||||
/* Report the first failure that occurs */
|
/* Report the first failure that occurs */
|
||||||
|
@ -179,7 +179,7 @@ static void pthread_start(void)
|
|||||||
|
|
||||||
/* Successfully spawned, add the pjoin to our data set. */
|
/* Successfully spawned, add the pjoin to our data set. */
|
||||||
|
|
||||||
(void)pthread_sem_take(&group->tg_joinsem, false);
|
(void)pthread_sem_take(&group->tg_joinsem, NULL, false);
|
||||||
pthread_addjoininfo(group, pjoin);
|
pthread_addjoininfo(group, pjoin);
|
||||||
(void)pthread_sem_give(&group->tg_joinsem);
|
(void)pthread_sem_give(&group->tg_joinsem);
|
||||||
|
|
||||||
@ -580,7 +580,7 @@ int pthread_create(FAR pthread_t *thread, FAR const pthread_attr_t *attr,
|
|||||||
* its join structure.
|
* its join structure.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
(void)pthread_sem_take(&pjoin->data_sem, false);
|
(void)pthread_sem_take(&pjoin->data_sem, NULL, false);
|
||||||
|
|
||||||
/* Return the thread information to the caller */
|
/* Return the thread information to the caller */
|
||||||
|
|
||||||
|
@ -87,7 +87,7 @@ int pthread_detach(pthread_t thread)
|
|||||||
|
|
||||||
/* Find the entry associated with this pthread. */
|
/* Find the entry associated with this pthread. */
|
||||||
|
|
||||||
(void)pthread_sem_take(&group->tg_joinsem, false);
|
(void)pthread_sem_take(&group->tg_joinsem, NULL, false);
|
||||||
pjoin = pthread_findjoininfo(group, (pid_t)thread);
|
pjoin = pthread_findjoininfo(group, (pid_t)thread);
|
||||||
if (!pjoin)
|
if (!pjoin)
|
||||||
{
|
{
|
||||||
|
@ -97,7 +97,7 @@ void pthread_initialize(void)
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
int pthread_sem_take(sem_t *sem, bool intr)
|
int pthread_sem_take(sem_t *sem, FAR const struct timespec *abs_timeout, bool intr)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@ -110,7 +110,15 @@ int pthread_sem_take(sem_t *sem, bool intr)
|
|||||||
{
|
{
|
||||||
/* Take the semaphore (perhaps waiting) */
|
/* Take the semaphore (perhaps waiting) */
|
||||||
|
|
||||||
ret = nxsem_wait(sem);
|
if ( abs_timeout == NULL )
|
||||||
|
{
|
||||||
|
ret = nxsem_wait(sem);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ret = nxsem_timedwait(sem, abs_timeout);
|
||||||
|
}
|
||||||
|
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
/* The only cases that an error should occur here is if the wait
|
/* The only cases that an error should occur here is if the wait
|
||||||
@ -118,7 +126,7 @@ int pthread_sem_take(sem_t *sem, bool intr)
|
|||||||
* the wait.
|
* the wait.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
DEBUGASSERT(ret == -EINTR || ret == -ECANCELED);
|
DEBUGASSERT(ret == -EINTR || ret == -ECANCELED || ret == -ETIMEDOUT);
|
||||||
|
|
||||||
/* When the error occurs in this case, should we errout? Or
|
/* When the error occurs in this case, should we errout? Or
|
||||||
* should we just continue waiting until we have the
|
* should we just continue waiting until we have the
|
||||||
|
@ -114,7 +114,7 @@ int pthread_join(pthread_t thread, FAR pthread_addr_t *pexit_value)
|
|||||||
* because it will also attempt to get this semaphore.
|
* because it will also attempt to get this semaphore.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
(void)pthread_sem_take(&group->tg_joinsem, false);
|
(void)pthread_sem_take(&group->tg_joinsem, NULL, false);
|
||||||
|
|
||||||
/* Find the join information associated with this thread.
|
/* Find the join information associated with this thread.
|
||||||
* This can fail for one of three reasons: (1) There is no
|
* This can fail for one of three reasons: (1) There is no
|
||||||
@ -197,7 +197,7 @@ int pthread_join(pthread_t thread, FAR pthread_addr_t *pexit_value)
|
|||||||
* pthread to exit.
|
* pthread to exit.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
(void)pthread_sem_take(&pjoin->exit_sem, false);
|
(void)pthread_sem_take(&pjoin->exit_sem, NULL, false);
|
||||||
|
|
||||||
/* The thread has exited! Get the thread exit value */
|
/* The thread has exited! Get the thread exit value */
|
||||||
|
|
||||||
@ -217,7 +217,7 @@ int pthread_join(pthread_t thread, FAR pthread_addr_t *pexit_value)
|
|||||||
* pthread_destroyjoin is called.
|
* pthread_destroyjoin is called.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
(void)pthread_sem_take(&group->tg_joinsem, false);
|
(void)pthread_sem_take(&group->tg_joinsem, NULL, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Pre-emption is okay now. The logic still cannot be re-entered
|
/* Pre-emption is okay now. The logic still cannot be re-entered
|
||||||
|
@ -177,7 +177,7 @@ static void pthread_mutex_remove(FAR struct pthread_mutex_s *mutex)
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
int pthread_mutex_take(FAR struct pthread_mutex_s *mutex, bool intr)
|
int pthread_mutex_take(FAR struct pthread_mutex_s *mutex, FAR const struct timespec *abs_timeout, bool intr)
|
||||||
{
|
{
|
||||||
int ret = EINVAL;
|
int ret = EINVAL;
|
||||||
|
|
||||||
@ -202,7 +202,7 @@ int pthread_mutex_take(FAR struct pthread_mutex_s *mutex, bool intr)
|
|||||||
* returns zero on success and a positive errno value on failure.
|
* returns zero on success and a positive errno value on failure.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ret = pthread_sem_take(&mutex->sem, intr);
|
ret = pthread_sem_take(&mutex->sem, abs_timeout, intr);
|
||||||
if (ret == OK)
|
if (ret == OK)
|
||||||
{
|
{
|
||||||
/* Check if the holder of the mutex has terminated without
|
/* Check if the holder of the mutex has terminated without
|
||||||
|
@ -103,8 +103,48 @@
|
|||||||
* been exceeded.
|
* been exceeded.
|
||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
int pthread_mutex_lock(FAR pthread_mutex_t *mutex)
|
int pthread_mutex_lock(FAR pthread_mutex_t *mutex)
|
||||||
|
{
|
||||||
|
return pthread_mutex_timedlock(mutex, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: pthread_mutex_timedlock
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* The pthread_mutex_timedlock() function shall lock the mutex object
|
||||||
|
* referenced by mutex. If the mutex is already locked, the calling
|
||||||
|
* thread shall block until the mutex becomes available as in the
|
||||||
|
* pthread_mutex_lock() function. If the mutex cannot be locked without
|
||||||
|
* waiting for another thread to unlock the mutex, this wait shall be
|
||||||
|
* terminated when the specified timeout expires.
|
||||||
|
*
|
||||||
|
* The timeout shall expire when the absolute time specified by
|
||||||
|
* abs_timeout passes, as measured by the clock on which timeouts are
|
||||||
|
* based (that is, when the value of that clock equals or exceeds
|
||||||
|
* abs_timeout), or if the absolute time specified by abs_timeout
|
||||||
|
* has already been passed at the time of the call.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* mutex - A reference to the mutex to be locked.
|
||||||
|
* abs_timeout - max wait time (NULL wait forever)
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* 0 on success or an errno value on failure. Note that the errno EINTR
|
||||||
|
* is never returned by pthread_mutex_lock().
|
||||||
|
* errno is ETIMEDOUT if mutex could not be locked before the specified
|
||||||
|
* timeout expired
|
||||||
|
*
|
||||||
|
* Assumptions:
|
||||||
|
*
|
||||||
|
* POSIX Compatibility:
|
||||||
|
* - This implementation does not return EAGAIN when the mutex could not be
|
||||||
|
* acquired because the maximum number of recursive locks for mutex has
|
||||||
|
* been exceeded.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
int pthread_mutex_timedlock(FAR pthread_mutex_t *restrict mutex,
|
||||||
|
FAR const struct timespec *abs_timeout)
|
||||||
{
|
{
|
||||||
int mypid = (int)getpid();
|
int mypid = (int)getpid();
|
||||||
int ret = EINVAL;
|
int ret = EINVAL;
|
||||||
@ -215,7 +255,7 @@ int pthread_mutex_lock(FAR pthread_mutex_t *mutex)
|
|||||||
* default mutex.
|
* default mutex.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ret = pthread_mutex_take(mutex, true);
|
ret = pthread_mutex_take(mutex, NULL, true);
|
||||||
|
|
||||||
/* If we successfully obtained the semaphore, then indicate
|
/* If we successfully obtained the semaphore, then indicate
|
||||||
* that we own it.
|
* that we own it.
|
||||||
|
Loading…
Reference in New Issue
Block a user