diff --git a/include/nuttx/mutex.h b/include/nuttx/mutex.h index b8785c8658b..7cd44d1d290 100644 --- a/include/nuttx/mutex.h +++ b/include/nuttx/mutex.h @@ -584,12 +584,10 @@ static inline_function int nxmutex_unlock(FAR mutex_t *mutex) * ****************************************************************************/ -#if defined(CONFIG_BUILD_FLAT) || defined(__KERNEL__) static inline_function void nxmutex_reset(FAR mutex_t *mutex) { nxsem_reset(&mutex->sem, 1); } -#endif /**************************************************************************** * Name: nxmutex_breaklock @@ -870,13 +868,11 @@ static inline_function bool nxrmutex_is_locked(FAR rmutex_t *rmutex) * ****************************************************************************/ -#if defined(CONFIG_BUILD_FLAT) || defined(__KERNEL__) static inline_function void nxrmutex_reset(FAR rmutex_t *rmutex) { rmutex->count = 0; nxmutex_reset(&rmutex->mutex); } -#endif #undef EXTERN #ifdef __cplusplus diff --git a/include/nuttx/pthread.h b/include/nuttx/pthread.h index a2d7114e9fa..07f825c27a0 100644 --- a/include/nuttx/pthread.h +++ b/include/nuttx/pthread.h @@ -100,6 +100,60 @@ } #endif +#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) +# define mutex_set_protocol(m,p) nxrmutex_set_protocol(m,p) +# define mutex_getprioceiling(m,p) nxrmutex_getprioceiling(m,p) +# define mutex_setprioceiling(m,p,o) nxrmutex_setprioceiling(m,p,o) +#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) +# define mutex_set_protocol(m,p) nxmutex_set_protocol(m,p) +# define mutex_getprioceiling(m,p) nxmutex_getprioceiling(m,p) +# define mutex_setprioceiling(m,p,o) nxmutex_setprioceiling(m,p,o) +#endif + +#ifndef CONFIG_PTHREAD_MUTEX_UNSAFE +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); +#else +# 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 + /**************************************************************************** * Public Types ****************************************************************************/ diff --git a/include/nuttx/sched.h b/include/nuttx/sched.h index dc438899d17..494ad5941c3 100644 --- a/include/nuttx/sched.h +++ b/include/nuttx/sched.h @@ -673,13 +673,6 @@ struct tcb_s siginfo_t *sigunbinfo; /* Signal info when task unblocked */ #endif /* !CONFIG_DISABLE_ALL_SIGNALS */ - /* Robust mutex support ***************************************************/ - -#if !defined(CONFIG_DISABLE_PTHREAD) && !defined(CONFIG_PTHREAD_MUTEX_UNSAFE) - FAR struct pthread_mutex_s *mhead; /* List of mutexes held by thread */ - spinlock_t mhead_lock; -#endif - /* CPU load monitoring support ********************************************/ #ifndef CONFIG_SCHED_CPULOAD_NONE diff --git a/include/nuttx/tls.h b/include/nuttx/tls.h index f971afe96f6..e8af699b38c 100644 --- a/include/nuttx/tls.h +++ b/include/nuttx/tls.h @@ -226,6 +226,15 @@ struct tls_info_s int tl_errno; /* Per-thread error number */ pid_t tl_tid; /* Thread ID */ FAR char **tl_argv; /* Arguments first string */ + + /* Robust mutex support ***************************************************/ + +#if !defined(CONFIG_DISABLE_PTHREAD) && !defined(CONFIG_PTHREAD_MUTEX_UNSAFE) + FAR struct pthread_mutex_s *tl_mhead; /* List of mutexes held by thread */ +#endif +#ifndef CONFIG_PTHREAD_MUTEX_UNSAFE + mutex_t tl_lock; +#endif }; /**************************************************************************** diff --git a/include/sys/syscall_lookup.h b/include/sys/syscall_lookup.h index 60fd08dced1..6972bdfbbb5 100644 --- a/include/sys/syscall_lookup.h +++ b/include/sys/syscall_lookup.h @@ -77,6 +77,7 @@ SYSCALL_LOOKUP(sethostname, 2) SYSCALL_LOOKUP(nxsem_destroy, 1) SYSCALL_LOOKUP(nxsem_post_slow, 1) +SYSCALL_LOOKUP(nxsem_reset, 2) SYSCALL_LOOKUP(nxsem_tickwait, 2) SYSCALL_LOOKUP(nxsem_clockwait, 3) SYSCALL_LOOKUP(nxsem_timedwait, 2) @@ -323,14 +324,6 @@ SYSCALL_LOOKUP(munmap, 2) SYSCALL_LOOKUP(nx_pthread_exit, 1) SYSCALL_LOOKUP(pthread_getschedparam, 3) SYSCALL_LOOKUP(pthread_join, 2) - SYSCALL_LOOKUP(pthread_mutex_destroy, 1) - SYSCALL_LOOKUP(pthread_mutex_init, 2) - SYSCALL_LOOKUP(pthread_mutex_timedlock, 2) - SYSCALL_LOOKUP(pthread_mutex_trylock, 1) - SYSCALL_LOOKUP(pthread_mutex_unlock, 1) -#ifndef CONFIG_PTHREAD_MUTEX_UNSAFE - SYSCALL_LOOKUP(pthread_mutex_consistent, 1) -#endif SYSCALL_LOOKUP(pthread_setschedparam, 3) SYSCALL_LOOKUP(pthread_setschedprio, 2) #ifdef CONFIG_SMP diff --git a/libs/libc/pthread/CMakeLists.txt b/libs/libc/pthread/CMakeLists.txt index 72ddf8fa5bd..22700b4b28b 100644 --- a/libs/libc/pthread/CMakeLists.txt +++ b/libs/libc/pthread/CMakeLists.txt @@ -89,9 +89,15 @@ if(NOT CONFIG_DISABLE_PTHREAD) pthread_mutexattr_getrobust.c pthread_mutexattr_setprioceiling.c pthread_mutexattr_getprioceiling.c + pthread_mutex.c + pthread_mutex_destroy.c + pthread_mutex_getprioceiling.c + pthread_mutex_init.c pthread_mutex_lock.c pthread_mutex_setprioceiling.c - pthread_mutex_getprioceiling.c + pthread_mutex_timedlock.c + pthread_mutex_trylock.c + pthread_mutex_unlock.c pthread_once.c pthread_yield.c pthread_atfork.c @@ -110,6 +116,10 @@ if(NOT CONFIG_DISABLE_PTHREAD) pthread_gettid_np.c pthread_concurrency.c) + if(NOT CONFIG_PTHREAD_MUTEX_UNSAFE) + list(APPEND SRCS pthread_mutex_consistent.c) + endif() + if(CONFIG_SMP) list(APPEND SRCS pthread_attr_getaffinity.c pthread_attr_setaffinity.c) endif() diff --git a/libs/libc/pthread/Make.defs b/libs/libc/pthread/Make.defs index fff7b1356df..94261b4696c 100644 --- a/libs/libc/pthread/Make.defs +++ b/libs/libc/pthread/Make.defs @@ -55,6 +55,8 @@ CSRCS += pthread_mutexattr_setprotocol.c pthread_mutexattr_getprotocol.c CSRCS += pthread_mutexattr_settype.c pthread_mutexattr_gettype.c CSRCS += pthread_mutexattr_setrobust.c pthread_mutexattr_getrobust.c CSRCS += pthread_mutexattr_setprioceiling.c pthread_mutexattr_getprioceiling.c +CSRCS += pthread_mutex_destroy.c pthread_mutex_init.c pthread_mutex_trylock.c +CSRCS += pthread_mutex_timedlock.c pthread_mutex.c pthread_mutex_unlock.c CSRCS += pthread_mutex_lock.c CSRCS += pthread_mutex_setprioceiling.c pthread_mutex_getprioceiling.c CSRCS += pthread_once.c pthread_yield.c pthread_atfork.c @@ -70,6 +72,10 @@ ifeq ($(CONFIG_SMP),y) CSRCS += pthread_attr_getaffinity.c pthread_attr_setaffinity.c endif +ifneq ($(CONFIG_PTHREAD_MUTEX_UNSAFE),y) +CSRCS += pthread_mutex_consistent.c +endif + ifeq ($(CONFIG_PTHREAD_SPINLOCKS),y) CSRCS += pthread_spinlock.c endif diff --git a/sched/pthread/pthread_mutex.c b/libs/libc/pthread/pthread_mutex.c similarity index 82% rename from sched/pthread/pthread_mutex.c rename to libs/libc/pthread/pthread_mutex.c index 7a790d3abb2..8caa4175610 100644 --- a/sched/pthread/pthread_mutex.c +++ b/libs/libc/pthread/pthread_mutex.c @@ -1,5 +1,5 @@ /**************************************************************************** - * sched/pthread/pthread_mutex.c + * libs/libc/pthread/pthread_mutex.c * * SPDX-License-Identifier: Apache-2.0 * @@ -34,14 +34,14 @@ #include #include #include - -#include "sched/sched.h" -#include "pthread/pthread.h" +#include /**************************************************************************** * Private Functions ****************************************************************************/ +#ifndef CONFIG_PTHREAD_MUTEX_UNSAFE + /**************************************************************************** * Name: pthread_mutex_add * @@ -58,17 +58,16 @@ static void pthread_mutex_add(FAR struct pthread_mutex_s *mutex) { - FAR struct tcb_s *rtcb = this_task(); - irqstate_t flags; + FAR struct tls_info_s *tls = tls_get_info(); DEBUGASSERT(mutex->flink == NULL); /* Add the mutex to the list of mutexes held by this pthread */ - flags = spin_lock_irqsave(&rtcb->mhead_lock); - mutex->flink = rtcb->mhead; - rtcb->mhead = mutex; - spin_unlock_irqrestore(&rtcb->mhead_lock, flags); + nxmutex_lock(&tls->tl_lock); + mutex->flink = tls->tl_mhead; + tls->tl_mhead = mutex; + nxmutex_unlock(&tls->tl_lock); } /**************************************************************************** @@ -87,16 +86,15 @@ static void pthread_mutex_add(FAR struct pthread_mutex_s *mutex) static void pthread_mutex_remove(FAR struct pthread_mutex_s *mutex) { - FAR struct tcb_s *rtcb = this_task(); + FAR struct tls_info_s *tls = tls_get_info(); FAR struct pthread_mutex_s *curr; FAR struct pthread_mutex_s *prev; - irqstate_t flags; - flags = spin_lock_irqsave(&rtcb->mhead_lock); + nxmutex_lock(&tls->tl_lock); /* Remove the mutex from the list of mutexes held by this task */ - for (prev = NULL, curr = rtcb->mhead; + for (prev = NULL, curr = tls->tl_mhead; curr != NULL && curr != mutex; prev = curr, curr = curr->flink) { @@ -110,7 +108,7 @@ static void pthread_mutex_remove(FAR struct pthread_mutex_s *mutex) if (prev == NULL) { - rtcb->mhead = mutex->flink; + tls->tl_mhead = mutex->flink; } else { @@ -118,7 +116,7 @@ static void pthread_mutex_remove(FAR struct pthread_mutex_s *mutex) } mutex->flink = NULL; - spin_unlock_irqrestore(&rtcb->mhead_lock, flags); + nxmutex_unlock(&tls->tl_lock); } /**************************************************************************** @@ -346,49 +344,4 @@ int pthread_mutex_restorelock(FAR struct pthread_mutex_s *mutex, return ret; } - -/**************************************************************************** - * Name: pthread_mutex_inconsistent - * - * Description: - * This function is called when a pthread is terminated via either - * pthread_exit() or pthread_cancel(). It will check for any mutexes - * held by exiting thread. It will mark them as inconsistent and - * then wake up the highest priority waiter for the mutex. That - * instance of pthread_mutex_lock() will then return EOWNERDEAD. - * - * Input Parameters: - * tcb -- a reference to the TCB of the exiting pthread. - * - * Returned Value: - * None. - * - ****************************************************************************/ - -void pthread_mutex_inconsistent(FAR struct tcb_s *tcb) -{ - FAR struct pthread_mutex_s *mutex; - irqstate_t flags; - - DEBUGASSERT(tcb != NULL); - - flags = spin_lock_irqsave_nopreempt(&tcb->mhead_lock); - - /* Remove and process each mutex held by this task */ - - while (tcb->mhead != NULL) - { - /* Remove the mutex from the TCB list */ - - mutex = tcb->mhead; - tcb->mhead = mutex->flink; - mutex->flink = NULL; - - /* Mark the mutex as INCONSISTENT and wake up any waiting thread */ - - mutex->flags |= _PTHREAD_MFLAGS_INCONSISTENT; - mutex_unlock(&mutex->mutex); - } - - spin_unlock_irqrestore_nopreempt(&tcb->mhead_lock, flags); -} +#endif diff --git a/sched/pthread/pthread_mutexconsistent.c b/libs/libc/pthread/pthread_mutex_consistent.c similarity index 97% rename from sched/pthread/pthread_mutexconsistent.c rename to libs/libc/pthread/pthread_mutex_consistent.c index f5b6d0f162f..2633c497935 100644 --- a/sched/pthread/pthread_mutexconsistent.c +++ b/libs/libc/pthread/pthread_mutex_consistent.c @@ -1,5 +1,5 @@ /**************************************************************************** - * sched/pthread/pthread_mutexconsistent.c + * libs/libc/pthread/pthread_mutex_consistent.c * * SPDX-License-Identifier: Apache-2.0 * @@ -33,8 +33,7 @@ #include #include - -#include "pthread/pthread.h" +#include /**************************************************************************** * Public Functions @@ -102,7 +101,7 @@ int pthread_mutex_consistent(FAR pthread_mutex_t *mutex) * nxsched_get_tcb() does. */ - if (nxsched_get_tcb(pid) == NULL) + if (pthread_kill(pid, 0) != 0) { /* Reset the semaphore. This has the same affect as if the * dead task had called pthread_mutex_unlock(). diff --git a/sched/pthread/pthread_mutexdestroy.c b/libs/libc/pthread/pthread_mutex_destroy.c similarity index 97% rename from sched/pthread/pthread_mutexdestroy.c rename to libs/libc/pthread/pthread_mutex_destroy.c index a5c74018e1b..88e09746a64 100644 --- a/sched/pthread/pthread_mutexdestroy.c +++ b/libs/libc/pthread/pthread_mutex_destroy.c @@ -1,5 +1,5 @@ /**************************************************************************** - * sched/pthread/pthread_mutexdestroy.c + * libs/libc/pthread/pthread_mutex_destroy.c * * SPDX-License-Identifier: Apache-2.0 * @@ -34,8 +34,7 @@ #include #include - -#include "pthread/pthread.h" +#include /**************************************************************************** * Public Functions @@ -89,7 +88,7 @@ int pthread_mutex_destroy(FAR pthread_mutex_t *mutex) * nxsched_get_tcb() does. */ - if (nxsched_get_tcb(pid) == NULL) + if (pthread_kill(pid, 0) != 0) { /* The thread associated with the PID no longer exists */ diff --git a/sched/pthread/pthread_mutexinit.c b/libs/libc/pthread/pthread_mutex_init.c similarity index 98% rename from sched/pthread/pthread_mutexinit.c rename to libs/libc/pthread/pthread_mutex_init.c index 5b55c569dc6..7b63cbb00d4 100644 --- a/sched/pthread/pthread_mutexinit.c +++ b/libs/libc/pthread/pthread_mutex_init.c @@ -1,5 +1,5 @@ /**************************************************************************** - * sched/pthread/pthread_mutexinit.c + * libs/libc/pthread/pthread_mutex_init.c * * SPDX-License-Identifier: Apache-2.0 * @@ -32,8 +32,7 @@ #include #include - -#include "pthread/pthread.h" +#include /**************************************************************************** * Public Functions diff --git a/sched/pthread/pthread_mutextimedlock.c b/libs/libc/pthread/pthread_mutex_timedlock.c similarity index 98% rename from sched/pthread/pthread_mutextimedlock.c rename to libs/libc/pthread/pthread_mutex_timedlock.c index 351e85fa14e..012d2ac7ece 100644 --- a/sched/pthread/pthread_mutextimedlock.c +++ b/libs/libc/pthread/pthread_mutex_timedlock.c @@ -1,5 +1,5 @@ /**************************************************************************** - * sched/pthread/pthread_mutextimedlock.c + * libs/libc/pthread/pthread_mutex_timedlock.c * * SPDX-License-Identifier: Apache-2.0 * @@ -34,8 +34,7 @@ #include #include - -#include "pthread/pthread.h" +#include /**************************************************************************** * Public Functions diff --git a/sched/pthread/pthread_mutextrylock.c b/libs/libc/pthread/pthread_mutex_trylock.c similarity index 96% rename from sched/pthread/pthread_mutextrylock.c rename to libs/libc/pthread/pthread_mutex_trylock.c index e4cee0aa024..2c2a627bd32 100644 --- a/sched/pthread/pthread_mutextrylock.c +++ b/libs/libc/pthread/pthread_mutex_trylock.c @@ -1,5 +1,5 @@ /**************************************************************************** - * sched/pthread/pthread_mutextrylock.c + * libs/libc/pthread/pthread_mutex_trylock.c * * SPDX-License-Identifier: Apache-2.0 * @@ -33,7 +33,7 @@ #include #include -#include "pthread/pthread.h" +#include /**************************************************************************** * Public Functions @@ -110,20 +110,20 @@ int pthread_mutex_trylock(FAR pthread_mutex_t *mutex) if (pid > 0 && ((mutex->flags & _PTHREAD_MFLAGS_ROBUST) != 0 || mutex->type != PTHREAD_MUTEX_NORMAL) && - nxsched_get_tcb(pid) == NULL) + pthread_kill(pid, 0) != 0) #else /* CONFIG_PTHREAD_MUTEX_TYPES */ /* Check if this NORMAL mutex is robust */ if (pid > 0 && (mutex->flags & _PTHREAD_MFLAGS_ROBUST) != 0 && - nxsched_get_tcb(pid) == NULL) + pthread_kill(pid, 0) != 0) #endif /* CONFIG_PTHREAD_MUTEX_TYPES */ #else /* CONFIG_PTHREAD_MUTEX_ROBUST */ /* This mutex is always robust, whatever type it is. */ - if (pid > 0 && nxsched_get_tcb(pid) == NULL) + if (pid > 0 && pthread_kill(pid, 0) != 0) #endif { /* < 0: available, >0 owned, ==0 error */ diff --git a/sched/pthread/pthread_mutexunlock.c b/libs/libc/pthread/pthread_mutex_unlock.c similarity index 98% rename from sched/pthread/pthread_mutexunlock.c rename to libs/libc/pthread/pthread_mutex_unlock.c index 2e73b77cb22..1708a0b3118 100644 --- a/sched/pthread/pthread_mutexunlock.c +++ b/libs/libc/pthread/pthread_mutex_unlock.c @@ -1,5 +1,5 @@ /**************************************************************************** - * sched/pthread/pthread_mutexunlock.c + * libs/libc/pthread/pthread_mutex_unlock.c * * SPDX-License-Identifier: Apache-2.0 * @@ -33,7 +33,7 @@ #include #include -#include "pthread/pthread.h" +#include /**************************************************************************** * Public Functions diff --git a/sched/init/nx_start.c b/sched/init/nx_start.c index 01ef285b901..ef04b1fbf95 100644 --- a/sched/init/nx_start.c +++ b/sched/init/nx_start.c @@ -451,10 +451,6 @@ static void idle_group_initialize(void) nxtask_joininit(tcb); -#if !defined(CONFIG_DISABLE_PTHREAD) && !defined(CONFIG_PTHREAD_MUTEX_UNSAFE) - spin_lock_init(&tcb->mhead_lock); -#endif - #ifdef CONFIG_SMP /* Create a stack for all CPU IDLE threads (except CPU0 which already * has a stack). diff --git a/sched/pthread/CMakeLists.txt b/sched/pthread/CMakeLists.txt index 6921bfe6f60..481e2133da2 100644 --- a/sched/pthread/CMakeLists.txt +++ b/sched/pthread/CMakeLists.txt @@ -29,11 +29,6 @@ if(NOT CONFIG_DISABLE_PTHREAD) pthread_detach.c pthread_getschedparam.c pthread_setschedparam.c - pthread_mutexinit.c - pthread_mutexdestroy.c - pthread_mutextimedlock.c - pthread_mutextrylock.c - pthread_mutexunlock.c pthread_condwait.c pthread_condsignal.c pthread_condbroadcast.c @@ -46,7 +41,7 @@ if(NOT CONFIG_DISABLE_PTHREAD) pthread_setschedprio.c) if(NOT CONFIG_PTHREAD_MUTEX_UNSAFE) - list(APPEND SRCS pthread_mutex.c pthread_mutexconsistent.c) + list(APPEND SRCS pthread_mutexinconsistent.c) endif() if(CONFIG_SMP) diff --git a/sched/pthread/Make.defs b/sched/pthread/Make.defs index 4a696068fa0..66fa744fe2e 100644 --- a/sched/pthread/Make.defs +++ b/sched/pthread/Make.defs @@ -24,15 +24,13 @@ ifneq ($(CONFIG_DISABLE_PTHREAD),y) CSRCS += pthread_create.c pthread_exit.c pthread_join.c pthread_detach.c CSRCS += pthread_getschedparam.c pthread_setschedparam.c -CSRCS += pthread_mutexinit.c pthread_mutexdestroy.c -CSRCS += pthread_mutextimedlock.c pthread_mutextrylock.c pthread_mutexunlock.c CSRCS += pthread_condwait.c pthread_condsignal.c pthread_condbroadcast.c CSRCS += pthread_condclockwait.c pthread_sigmask.c pthread_cancel.c CSRCS += pthread_completejoin.c pthread_findjoininfo.c CSRCS += pthread_release.c pthread_setschedprio.c ifneq ($(CONFIG_PTHREAD_MUTEX_UNSAFE),y) -CSRCS += pthread_mutex.c pthread_mutexconsistent.c +CSRCS += pthread_mutexinconsistent.c endif ifeq ($(CONFIG_SMP),y) diff --git a/sched/pthread/pthread.h b/sched/pthread/pthread.h index 1688ce71c3b..6737eeda98b 100644 --- a/sched/pthread/pthread.h +++ b/sched/pthread/pthread.h @@ -42,44 +42,6 @@ * 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_ticklock(m,t) nxrmutex_ticklock(m,t) -# define mutex_clocklock(m,t) nxrmutex_clocklock(m,CLOCK_REALTIME,t) -# define mutex_set_protocol(m,p) nxrmutex_set_protocol(m,p) -# define mutex_getprioceiling(m,p) nxrmutex_getprioceiling(m,p) -# define mutex_setprioceiling(m,p,o) nxrmutex_setprioceiling(m,p,o) -#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_ticklock(m,t) nxmutex_ticklock(m,t) -# define mutex_clocklock(m,t) nxmutex_clocklock(m,CLOCK_REALTIME,t) -# define mutex_set_protocol(m,p) nxmutex_set_protocol(m,p) -# define mutex_getprioceiling(m,p) nxmutex_getprioceiling(m,p) -# define mutex_setprioceiling(m,p,o) nxmutex_setprioceiling(m,p,o) -#endif - #define COND_WAIT_COUNT(cond) ((FAR atomic_t *)&(cond)->wait_count) /**************************************************************************** @@ -111,22 +73,7 @@ int pthread_findjoininfo(FAR struct task_group_s *group, pid_t pid, void pthread_release(FAR struct task_group_s *group); #ifndef CONFIG_PTHREAD_MUTEX_UNSAFE -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) -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 120d72d3f5c..7a95bbf8b54 100644 --- a/sched/pthread/pthread_condclockwait.c +++ b/sched/pthread/pthread_condclockwait.c @@ -41,6 +41,7 @@ #include #include #include +#include #include "sched/sched.h" #include "pthread/pthread.h" diff --git a/sched/pthread/pthread_condwait.c b/sched/pthread/pthread_condwait.c index 731599db72e..60b774db2c1 100644 --- a/sched/pthread/pthread_condwait.c +++ b/sched/pthread/pthread_condwait.c @@ -34,6 +34,7 @@ #include #include +#include #include "pthread/pthread.h" diff --git a/sched/pthread/pthread_create.c b/sched/pthread/pthread_create.c index d608fdaf8cc..f2349932e61 100644 --- a/sched/pthread/pthread_create.c +++ b/sched/pthread/pthread_create.c @@ -226,10 +226,6 @@ int nx_pthread_create(pthread_trampoline_t trampoline, FAR pthread_t *thread, nxtask_joininit(ptcb); -#ifndef CONFIG_PTHREAD_MUTEX_UNSAFE - spin_lock_init(&ptcb->mhead_lock); -#endif - /* Bind the parent's group to the new TCB (we have not yet joined the * group). */ diff --git a/sched/pthread/pthread_mutexinconsistent.c b/sched/pthread/pthread_mutexinconsistent.c new file mode 100644 index 00000000000..cc7349e77c1 --- /dev/null +++ b/sched/pthread/pthread_mutexinconsistent.c @@ -0,0 +1,89 @@ +/**************************************************************************** + * sched/pthread/pthread_mutexinconsistent.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include "pthread/pthread.h" +#include "sched/sched.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: pthread_mutex_inconsistent + * + * Description: + * This function is called when a pthread is terminated via either + * pthread_exit() or pthread_cancel(). It will check for any mutexes + * held by exiting thread. It will mark them as inconsistent and + * then wake up the highest priority waiter for the mutex. That + * instance of pthread_mutex_lock() will then return EOWNERDEAD. + * + * Input Parameters: + * tcb -- a reference to the TCB of the exiting pthread. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +void pthread_mutex_inconsistent(FAR struct tcb_s *tcb) +{ + FAR struct pthread_mutex_s *mutex; + FAR struct tls_info_s *tls = nxsched_get_tls(tcb); + + DEBUGASSERT(tcb != NULL); + + nxmutex_lock(&tls->tl_lock); + + /* Remove and process each mutex held by this task */ + + while (tls->tl_mhead != NULL) + { + /* Remove the mutex from the TCB list */ + + mutex = tls->tl_mhead; + tls->tl_mhead = mutex->flink; + mutex->flink = NULL; + + /* Mark the mutex as INCONSISTENT and wake up any waiting thread */ + + mutex->flags |= _PTHREAD_MFLAGS_INCONSISTENT; + mutex_reset(&mutex->mutex); + } + + nxmutex_unlock(&tls->tl_lock); +} diff --git a/sched/sched/sched_releasetcb.c b/sched/sched/sched_releasetcb.c index 96b3e736e79..7d2b51816a7 100644 --- a/sched/sched/sched_releasetcb.c +++ b/sched/sched/sched_releasetcb.c @@ -118,6 +118,10 @@ int nxsched_release_tcb(FAR struct tcb_s *tcb, uint8_t ttype) timer_deleteall(tcb->pid); #endif +#ifndef CONFIG_PTHREAD_MUTEX_UNSAFE + nxmutex_destroy(&nxsched_get_tls(tcb)->tl_lock); +#endif + /* Release the task's process ID if one was assigned. PID * zero is reserved for the IDLE task. The TCB of the IDLE * task is never release so a value of zero simply means that diff --git a/sched/task/task_fork.c b/sched/task/task_fork.c index 359db312f48..60645512d00 100644 --- a/sched/task/task_fork.c +++ b/sched/task/task_fork.c @@ -151,10 +151,6 @@ FAR struct tcb_s *nxtask_setup_fork(start_t retaddr) nxtask_joininit(child); -#if !defined(CONFIG_DISABLE_PTHREAD) && !defined(CONFIG_PTHREAD_MUTEX_UNSAFE) - spin_lock_init(&child->mhead_lock); -#endif - /* Allocate a new task group with the same privileges as the parent */ ret = group_allocate(child, ttype); diff --git a/sched/task/task_init.c b/sched/task/task_init.c index e26678704a3..6460dff6205 100644 --- a/sched/task/task_init.c +++ b/sched/task/task_init.c @@ -126,10 +126,6 @@ int nxtask_init(FAR struct tcb_s *tcb, const char *name, int priority, nxtask_joininit(tcb); #endif -#if !defined(CONFIG_DISABLE_PTHREAD) && !defined(CONFIG_PTHREAD_MUTEX_UNSAFE) - spin_lock_init(&tcb->mhead_lock); -#endif - /* Duplicate the parent tasks environment */ ret = env_dup(tcb->group, envp); diff --git a/sched/tls/tls_dupinfo.c b/sched/tls/tls_dupinfo.c index 5ee29d93de9..c1c5fe8776b 100644 --- a/sched/tls/tls_dupinfo.c +++ b/sched/tls/tls_dupinfo.c @@ -81,5 +81,9 @@ int tls_dup_info(FAR struct tcb_s *dst, FAR struct tcb_s *src) info->tl_tid = dst->pid; +#ifndef CONFIG_PTHREAD_MUTEX_UNSAFE + nxmutex_init(&info->tl_lock); +#endif + return OK; } diff --git a/sched/tls/tls_initinfo.c b/sched/tls/tls_initinfo.c index c38704a19cf..99ff59ad67e 100644 --- a/sched/tls/tls_initinfo.c +++ b/sched/tls/tls_initinfo.c @@ -84,5 +84,9 @@ int tls_init_info(FAR struct tcb_s *tcb) info->tl_argv = NULL; +#ifndef CONFIG_PTHREAD_MUTEX_UNSAFE + nxmutex_init(&info->tl_lock); +#endif + return OK; } diff --git a/syscall/syscall.csv b/syscall/syscall.csv index 4cf841bc3a4..37ead69a329 100644 --- a/syscall/syscall.csv +++ b/syscall/syscall.csv @@ -93,6 +93,7 @@ "nxsem_getprioceiling","nuttx/semaphore.h","defined(CONFIG_PRIORITY_PROTECT)","int","FAR const sem_t *","FAR int *" "nxsem_open","nuttx/semaphore.h","defined(CONFIG_FS_NAMED_SEMAPHORES)","int","FAR sem_t **","FAR const char *","int","...","mode_t","unsigned int" "nxsem_post_slow","nuttx/semaphore.h","","int","FAR sem_t *" +"nxsem_reset","nuttx/semaphore.h","","int","FAR sem_t *","int16_t" "nxsem_set_protocol","nuttx/semaphore.h","defined(CONFIG_PRIORITY_INHERITANCE)","int","FAR sem_t *","int" "nxsem_setprioceiling","nuttx/semaphore.h","defined(CONFIG_PRIORITY_PROTECT)","int","FAR sem_t *","int","FAR int *" "nxsem_timedwait","nuttx/semaphore.h","","int","FAR sem_t *","FAR const struct timespec *" @@ -117,12 +118,6 @@ "pthread_getaffinity_np","pthread.h","!defined(CONFIG_DISABLE_PTHREAD) && defined(CONFIG_SMP)","int","pthread_t","size_t","FAR cpu_set_t*" "pthread_getschedparam","pthread.h","!defined(CONFIG_DISABLE_PTHREAD)","int","pthread_t","FAR int *","FAR struct sched_param *" "pthread_join","pthread.h","!defined(CONFIG_DISABLE_PTHREAD)","int","pthread_t","FAR pthread_addr_t *" -"pthread_mutex_consistent","pthread.h","!defined(CONFIG_DISABLE_PTHREAD) && !defined(CONFIG_PTHREAD_MUTEX_UNSAFE)","int","FAR pthread_mutex_t *" -"pthread_mutex_destroy","pthread.h","!defined(CONFIG_DISABLE_PTHREAD)","int","FAR pthread_mutex_t *" -"pthread_mutex_init","pthread.h","!defined(CONFIG_DISABLE_PTHREAD)","int","FAR pthread_mutex_t *","FAR const pthread_mutexattr_t *" -"pthread_mutex_timedlock","pthread.h","!defined(CONFIG_DISABLE_PTHREAD)","int","FAR pthread_mutex_t *","FAR const struct timespec *" -"pthread_mutex_trylock","pthread.h","!defined(CONFIG_DISABLE_PTHREAD)","int","FAR pthread_mutex_t *" -"pthread_mutex_unlock","pthread.h","!defined(CONFIG_DISABLE_PTHREAD)","int","FAR pthread_mutex_t *" "pthread_setaffinity_np","pthread.h","!defined(CONFIG_DISABLE_PTHREAD) && defined(CONFIG_SMP)","int","pthread_t","size_t","FAR const cpu_set_t *" "pthread_setschedparam","pthread.h","!defined(CONFIG_DISABLE_PTHREAD)","int","pthread_t","int","FAR const struct sched_param *" "pthread_setschedprio","pthread.h","!defined(CONFIG_DISABLE_PTHREAD)","int","pthread_t","int" diff --git a/tools/pynuttx/nxgdb/protocols/thread.py b/tools/pynuttx/nxgdb/protocols/thread.py index 750aa8b8ad5..db89313840b 100644 --- a/tools/pynuttx/nxgdb/protocols/thread.py +++ b/tools/pynuttx/nxgdb/protocols/thread.py @@ -97,7 +97,6 @@ class Tcb(Value): sigpendactionq: Value sigpostedq: Value sigunbinfo: Value - mhead: Value ticks: Value run_start: Value run_max: Value