diff --git a/Documentation/NuttxUserGuide.html b/Documentation/NuttxUserGuide.html index da5473da8e3..e6bab2cf571 100644 --- a/Documentation/NuttxUserGuide.html +++ b/Documentation/NuttxUserGuide.html @@ -13,7 +13,7 @@

NuttX Operating System

User's Manual

by

Gregory Nutt

-

Last Updated: July 15, 2018

+

Last Updated: February 24, 20189

@@ -5823,8 +5823,9 @@ be sent.
  • 2.8.37 pthread_mutex_init
  • 2.8.38 pthread_mutex_destroy
  • 2.8.39 pthread_mutex_lock
  • -
  • 2.8.40 pthread_mutex_trylock
  • -
  • 2.8.41 pthread_mutex_unlock
  • +
  • 2.8.40 pthread_mutex_timedlock
  • +
  • 2.8.41 pthread_mutex_trylock
  • +
  • 2.8.42 pthread_mutex_unlock
  • Condition Variables. @@ -7432,7 +7433,47 @@ Otherwise, an error number will be returned to indicate the error: POSIX Compatibility: Comparable to the POSIX interface of the same name. -

    2.8.40 pthread_mutex_trylock

    +

    2.8.40 pthread_mutex_timedlock

    +

    +Function Prototype: +

    +

    +    #include <pthread.h>
    +    int pthread_mutex_timedlock(pthread_mutex_t *mutex, const struct timespec *abs_timeout);
    +
    +

    +Description: + The pthread_mutex_timedlock() function will lock the mutex object referenced by mutex. + If the mutex is already locked, the calling thread will 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 will be terminated when the specified abs_timeout expires. +

    +

    + The timeout will 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: +

    +

    +

    +Returned Value: +

    +If successful, the pthread_mutex_trylock() function will return zero (OK). +Otherwise, an error number will be returned to indicate the error. +Note that the errno EINTR is never returned by pthread_mutex_timedlock(). +The returned errno is ETIMEDOUT if the mutex could not be locked before the specified timeout expired +

    +

    +Assumptions/Limitations: +

    +POSIX Compatibility: + Comparable to the POSIX interface of the same name. + 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. +

    + +

    2.8.41 pthread_mutex_trylock

    Function Prototype:

    @@ -7442,7 +7483,7 @@ interface of the same name.

    Description: - The function pthread_mutex_trylock() is identical to pthread_mutex_lock() + The function pthread_mutex_trylock() is identical to pthread_mutex_lock() except that if the mutex object referenced by mutex is currently locked (by any thread, including the current thread), the call returns immediately with the errno EBUSY. @@ -7472,7 +7513,7 @@ Otherwise, an error number will be returned to indicate the error: POSIX Compatibility: Comparable to the POSIX interface of the same name. -

    2.8.41 pthread_mutex_unlock

    +

    2.8.42 pthread_mutex_unlock

    Function Prototype:

    @@ -10581,6 +10622,7 @@ notify a task when a message is available on a queue.

  • pthread_mutex_destroy
  • pthread_mutex_init
  • pthread_mutex_lock
  • +
  • pthread_mutex_timedlock
  • pthread_mutex_trylock
  • pthread_mutex_unlock
  • pthread_condattr_destroy
  • diff --git a/include/pthread.h b/include/pthread.h index 2c8ba39e9c3..188de4967c2 100644 --- a/include/pthread.h +++ b/include/pthread.h @@ -1,7 +1,8 @@ /******************************************************************************** * include/pthread.h * - * Copyright (C) 2007-2009, 2011-2012, 2015-2017 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2009, 2011-2012, 2015-2017, 2019 Gregory Nutt. All + * rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -77,23 +78,26 @@ * * PTHREAD_MUTEX_NORMAL: This type of mutex does not detect deadlock. A thread * attempting to relock this mutex without first unlocking it will deadlock. - * Attempting to unlock a mutex locked by a different thread results in undefined - * behavior. Attempting to unlock an unlocked mutex results in undefined behavior. + * Attempting to unlock a mutex locked by a different thread results in + * undefined behavior. Attempting to unlock an unlocked mutex results in + * undefined behavior. * PTHREAD_MUTEX_ERRORCHECK - * This type of mutex provides error checking. A thread attempting to relock this - * mutex without first unlocking it will return with an error. A thread attempting - * to unlock a mutex which another thread has locked will return with an error. A - * thread attempting to unlock an unlocked mutex will return with an error. + * This type of mutex provides error checking. A thread attempting to relock + * this mutex without first unlocking it will return with an error. A thread + * attempting to unlock a mutex which another thread has locked will return + * with an error. A thread attempting to unlock an unlocked mutex will return + * with an error. * PTHREAD_MUTEX_RECURSIVE - * A thread attempting to relock this mutex without first unlocking it will succeed - * in locking the mutex. The relocking deadlock which can occur with mutexes of type - * PTHREAD_MUTEX_NORMAL cannot occur with this type of mutex. Multiple locks of this - * mutex require the same number of unlocks to release the mutex before another thread - * can acquire the mutex. A thread attempting to unlock a mutex which another thread - * has locked will return with an error. A thread attempting to unlock an unlocked - * mutex will return with an error. + * A thread attempting to relock this mutex without first unlocking it will + * succeed in locking the mutex. The relocking deadlock which can occur with + * mutexes of type PTHREAD_MUTEX_NORMAL cannot occur with this type of mutex. + * Multiple locks of this mutex require the same number of unlocks to release + * the mutex before another thread can acquire the mutex. A thread attempting + * to unlock a mutex which another thread has locked will return with an error. + * A thread attempting to unlock an unlocked mutex will return with an error. * PTHREAD_MUTEX_DEFAULT - * An implementation is allowed to map this mutex to one of the other mutex types. + * An implementation is allowed to map this mutex to one of the other mutex + * types. */ #define PTHREAD_MUTEX_NORMAL 0 @@ -509,7 +513,7 @@ int pthread_getaffinity_np(pthread_t thread, size_t cpusetsize, /* Thread-specific Data Interfaces */ int pthread_key_create(FAR pthread_key_t *key, - CODE void (*destructor)(FAR void*)); + CODE void (*destructor)(FAR void *)); int pthread_setspecific(pthread_key_t key, FAR const void *value); FAR void *pthread_getspecific(pthread_key_t key); int pthread_key_delete(pthread_key_t key); @@ -540,7 +544,7 @@ int pthread_mutex_init(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_timedlock(FAR pthread_mutex_t *mutex, - FAR const struct timespec *abs_timeout); + FAR const struct timespec *abs_timeout); int pthread_mutex_trylock(FAR pthread_mutex_t *mutex); int pthread_mutex_unlock(FAR pthread_mutex_t *mutex); @@ -557,7 +561,8 @@ int pthread_condattr_destroy(FAR pthread_condattr_t *attr); /* A thread can create and delete condition variables. */ -int pthread_cond_init(FAR pthread_cond_t *cond, FAR const pthread_condattr_t *attr); +int pthread_cond_init(FAR pthread_cond_t *cond, + FAR const pthread_condattr_t *attr); int pthread_cond_destroy(FAR pthread_cond_t *cond); /* A thread can signal to and broadcast on a condition variable. */ diff --git a/sched/pthread/pthread.h b/sched/pthread/pthread.h index 0e71fd6d6ea..57f15e0d92a 100644 --- a/sched/pthread/pthread.h +++ b/sched/pthread/pthread.h @@ -1,7 +1,8 @@ /**************************************************************************** * sched/pthread/pthread.h * - * Copyright (C) 2007-2009, 2011, 2013-2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2009, 2011, 2013-2014, 2019 Gregory Nutt. All rights + * reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -94,8 +95,8 @@ struct pthread_tcb_s; /* Forward reference */ struct task_group_s; /* Forward reference */ void weak_function pthread_initialize(void); -int pthread_schedsetup(FAR struct pthread_tcb_s *tcb, int priority, start_t start, - pthread_startroutine_t entry); +int pthread_schedsetup(FAR struct pthread_tcb_s *tcb, int priority, + start_t start, pthread_startroutine_t entry); #ifdef CONFIG_PTHREAD_CLEANUP void pthread_cleanup_popall(FAR struct pthread_tcb_s *tcb); @@ -108,14 +109,16 @@ FAR struct join_s *pthread_findjoininfo(FAR struct task_group_s *group, pid_t pid); void pthread_release(FAR struct task_group_s *group); -int pthread_sem_take(sem_t *sem, FAR const struct timespec *abs_timeout, bool intr); +int pthread_sem_take(FAR sem_t *sem, FAR const struct timespec *abs_timeout, + bool intr); #ifdef CONFIG_PTHREAD_MUTEX_UNSAFE int pthread_sem_trytake(sem_t *sem); #endif int pthread_sem_give(sem_t *sem); #ifndef CONFIG_PTHREAD_MUTEX_UNSAFE -int pthread_mutex_take(FAR struct pthread_mutex_s *mutex, FAR const struct timespec *abs_timeout, 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_give(FAR struct pthread_mutex_s *mutex); void pthread_mutex_inconsistent(FAR struct pthread_tcb_s *tcb); @@ -135,4 +138,3 @@ int pthread_mutexattr_verifytype(int type); #endif #endif /* __SCHED_PTHREAD_PTHREAD_H */ - diff --git a/sched/pthread/pthread_initialize.c b/sched/pthread/pthread_initialize.c index 84f641d4bb9..2c8f267c94f 100644 --- a/sched/pthread/pthread_initialize.c +++ b/sched/pthread/pthread_initialize.c @@ -1,7 +1,7 @@ /**************************************************************************** * sched/pthread/pthread_initialize.c * - * Copyright (C) 2007-2010, 2013, 2017-2018 Gregory Nutt. All rights + * Copyright (C) 2007-2010, 2013, 2017-2019 Gregory Nutt. All rights * reserved. * Author: Gregory Nutt * @@ -97,7 +97,8 @@ void pthread_initialize(void) * ****************************************************************************/ -int pthread_sem_take(sem_t *sem, FAR const struct timespec *abs_timeout, bool intr) +int pthread_sem_take(FAR sem_t *sem, FAR const struct timespec *abs_timeout, + bool intr) { int ret; @@ -110,14 +111,14 @@ int pthread_sem_take(sem_t *sem, FAR const struct timespec *abs_timeout, bool in { /* Take the semaphore (perhaps waiting) */ - if ( abs_timeout == NULL ) - { - ret = nxsem_wait(sem); - } - else - { - ret = nxsem_timedwait(sem, abs_timeout); - } + if (abs_timeout == NULL) + { + ret = nxsem_wait(sem); + } + else + { + ret = nxsem_timedwait(sem, abs_timeout); + } if (ret < 0) { @@ -126,7 +127,8 @@ int pthread_sem_take(sem_t *sem, FAR const struct timespec *abs_timeout, bool in * the wait. */ - DEBUGASSERT(ret == -EINTR || ret == -ECANCELED || ret == -ETIMEDOUT); + DEBUGASSERT(ret == -EINTR || ret == -ECANCELED || + ret == -ETIMEDOUT); /* When the error occurs in this case, should we errout? Or * should we just continue waiting until we have the diff --git a/sched/pthread/pthread_mutex.c b/sched/pthread/pthread_mutex.c index 420d0b1a7b4..a81a00abd82 100644 --- a/sched/pthread/pthread_mutex.c +++ b/sched/pthread/pthread_mutex.c @@ -1,7 +1,7 @@ /**************************************************************************** * sched/pthread/pthread_mutex.c * - * Copyright (C) 2017 Gregory Nutt. All rights reserved. + * Copyright (C) 2017, 2019 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -177,7 +177,8 @@ static void pthread_mutex_remove(FAR struct pthread_mutex_s *mutex) * ****************************************************************************/ -int pthread_mutex_take(FAR struct pthread_mutex_s *mutex, FAR const struct timespec *abs_timeout, bool intr) +int pthread_mutex_take(FAR struct pthread_mutex_s *mutex, + FAR const struct timespec *abs_timeout, bool intr) { int ret = EINVAL; diff --git a/sched/pthread/pthread_mutexlock.c b/sched/pthread/pthread_mutexlock.c index af107fbf01e..8571c065efa 100644 --- a/sched/pthread/pthread_mutexlock.c +++ b/sched/pthread/pthread_mutexlock.c @@ -1,7 +1,7 @@ /**************************************************************************** * sched/pthread/pthread_mutexlock.c * - * Copyright (C) 2007-2009, 2017 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2009, 2017, 2019 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -103,48 +103,50 @@ * been exceeded. * ****************************************************************************/ + int pthread_mutex_lock(FAR pthread_mutex_t *mutex) { - return pthread_mutex_timedlock(mutex, NULL); + 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) +/**************************************************************************** + * Name: pthread_mutex_timedlock + * + * Description: + * The pthread_mutex_timedlock() function will lock the mutex object + * referenced by mutex. If the mutex is already locked, the calling + * thread will 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 will be + * terminated when the specified timeout expires. + * + * The timeout will 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_timedlock(). + * 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 *mutex, + FAR const struct timespec *abs_timeout) { int mypid = (int)getpid(); int ret = EINVAL; @@ -205,70 +207,70 @@ int pthread_mutex_timedlock(FAR pthread_mutex_t *restrict mutex, #endif /* CONFIG_PTHREAD_MUTEX_TYPES */ #ifndef CONFIG_PTHREAD_MUTEX_UNSAFE - /* The calling thread does not hold the semaphore. The correct - * behavior for the 'robust' mutex is to verify that the holder of the - * mutex is still valid. This is protection from the case - * where the holder of the mutex has exitted without unlocking it. - */ + /* The calling thread does not hold the semaphore. The correct + * behavior for the 'robust' mutex is to verify that the holder of the + * mutex is still valid. This is protection from the case + * where the holder of the mutex has exitted without unlocking it. + */ #ifdef CONFIG_PTHREAD_MUTEX_BOTH #ifdef CONFIG_PTHREAD_MUTEX_TYPES - /* Include check if this is a NORMAL mutex and that it is robust */ + /* Include check if this is a NORMAL mutex and that it is robust */ - if (mutex->pid > 0 && - ((mutex->flags & _PTHREAD_MFLAGS_ROBUST) != 0 || - mutex->type != PTHREAD_MUTEX_NORMAL) && - sched_gettcb(mutex->pid) == NULL) + if (mutex->pid > 0 && + ((mutex->flags & _PTHREAD_MFLAGS_ROBUST) != 0 || + mutex->type != PTHREAD_MUTEX_NORMAL) && + sched_gettcb(mutex->pid) == NULL) #else /* CONFIG_PTHREAD_MUTEX_TYPES */ - /* This can only be a NORMAL mutex. Include check if it is robust */ + /* This can only be a NORMAL mutex. Include check if it is robust */ - if (mutex->pid > 0 && - (mutex->flags & _PTHREAD_MFLAGS_ROBUST) != 0 && - sched_gettcb(mutex->pid) == NULL) + if (mutex->pid > 0 && + (mutex->flags & _PTHREAD_MFLAGS_ROBUST) != 0 && + sched_gettcb(mutex->pid) == NULL) #endif /* CONFIG_PTHREAD_MUTEX_TYPES */ #else /* CONFIG_PTHREAD_MUTEX_ROBUST */ - /* This mutex is always robust, whatever type it is. */ + /* This mutex is always robust, whatever type it is. */ - if (mutex->pid > 0 && sched_gettcb(mutex->pid) == NULL) + if (mutex->pid > 0 && sched_gettcb(mutex->pid) == NULL) #endif - { - DEBUGASSERT(mutex->pid != 0); /* < 0: available, >0 owned, ==0 error */ - DEBUGASSERT((mutex->flags & _PTHREAD_MFLAGS_INCONSISTENT) != 0); + { + DEBUGASSERT(mutex->pid != 0); /* < 0: available, >0 owned, ==0 error */ + DEBUGASSERT((mutex->flags & _PTHREAD_MFLAGS_INCONSISTENT) != 0); - /* A thread holds the mutex, but there is no such thread. POSIX - * requires that the 'robust' mutex return EOWNERDEAD in this case. - * It is then the caller's responsibility to call pthread_mutx_consistent() - * fo fix the mutex. - */ + /* A thread holds the mutex, but there is no such thread. POSIX + * requires that the 'robust' mutex return EOWNERDEAD in this + * case. It is then the caller's responsibility to call + * pthread_mutx_consistent() to fix the mutex. + */ - mutex->flags |= _PTHREAD_MFLAGS_INCONSISTENT; - ret = EOWNERDEAD; - } - else + mutex->flags |= _PTHREAD_MFLAGS_INCONSISTENT; + ret = EOWNERDEAD; + } + else #endif /* !CONFIG_PTHREAD_MUTEX_UNSAFE */ - { - /* Take the underlying semaphore, waiting if necessary. NOTE that - * is required to deadlock for the case of the non-robust NORMAL or - * default mutex. - */ + { + /* Take the underlying semaphore, waiting if necessary. NOTE that + * is required to deadlock for the case of the non-robust NORMAL + * or default mutex. + */ - ret = pthread_mutex_take(mutex, NULL, true); + ret = pthread_mutex_take(mutex, NULL, true); - /* If we successfully obtained the semaphore, then indicate - * that we own it. - */ + /* If we successfully obtained the semaphore, then indicate + * that we own it. + */ - if (ret == OK) - { - mutex->pid = mypid; + if (ret == OK) + { + mutex->pid = mypid; #ifdef CONFIG_PTHREAD_MUTEX_TYPES - mutex->nlocks = 1; + mutex->nlocks = 1; #endif - } - } + } + } sched_unlock(); }