diff --git a/include/pthread.h b/include/pthread.h index 99c5f6a21c..07ff707c1b 100644 --- a/include/pthread.h +++ b/include/pthread.h @@ -27,6 +27,7 @@ #include /* Default settings */ #include /* Compiler settings, noreturn_function */ +#include #include /* Needed for general types */ #include /* C99 fixed width integer types */ @@ -34,7 +35,6 @@ #include /* For getpid */ #include /* Needed for sigset_t, includes this file */ #include /* Needed for struct timespec */ -#include /* For sem_t and SEM_PRIO_* defines */ #ifdef CONFIG_PTHREAD_SPINLOCKS /* The architecture specific spinlock.h header file must provide the @@ -301,18 +301,16 @@ struct pthread_mutex_s /* Supports a singly linked list */ FAR struct pthread_mutex_s *flink; + uint8_t flags; /* See _PTHREAD_MFLAGS_* */ #endif /* Payload */ - sem_t sem; /* Semaphore underlying the implementation of the mutex */ - pid_t pid; /* ID of the holder of the mutex */ -#ifndef CONFIG_PTHREAD_MUTEX_UNSAFE - uint8_t flags; /* See _PTHREAD_MFLAGS_* */ -#endif #ifdef CONFIG_PTHREAD_MUTEX_TYPES uint8_t type; /* Type of the mutex. See PTHREAD_MUTEX_* definitions */ - int16_t nlocks; /* The number of recursive locks held */ + rmutex_t mutex; /* Mutex underlying the implementation of the mutex */ +#else + mutex_t mutex; /* Mutex underlying the implementation of the mutex */ #endif }; @@ -330,24 +328,24 @@ typedef struct pthread_mutex_s pthread_mutex_t; #endif #if defined(CONFIG_PTHREAD_MUTEX_TYPES) && !defined(CONFIG_PTHREAD_MUTEX_UNSAFE) -# define PTHREAD_MUTEX_INITIALIZER {NULL, SEM_INITIALIZER(1), -1, \ - __PTHREAD_MUTEX_DEFAULT_FLAGS, \ - PTHREAD_MUTEX_DEFAULT, 0} +# define PTHREAD_MUTEX_INITIALIZER {NULL, __PTHREAD_MUTEX_DEFAULT_FLAGS, \ + PTHREAD_MUTEX_DEFAULT, \ + NXRMUTEX_INITIALIZER} # define PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP \ - {NULL, SEM_INITIALIZER(1), -1, \ - __PTHREAD_MUTEX_DEFAULT_FLAGS, \ - PTHREAD_MUTEX_RECURSIVE, 0} + {NULL, __PTHREAD_MUTEX_DEFAULT_FLAGS, \ + PTHREAD_MUTEX_RECURSIVE, \ + NXRMUTEX_INITIALIZER,} #elif defined(CONFIG_PTHREAD_MUTEX_TYPES) -# define PTHREAD_MUTEX_INITIALIZER {SEM_INITIALIZER(1), -1, \ - PTHREAD_MUTEX_DEFAULT, 0} +# define PTHREAD_MUTEX_INITIALIZER {PTHREAD_MUTEX_DEFAULT, \ + NXRMUTEX_INITIALIZER,} # define PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP \ - {SEM_INITIALIZER(1), -1, \ - PTHREAD_MUTEX_RECURSIVE, 0} + {PTHREAD_MUTEX_RECURSIVE, \ + NXRMUTEX_INITIALIZER} #elif !defined(CONFIG_PTHREAD_MUTEX_UNSAFE) -# define PTHREAD_MUTEX_INITIALIZER {NULL, SEM_INITIALIZER(1), -1,\ - __PTHREAD_MUTEX_DEFAULT_FLAGS} +# define PTHREAD_MUTEX_INITIALIZER {NULL, __PTHREAD_MUTEX_DEFAULT_FLAGS,\ + NXMUTEX_INITIALIZER} #else -# define PTHREAD_MUTEX_INITIALIZER {SEM_INITIALIZER(1), -1} +# define PTHREAD_MUTEX_INITIALIZER {NXMUTEX_INITIALIZER} #endif struct pthread_barrierattr_s diff --git a/sched/pthread/pthread.h b/sched/pthread/pthread.h index f4d04e8f55..6e7dd8b6d3 100644 --- a/sched/pthread/pthread.h +++ b/sched/pthread/pthread.h @@ -36,6 +36,40 @@ #include #include +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifdef CONFIG_PTHREAD_MUTEX_TYPES +# define mutex_init(m) nxrmutex_init(m) +# define mutex_destroy(m) nxrmutex_destroy(m) +# define mutex_is_hold(m) nxrmutex_is_hold(m) +# define mutex_is_locked(m) nxrmutex_is_locked(m) +# define mutex_is_recursive(m) nxrmutex_is_recursive(m) +# define mutex_get_holder(m) nxrmutex_get_holder(m) +# define mutex_reset(m) nxrmutex_reset(m) +# define mutex_unlock(m) nxrmutex_unlock(m) +# define mutex_lock(m) nxrmutex_lock(m) +# define mutex_trylock(m) nxrmutex_trylock(m) +# define mutex_breaklock(m,v) nxrmutex_breaklock(m,v) +# define mutex_restorelock(m,v) nxrmutex_restorelock(m,v) +# define mutex_clocklock(m,t) nxrmutex_clocklock(m,CLOCK_REALTIME,t) +#else +# define mutex_init(m) nxmutex_init(m) +# define mutex_destroy(m) nxmutex_destroy(m) +# define mutex_is_hold(m) nxmutex_is_hold(m) +# define mutex_is_recursive(m) (false) +# define mutex_is_locked(m) nxmutex_is_locked(m) +# define mutex_get_holder(m) nxmutex_get_holder(m) +# define mutex_reset(m) nxmutex_reset(m) +# define mutex_unlock(m) nxmutex_unlock(m) +# define mutex_lock(m) nxmutex_lock(m) +# define mutex_trylock(m) nxmutex_trylock(m) +# define mutex_breaklock(m,v) nxmutex_breaklock(m, v) +# define mutex_restorelock(m,v) nxmutex_restorelock(m, v) +# define mutex_clocklock(m,t) nxmutex_clocklock(m,CLOCK_REALTIME,t) +#endif + /**************************************************************************** * Public Data ****************************************************************************/ @@ -76,11 +110,18 @@ int pthread_mutex_take(FAR struct pthread_mutex_s *mutex, FAR const struct timespec *abs_timeout); int pthread_mutex_trytake(FAR struct pthread_mutex_s *mutex); int pthread_mutex_give(FAR struct pthread_mutex_s *mutex); +int pthread_mutex_breaklock(FAR struct pthread_mutex_s *mutex, + FAR unsigned int *breakval); +int pthread_mutex_restorelock(FAR struct pthread_mutex_s *mutex, + unsigned int breakval); void pthread_mutex_inconsistent(FAR struct tcb_s *tcb); #else -# define pthread_mutex_take(m,abs_timeout) pthread_sem_take(&(m)->sem,(abs_timeout)) -# define pthread_mutex_trytake(m) pthread_sem_trytake(&(m)->sem) -# define pthread_mutex_give(m) pthread_sem_give(&(m)->sem) +# define pthread_mutex_take(m,abs_timeout) -mutex_clocklock(&(m)->mutex, \ + abs_timeout) +# define pthread_mutex_trytake(m) -mutex_trylock(&(m)->mutex) +# define pthread_mutex_give(m) -mutex_unlock(&(m)->mutex) +# define pthread_mutex_breaklock(m,v) -mutex_breaklock(&(m)->mutex,v) +# define pthread_mutex_restorelock(m,v) -mutex_restorelock(&(m)->mutex,v) #endif #ifdef CONFIG_PTHREAD_MUTEX_TYPES diff --git a/sched/pthread/pthread_condclockwait.c b/sched/pthread/pthread_condclockwait.c index a600d301f4..d8afeb605a 100644 --- a/sched/pthread/pthread_condclockwait.c +++ b/sched/pthread/pthread_condclockwait.c @@ -74,7 +74,6 @@ int pthread_cond_clockwait(FAR pthread_cond_t *cond, FAR const struct timespec *abstime) { irqstate_t flags; - int mypid = nxsched_gettid(); int ret = OK; int status; @@ -93,7 +92,7 @@ int pthread_cond_clockwait(FAR pthread_cond_t *cond, /* Make sure that the caller holds the mutex */ - else if (mutex->pid != mypid) + else if (!mutex_is_hold(&mutex->mutex)) { ret = EPERM; } @@ -109,9 +108,7 @@ int pthread_cond_clockwait(FAR pthread_cond_t *cond, else { -#ifdef CONFIG_PTHREAD_MUTEX_TYPES - int16_t nlocks; -#endif + unsigned int nlocks; sinfo("Give up mutex...\n"); @@ -126,11 +123,7 @@ int pthread_cond_clockwait(FAR pthread_cond_t *cond, /* Give up the mutex */ - mutex->pid = INVALID_PROCESS_ID; -#ifdef CONFIG_PTHREAD_MUTEX_TYPES - nlocks = mutex->nlocks; -#endif - ret = pthread_mutex_give(mutex); + ret = pthread_mutex_breaklock(mutex, &nlocks); if (ret == 0) { status = nxsem_clockwait_uninterruptible(&cond->sem, @@ -151,17 +144,10 @@ int pthread_cond_clockwait(FAR pthread_cond_t *cond, sinfo("Re-locking...\n"); - status = pthread_mutex_take(mutex, NULL); - if (status == OK) + status = pthread_mutex_restorelock(mutex, nlocks); + if (ret == 0) { - mutex->pid = mypid; -#ifdef CONFIG_PTHREAD_MUTEX_TYPES - mutex->nlocks = nlocks; -#endif - } - else if (ret == 0) - { - ret = status; + ret = status; } /* Re-enable pre-emption (It is expected that interrupts diff --git a/sched/pthread/pthread_condwait.c b/sched/pthread/pthread_condwait.c index ada6658d95..7bb73c7382 100644 --- a/sched/pthread/pthread_condwait.c +++ b/sched/pthread/pthread_condwait.c @@ -75,15 +75,13 @@ int pthread_cond_wait(FAR pthread_cond_t *cond, FAR pthread_mutex_t *mutex) /* Make sure that the caller holds the mutex */ - else if (mutex->pid != nxsched_gettid()) + else if (!mutex_is_hold(&mutex->mutex)) { ret = EPERM; } else { -#ifdef CONFIG_PTHREAD_MUTEX_TYPES - int16_t nlocks; -#endif + unsigned int nlocks; /* Give up the mutex */ @@ -91,11 +89,7 @@ int pthread_cond_wait(FAR pthread_cond_t *cond, FAR pthread_mutex_t *mutex) flags = enter_critical_section(); sched_lock(); - mutex->pid = INVALID_PROCESS_ID; -#ifdef CONFIG_PTHREAD_MUTEX_TYPES - nlocks = mutex->nlocks; -#endif - ret = pthread_mutex_give(mutex); + ret = pthread_mutex_breaklock(mutex, &nlocks); /* Take the semaphore. This may be awakened only be a signal (EINTR) * or if the thread is canceled (ECANCELED) @@ -121,25 +115,13 @@ int pthread_cond_wait(FAR pthread_cond_t *cond, FAR pthread_mutex_t *mutex) sinfo("Reacquire mutex...\n"); - status = pthread_mutex_take(mutex, NULL); + status = pthread_mutex_restorelock(mutex, nlocks); if (ret == OK) { /* Report the first failure that occurs */ ret = status; } - - /* Did we get the mutex? */ - - if (status == OK) - { - /* Yes.. Then initialize it properly */ - - mutex->pid = nxsched_gettid(); -#ifdef CONFIG_PTHREAD_MUTEX_TYPES - mutex->nlocks = nlocks; -#endif - } } leave_cancellation_point(); diff --git a/sched/pthread/pthread_mutex.c b/sched/pthread/pthread_mutex.c index d609608b02..9dace791b3 100644 --- a/sched/pthread/pthread_mutex.c +++ b/sched/pthread/pthread_mutex.c @@ -158,13 +158,20 @@ int pthread_mutex_take(FAR struct pthread_mutex_s *mutex, { ret = EOWNERDEAD; } +#ifdef CONFIG_PTHREAD_MUTEX_TYPES + else if (mutex_is_hold(&mutex->mutex) && + mutex->type != PTHREAD_MUTEX_RECURSIVE) + { + ret = EDEADLK; + } +#endif else { - /* Take semaphore underlying the mutex. pthread_sem_take - * returns zero on success and a positive errno value on failure. + /* mutex_clocklock returns zero when successful, and the negative + * errno value is returned when failed. */ - ret = pthread_sem_take(&mutex->sem, abs_timeout); + ret = -mutex_clocklock(&mutex->mutex, abs_timeout); if (ret == OK) { /* Check if the holder of the mutex has terminated without @@ -174,12 +181,19 @@ int pthread_mutex_take(FAR struct pthread_mutex_s *mutex, if ((mutex->flags & _PTHREAD_MFLAGS_INCONSISTENT) != 0) { + /* If the holder thread has terminated, we need to reset + * the mutex and return an error. + */ + + mutex_reset(&mutex->mutex); ret = EOWNERDEAD; } - /* Add the mutex to the list of mutexes held by this task */ + /* If mutex is recursion, it is already in the linked list, + * and we should not add it to the link list again. + */ - else + else if (!mutex_is_recursive(&mutex->mutex)) { pthread_mutex_add(mutex); } @@ -228,18 +242,27 @@ int pthread_mutex_trytake(FAR struct pthread_mutex_s *mutex) { ret = EOWNERDEAD; } +#ifdef CONFIG_PTHREAD_MUTEX_TYPES + else if (mutex_is_hold(&mutex->mutex) && + mutex->type != PTHREAD_MUTEX_RECURSIVE) + { + ret = EBUSY; + } +#endif else { /* Try to take the semaphore underlying the mutex */ - ret = nxsem_trywait(&mutex->sem); + ret = mutex_trylock(&mutex->mutex); if (ret < 0) { ret = -ret; } - else + else if (!mutex_is_recursive(&mutex->mutex)) { - /* Add the mutex to the list of mutexes held by this task */ + /* If we successfully acquire the mutex, and we didn't get + * it before, add the mutex to the linked list. + */ pthread_mutex_add(mutex); } @@ -277,11 +300,58 @@ int pthread_mutex_give(FAR struct pthread_mutex_s *mutex) { /* Remove the mutex from the list of mutexes held by this task */ - pthread_mutex_remove(mutex); + if (!mutex_is_recursive(&mutex->mutex)) + { + pthread_mutex_remove(mutex); + } - /* Now release the underlying semaphore */ + /* Now release the underlying mutex */ - ret = pthread_sem_give(&mutex->sem); + ret = -mutex_unlock(&mutex->mutex); + } + + return ret; +} + +int pthread_mutex_breaklock(FAR struct pthread_mutex_s *mutex, + FAR unsigned int *breakval) +{ + int ret = EINVAL; + + /* Verify input parameters */ + + DEBUGASSERT(mutex != NULL); + if (mutex != NULL) + { + /* Remove the mutex from the list of mutexes held by this task */ + + pthread_mutex_remove(mutex); + + /* Now release the underlying mutex */ + + ret = -mutex_breaklock(&mutex->mutex, breakval); + } + + return ret; +} + +int pthread_mutex_restorelock(FAR struct pthread_mutex_s *mutex, + unsigned int breakval) +{ + int ret = EINVAL; + + /* Verify input parameters */ + + DEBUGASSERT(mutex != NULL); + if (mutex != NULL) + { + ret = -mutex_restorelock(&mutex->mutex, breakval); + if (ret == OK) + { + /* Add the mutex to the list of mutexes held by this task */ + + pthread_mutex_add(mutex); + } } return ret; diff --git a/sched/pthread/pthread_mutexconsistent.c b/sched/pthread/pthread_mutexconsistent.c index c9c888a8e4..a56e6dc436 100644 --- a/sched/pthread/pthread_mutexconsistent.c +++ b/sched/pthread/pthread_mutexconsistent.c @@ -74,21 +74,24 @@ int pthread_mutex_consistent(FAR pthread_mutex_t *mutex) { int ret = EINVAL; - int status; sinfo("mutex=%p\n", mutex); DEBUGASSERT(mutex != NULL); if (mutex != NULL) { + pid_t pid; + /* Make sure the mutex is stable while we make the following checks. */ sched_lock(); + pid = mutex_get_holder(&mutex->mutex); + /* Is the mutex available? */ - DEBUGASSERT(mutex->pid != 0); /* < 0: available, >0 owned, ==0 error */ - if (mutex->pid >= 0) + DEBUGASSERT(pid != 0); /* < 0: available, >0 owned, ==0 error */ + if (pid >= 0) { /* No.. Verify that the thread associated with the PID still * exists. We may be destroying the mutex after cancelling a @@ -101,28 +104,18 @@ int pthread_mutex_consistent(FAR pthread_mutex_t *mutex) * nxsched_get_tcb() does. */ - if (nxsched_get_tcb(mutex->pid) == NULL) + if (nxsched_get_tcb(pid) == NULL) { - /* The thread associated with the PID no longer exists */ - - mutex->pid = INVALID_PROCESS_ID; - mutex->flags &= _PTHREAD_MFLAGS_ROBUST; -#ifdef CONFIG_PTHREAD_MUTEX_TYPES - mutex->nlocks = 0; -#endif /* Reset the semaphore. This has the same affect as if the * dead task had called pthread_mutex_unlock(). */ - status = nxsem_reset(&mutex->sem, 1); - if (status < 0) - { - ret = -status; - } - else - { - ret = OK; - } + mutex_reset(&mutex->mutex); + + /* The thread associated with the PID no longer exists */ + + mutex->flags &= _PTHREAD_MFLAGS_ROBUST; + ret = OK; } /* Otherwise the mutex is held by some active thread. Let's not @@ -136,9 +129,6 @@ int pthread_mutex_consistent(FAR pthread_mutex_t *mutex) */ mutex->flags &= _PTHREAD_MFLAGS_ROBUST; -#ifdef CONFIG_PTHREAD_MUTEX_TYPES - mutex->nlocks = 0; -#endif ret = OK; } diff --git a/sched/pthread/pthread_mutexdestroy.c b/sched/pthread/pthread_mutexdestroy.c index b3d088e815..7191ca2f6a 100644 --- a/sched/pthread/pthread_mutexdestroy.c +++ b/sched/pthread/pthread_mutexdestroy.c @@ -65,20 +65,23 @@ int pthread_mutex_destroy(FAR pthread_mutex_t *mutex) if (mutex != NULL) { + pid_t pid; + /* Make sure the semaphore is stable while we make the following * checks. */ sched_lock(); + pid = mutex_get_holder(&mutex->mutex); + /* Is the mutex available? */ - if (mutex->pid >= 0) + if (pid >= 0) { /* < 0: available, >0 owned, ==0 error */ - DEBUGASSERT(mutex->pid != 0); - + DEBUGASSERT(pid != 0); /* No.. Verify that the PID still exists. We may be destroying * the mutex after cancelling a pthread and the mutex may have * been in a bad state owned by the dead pthread. NOTE: The @@ -90,28 +93,22 @@ int pthread_mutex_destroy(FAR pthread_mutex_t *mutex) * nxsched_get_tcb() does. */ - if (nxsched_get_tcb(mutex->pid) == NULL) + if (nxsched_get_tcb(pid) == NULL) { /* The thread associated with the PID no longer exists */ - mutex->pid = INVALID_PROCESS_ID; - /* Reset the semaphore. If threads are were on this * semaphore, then this will awakened them and make * destruction of the semaphore impossible here. */ - status = nxsem_reset(&mutex->sem, 1); - if (status < 0) - { - ret = -status; - } + mutex_reset(&mutex->mutex); /* Check if the reset caused some other thread to lock the * mutex. */ - else if (mutex->pid != INVALID_PROCESS_ID) + if (mutex_is_locked(&mutex->mutex)) { /* Yes.. then we cannot destroy the mutex now. */ @@ -122,7 +119,7 @@ int pthread_mutex_destroy(FAR pthread_mutex_t *mutex) else { - status = nxsem_destroy(&mutex->sem); + status = mutex_destroy(&mutex->mutex); ret = (status < 0) ? -status : OK; } } @@ -139,7 +136,7 @@ int pthread_mutex_destroy(FAR pthread_mutex_t *mutex) * Perhaps this logic should all nxsem_reset() first? */ - status = nxsem_destroy(&mutex->sem); + status = mutex_destroy(&mutex->mutex); ret = ((status < 0) ? -status : OK); } diff --git a/sched/pthread/pthread_mutexinconsistent.c b/sched/pthread/pthread_mutexinconsistent.c index a4191f5ddd..4b69cfab5c 100644 --- a/sched/pthread/pthread_mutexinconsistent.c +++ b/sched/pthread/pthread_mutexinconsistent.c @@ -80,7 +80,7 @@ void pthread_mutex_inconsistent(FAR struct tcb_s *tcb) /* Mark the mutex as INCONSISTENT and wake up any waiting thread */ mutex->flags |= _PTHREAD_MFLAGS_INCONSISTENT; - pthread_sem_give(&mutex->sem); + mutex_unlock(&mutex->mutex); } sched_unlock(); diff --git a/sched/pthread/pthread_mutexinit.c b/sched/pthread/pthread_mutexinit.c index aaef94dfd5..0222dc2556 100644 --- a/sched/pthread/pthread_mutexinit.c +++ b/sched/pthread/pthread_mutexinit.c @@ -58,13 +58,6 @@ int pthread_mutex_init(FAR pthread_mutex_t *mutex, #ifdef CONFIG_PTHREAD_MUTEX_TYPES uint8_t type = PTHREAD_MUTEX_DEFAULT; #endif -#ifdef CONFIG_PRIORITY_INHERITANCE -# ifdef CONFIG_PTHREAD_MUTEX_DEFAULT_PRIO_INHERIT - uint8_t proto = PTHREAD_PRIO_INHERIT; -# else - uint8_t proto = PTHREAD_PRIO_NONE; -# endif -#endif #ifndef CONFIG_PTHREAD_MUTEX_UNSAFE #ifdef CONFIG_PTHREAD_MUTEX_DEFAULT_UNSAFE uint8_t flags = 0; @@ -87,9 +80,6 @@ int pthread_mutex_init(FAR pthread_mutex_t *mutex, if (attr) { -#ifdef CONFIG_PRIORITY_INHERITANCE - proto = attr->proto; -#endif #ifdef CONFIG_PTHREAD_MUTEX_TYPES type = attr->type; #endif @@ -99,41 +89,25 @@ int pthread_mutex_init(FAR pthread_mutex_t *mutex, #endif } - /* Indicate that the semaphore is not held by any thread. */ - - mutex->pid = INVALID_PROCESS_ID; - /* Initialize the mutex like a semaphore with initial count = 1 */ - status = nxsem_init(&mutex->sem, 0, 1); - if (status < 0) - { - ret = -ret; - } - -#ifdef CONFIG_PRIORITY_INHERITANCE - /* Initialize the semaphore protocol */ - - status = nxsem_set_protocol(&mutex->sem, proto); + status = mutex_init(&mutex->mutex); if (status < 0) { ret = -status; } -#endif #ifndef CONFIG_PTHREAD_MUTEX_UNSAFE /* Initial internal fields of the mutex */ - mutex->flink = NULL; - - mutex->flags = flags; + mutex->flink = NULL; + mutex->flags = flags; #endif #ifdef CONFIG_PTHREAD_MUTEX_TYPES /* Set up attributes unique to the mutex type */ - mutex->type = type; - mutex->nlocks = 0; + mutex->type = type; #endif } diff --git a/sched/pthread/pthread_mutextimedlock.c b/sched/pthread/pthread_mutextimedlock.c index 6c36f57dca..cd0141f6e2 100644 --- a/sched/pthread/pthread_mutextimedlock.c +++ b/sched/pthread/pthread_mutextimedlock.c @@ -78,7 +78,6 @@ int pthread_mutex_timedlock(FAR pthread_mutex_t *mutex, FAR const struct timespec *abs_timeout) { - pid_t mypid = nxsched_gettid(); int ret = EINVAL; irqstate_t flags; @@ -87,6 +86,10 @@ int pthread_mutex_timedlock(FAR pthread_mutex_t *mutex, if (mutex != NULL) { +#ifndef CONFIG_PTHREAD_MUTEX_UNSAFE + pid_t pid = mutex_get_holder(&mutex->mutex); +#endif + /* Make sure the semaphore is stable while we make the following * checks. This all needs to be one atomic action. */ @@ -98,7 +101,8 @@ int pthread_mutex_timedlock(FAR pthread_mutex_t *mutex, * an error if the caller does not hold the mutex. */ - if (mutex->type != PTHREAD_MUTEX_NORMAL && mutex->pid == mypid) + if (mutex->type != PTHREAD_MUTEX_NORMAL && + mutex_is_hold(&mutex->mutex)) { /* Yes... Is this a recursive mutex? */ @@ -108,15 +112,7 @@ int pthread_mutex_timedlock(FAR pthread_mutex_t *mutex, * success. */ - if (mutex->nlocks < INT16_MAX) - { - mutex->nlocks++; - ret = OK; - } - else - { - ret = EOVERFLOW; - } + ret = pthread_mutex_take(mutex, abs_timeout); } else { @@ -148,26 +144,26 @@ int pthread_mutex_timedlock(FAR pthread_mutex_t *mutex, #ifdef CONFIG_PTHREAD_MUTEX_TYPES /* Include check if this is a NORMAL mutex and that it is robust */ - if (mutex->pid > 0 && + if (pid > 0 && ((mutex->flags & _PTHREAD_MFLAGS_ROBUST) != 0 || mutex->type != PTHREAD_MUTEX_NORMAL) && - nxsched_get_tcb(mutex->pid) == NULL) + nxsched_get_tcb(pid) == NULL) #else /* CONFIG_PTHREAD_MUTEX_TYPES */ /* This can only be a NORMAL mutex. Include check if it is robust */ - if (mutex->pid > 0 && + if (pid > 0 && (mutex->flags & _PTHREAD_MFLAGS_ROBUST) != 0 && - nxsched_get_tcb(mutex->pid) == NULL) + nxsched_get_tcb(pid) == NULL) #endif /* CONFIG_PTHREAD_MUTEX_TYPES */ #else /* CONFIG_PTHREAD_MUTEX_ROBUST */ /* This mutex is always robust, whatever type it is. */ - if (mutex->pid > 0 && nxsched_get_tcb(mutex->pid) == NULL) + if (pid > 0 && nxsched_get_tcb(pid) == NULL) #endif { - DEBUGASSERT(mutex->pid != 0); /* < 0: available, >0 owned, ==0 error */ + DEBUGASSERT(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 @@ -189,18 +185,6 @@ int pthread_mutex_timedlock(FAR pthread_mutex_t *mutex, */ ret = pthread_mutex_take(mutex, abs_timeout); - - /* If we successfully obtained the semaphore, then indicate - * that we own it. - */ - - if (ret == OK) - { - mutex->pid = mypid; -#ifdef CONFIG_PTHREAD_MUTEX_TYPES - mutex->nlocks = 1; -#endif - } } leave_critical_section(flags); diff --git a/sched/pthread/pthread_mutextrylock.c b/sched/pthread/pthread_mutextrylock.c index ace0656843..227dfe6352 100644 --- a/sched/pthread/pthread_mutextrylock.c +++ b/sched/pthread/pthread_mutextrylock.c @@ -76,7 +76,9 @@ int pthread_mutex_trylock(FAR pthread_mutex_t *mutex) if (mutex != NULL) { - pid_t mypid = nxsched_gettid(); +#ifndef CONFIG_PTHREAD_MUTEX_UNSAFE + pid_t pid = mutex_get_holder(&mutex->mutex); +#endif /* Make sure the semaphore is stable while we make the following * checks. This all needs to be one atomic action. @@ -89,19 +91,6 @@ int pthread_mutex_trylock(FAR pthread_mutex_t *mutex) status = pthread_mutex_trytake(mutex); if (status == OK) { - /* If we successfully obtained the semaphore, then indicate - * that we own it. - */ - - mutex->pid = mypid; - -#ifdef CONFIG_PTHREAD_MUTEX_TYPES - if (mutex->type == PTHREAD_MUTEX_RECURSIVE) - { - mutex->nlocks = 1; - } -#endif - ret = OK; } @@ -111,28 +100,6 @@ int pthread_mutex_trylock(FAR pthread_mutex_t *mutex) else if (status == EAGAIN) { -#ifdef CONFIG_PTHREAD_MUTEX_TYPES - /* Check if recursive mutex was locked by the calling thread. */ - - if (mutex->type == PTHREAD_MUTEX_RECURSIVE && mutex->pid == mypid) - { - /* Increment the number of locks held and return - * successfully. - */ - - if (mutex->nlocks < INT16_MAX) - { - mutex->nlocks++; - ret = OK; - } - else - { - ret = EOVERFLOW; - } - } - else -#endif - #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 @@ -144,28 +111,28 @@ int pthread_mutex_trylock(FAR pthread_mutex_t *mutex) #ifdef CONFIG_PTHREAD_MUTEX_TYPES /* Check if this NORMAL mutex is robust */ - if (mutex->pid > 0 && + if (pid > 0 && ((mutex->flags & _PTHREAD_MFLAGS_ROBUST) != 0 || mutex->type != PTHREAD_MUTEX_NORMAL) && - nxsched_get_tcb(mutex->pid) == NULL) + nxsched_get_tcb(pid) == NULL) #else /* CONFIG_PTHREAD_MUTEX_TYPES */ /* Check if this NORMAL mutex is robust */ - if (mutex->pid > 0 && + if (pid > 0 && (mutex->flags & _PTHREAD_MFLAGS_ROBUST) != 0 && - nxsched_get_tcb(mutex->pid) == NULL) + nxsched_get_tcb(pid) == NULL) #endif /* CONFIG_PTHREAD_MUTEX_TYPES */ #else /* CONFIG_PTHREAD_MUTEX_ROBUST */ /* This mutex is always robust, whatever type it is. */ - if (mutex->pid > 0 && nxsched_get_tcb(mutex->pid) == NULL) + if (pid > 0 && nxsched_get_tcb(pid) == NULL) #endif { /* < 0: available, >0 owned, ==0 error */ - DEBUGASSERT(mutex->pid != 0); + DEBUGASSERT(pid != 0); DEBUGASSERT((mutex->flags & _PTHREAD_MFLAGS_INCONSISTENT) != 0); diff --git a/sched/pthread/pthread_mutexunlock.c b/sched/pthread/pthread_mutexunlock.c index 08b5b9e2e4..f2595700ce 100644 --- a/sched/pthread/pthread_mutexunlock.c +++ b/sched/pthread/pthread_mutexunlock.c @@ -33,39 +33,6 @@ #include "pthread/pthread.h" -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: pthread_mutex_islocked - * - * Description: - * Return true is the mutex is locked. - * - * Input Parameters: - * None - * - * Returned Value: - * Returns true if the mutex is locked - * - ****************************************************************************/ - -static inline bool pthread_mutex_islocked(FAR struct pthread_mutex_s *mutex) -{ - int semcount = mutex->sem.semcount; - - /* The underlying semaphore should have a count less than 2: - * - * 1 == mutex is unlocked. - * 0 == mutex is locked with no waiters - * -n == mutex is locked with 'n' waiters. - */ - - DEBUGASSERT(semcount < 2); - return semcount < 1; -} - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -123,7 +90,7 @@ int pthread_mutex_unlock(FAR pthread_mutex_t *mutex) * remaining case. */ - if (pthread_mutex_islocked(mutex)) + if (mutex_is_locked(&mutex->mutex)) { #if !defined(CONFIG_PTHREAD_MUTEX_UNSAFE) || defined(CONFIG_PTHREAD_MUTEX_TYPES) /* Does the calling thread own the semaphore? If no, should we return @@ -143,7 +110,7 @@ int pthread_mutex_unlock(FAR pthread_mutex_t *mutex) * thread owns the semaphore. */ - if (mutex->pid != nxsched_gettid()) + if (!mutex_is_hold(&mutex->mutex)) #elif defined(CONFIG_PTHREAD_MUTEX_UNSAFE) && defined(CONFIG_PTHREAD_MUTEX_TYPES) /* If mutex types are not supported, then all mutexes are NORMAL (or @@ -152,7 +119,7 @@ int pthread_mutex_unlock(FAR pthread_mutex_t *mutex) */ if (mutex->type != PTHREAD_MUTEX_NORMAL && - mutex->pid != nxsched_gettid()) + !mutex_is_hold(&mutex->mutex)) #else /* CONFIG_PTHREAD_MUTEX_BOTH */ /* Skip the error check if this is a non-robust NORMAL mutex */ @@ -166,7 +133,7 @@ int pthread_mutex_unlock(FAR pthread_mutex_t *mutex) * the EPERM error? */ - if (errcheck && mutex->pid != nxsched_gettid()) + if (errcheck && !mutex_is_hold(&mutex->mutex)) #endif { /* No... return an EPERM error. @@ -180,29 +147,13 @@ int pthread_mutex_unlock(FAR pthread_mutex_t *mutex) * the behavior is undefined. */ - serr("ERROR: Holder=%d returning EPERM\n", mutex->pid); + serr("ERROR: Holder=%d returning EPERM\n", + mutex_get_holder(&mutex->mutex)); ret = EPERM; } else #endif /* !CONFIG_PTHREAD_MUTEX_UNSAFE || CONFIG_PTHREAD_MUTEX_TYPES */ -#ifdef CONFIG_PTHREAD_MUTEX_TYPES - /* Yes, the caller owns the semaphore.. Is this a recursive mutex? */ - - if (mutex->type == PTHREAD_MUTEX_RECURSIVE && mutex->nlocks > 1) - { - /* This is a recursive mutex and we there are multiple locks held. - * Retain the mutex lock, just decrement the count of locks held, - * and return success. - */ - - mutex->nlocks--; - ret = OK; - } - else - -#endif /* CONFIG_PTHREAD_MUTEX_TYPES */ - /* This is either a non-recursive mutex or is the outermost unlock of * a recursive mutex. * @@ -214,12 +165,6 @@ int pthread_mutex_unlock(FAR pthread_mutex_t *mutex) */ { - /* Nullify the pid and lock count then post the semaphore */ - - mutex->pid = INVALID_PROCESS_ID; -#ifdef CONFIG_PTHREAD_MUTEX_TYPES - mutex->nlocks = 0; -#endif ret = pthread_mutex_give(mutex); } }