From b51b72b2dba6dc7350cddfa40ca93203ebbc6932 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Mon, 10 Apr 2017 08:11:16 -0600 Subject: [PATCH] pthreads: Re-order some operations so that mutexes are placed in the inconsistent state BEFORE the clean-up callbacks are called. --- sched/Kconfig | 4 ++-- sched/pthread/pthread_cancel.c | 12 ++++++------ sched/pthread/pthread_exit.c | 12 ++++++------ sched/pthread/pthread_mutexconsistent.c | 4 +++- 4 files changed, 17 insertions(+), 15 deletions(-) diff --git a/sched/Kconfig b/sched/Kconfig index 50613fb44d..6cefe0e121 100644 --- a/sched/Kconfig +++ b/sched/Kconfig @@ -601,8 +601,6 @@ config PTHREAD_CLEANUP_STACKSIZE 8 for a CPU with 32-bit addressing and 4 for a CPU with 16-bit addressing. -endmenu # Pthread Options - config CANCELLATION_POINTS bool "Cancellation points" default n @@ -611,6 +609,8 @@ config CANCELLATION_POINTS cancellation points will also used with the () task_delete() API even if pthreads are not enabled. +endmenu # Pthread Options + menu "Performance Monitoring" config SCHED_CPULOAD diff --git a/sched/pthread/pthread_cancel.c b/sched/pthread/pthread_cancel.c index e2cad60ebb..f68d272e03 100644 --- a/sched/pthread/pthread_cancel.c +++ b/sched/pthread/pthread_cancel.c @@ -145,6 +145,12 @@ int pthread_cancel(pthread_t thread) pthread_exit(PTHREAD_CANCELED); } +#ifndef CONFIG_PTHREAD_MUTEX_UNSAFE + /* Recover any mutexes still held by the canceled thread */ + + pthread_mutex_inconsistent(tcb); +#endif + #ifdef CONFIG_PTHREAD_CLEANUP /* Perform any stack pthread clean-up callbacks. * @@ -162,12 +168,6 @@ int pthread_cancel(pthread_t thread) (void)pthread_completejoin((pid_t)thread, PTHREAD_CANCELED); -#ifndef CONFIG_PTHREAD_MUTEX_UNSAFE - /* Recover any mutexes still held by the canceled thread */ - - pthread_mutex_inconsistent(tcb); -#endif - /* Then let task_terminate do the real work */ return task_terminate((pid_t)thread, false); diff --git a/sched/pthread/pthread_exit.c b/sched/pthread/pthread_exit.c index bcc8e79c85..4929db94cb 100644 --- a/sched/pthread/pthread_exit.c +++ b/sched/pthread/pthread_exit.c @@ -105,6 +105,12 @@ void pthread_exit(FAR void *exit_value) tcb->cpcount = 0; #endif +#ifndef CONFIG_PTHREAD_MUTEX_UNSAFE + /* Recover any mutexes still held by the canceled thread */ + + pthread_mutex_inconsistent((FAR struct pthread_tcb_s *)tcb); +#endif + #ifdef CONFIG_PTHREAD_CLEANUP /* Perform any stack pthread clean-up callbacks */ @@ -123,12 +129,6 @@ void pthread_exit(FAR void *exit_value) exit(EXIT_FAILURE); } -#ifndef CONFIG_PTHREAD_MUTEX_UNSAFE - /* Recover any mutexes still held by the canceled thread */ - - pthread_mutex_inconsistent((FAR struct pthread_tcb_s *)tcb); -#endif - /* Perform common task termination logic. This will get called again later * through logic kicked off by _exit(). However, we need to call it before * calling _exit() in order certain operations if this is the last thread diff --git a/sched/pthread/pthread_mutexconsistent.c b/sched/pthread/pthread_mutexconsistent.c index 77d9bede3e..e374083021 100644 --- a/sched/pthread/pthread_mutexconsistent.c +++ b/sched/pthread/pthread_mutexconsistent.c @@ -119,7 +119,6 @@ int pthread_mutex_consistent(FAR pthread_mutex_t *mutex) /* The thread associated with the PID no longer exists */ mutex->pid = -1; - mutex->flags &= _PTHREAD_MFLAGS_ROBUST; #ifdef CONFIG_PTHREAD_MUTEX_TYPES mutex->nlocks = 0; #endif @@ -132,6 +131,9 @@ int pthread_mutex_consistent(FAR pthread_mutex_t *mutex) } } + /* Clear the inconsistent flag in any case */ + + mutex->flags &= _PTHREAD_MFLAGS_ROBUST; sched_unlock(); ret = OK; }