From da82656065d09f7b6aa411ba361287afdd787204 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Fri, 13 May 2016 10:28:14 +0200 Subject: posix: Rework thread cancellation Add Thread_Life_state::THREAD_LIFE_CHANGE_DEFERRED and rework the POSIX thread cancellation to use the thread life states. Update #2555. Update #2626. --- cpukit/posix/src/cancel.c | 45 ++++++++++++++--------------- cpukit/posix/src/canceleval.c | 45 ----------------------------- cpukit/posix/src/pthread.c | 7 ----- cpukit/posix/src/pthreadcreate.c | 2 ++ cpukit/posix/src/pthreadexit.c | 29 +++---------------- cpukit/posix/src/pthreadinitthreads.c | 1 - cpukit/posix/src/setcancelstate.c | 51 ++++++++++++++------------------- cpukit/posix/src/setcanceltype.c | 54 ++++++++++++++++------------------- cpukit/posix/src/testcancel.c | 36 ++++------------------- 9 files changed, 80 insertions(+), 190 deletions(-) delete mode 100644 cpukit/posix/src/canceleval.c (limited to 'cpukit/posix/src') diff --git a/cpukit/posix/src/cancel.c b/cpukit/posix/src/cancel.c index f103d6574b..9519c45e52 100644 --- a/cpukit/posix/src/cancel.c +++ b/cpukit/posix/src/cancel.c @@ -9,6 +9,8 @@ * COPYRIGHT (c) 1989-2008. * On-Line Applications Research Corporation (OAR). * + * Copyright (c) 2016 embedded brains GmbH. + * * The license and distribution terms for this file may be * found in the file LICENSE in this distribution or at * http://www.rtems.org/license/LICENSE. @@ -23,46 +25,43 @@ #include #include -#include -#include /* * 18.2.1 Canceling Execution of a Thread, P1003.1c/Draft 10, p. 181 */ -int pthread_cancel( - pthread_t thread -) +int pthread_cancel( pthread_t thread ) { - Thread_Control *the_thread; - POSIX_API_Control *thread_support; - Objects_Locations location; + Thread_Control *the_thread; + ISR_lock_Context lock_context; + Thread_Control *executing; + Per_CPU_Control *cpu_self; /* * Don't even think about deleting a resource from an ISR. */ - if ( _ISR_Is_in_progress() ) + if ( _ISR_Is_in_progress() ) { return EPROTO; + } - the_thread = _Thread_Get( thread, &location ); - switch ( location ) { + the_thread = _Thread_Get_interrupt_disable( thread, &lock_context ); - case OBJECTS_LOCAL: - thread_support = the_thread->API_Extensions[ THREAD_API_POSIX ]; + if ( the_thread == NULL ) { + return ESRCH; + } - thread_support->cancelation_requested = 1; + cpu_self = _Thread_Dispatch_disable_critical( &lock_context ); + _ISR_lock_ISR_enable( &lock_context ); - /* This enables dispatch implicitly */ - _POSIX_Thread_Evaluate_cancellation_and_enable_dispatch( the_thread ); - return 0; + executing = _Per_CPU_Get_executing( cpu_self ); -#if defined(RTEMS_MULTIPROCESSING) - case OBJECTS_REMOTE: -#endif - case OBJECTS_ERROR: - break; + if ( the_thread == executing ) { + _Thread_Exit( executing, THREAD_LIFE_TERMINATING, PTHREAD_CANCELED ); + } else { + _Thread_Cancel( the_thread, executing, PTHREAD_CANCELED ); } - return ESRCH; + _Thread_Dispatch_enable( cpu_self ); + return 0; } diff --git a/cpukit/posix/src/canceleval.c b/cpukit/posix/src/canceleval.c deleted file mode 100644 index 9e02c92375..0000000000 --- a/cpukit/posix/src/canceleval.c +++ /dev/null @@ -1,45 +0,0 @@ -/** - * @file - * - * @brief POSIX Function Evaluates Thread Cancellation and Enables Dispatch - * @ingroup POSIXAPI - */ - -/* - * COPYRIGHT (c) 1989-2009. - * On-Line Applications Research Corporation (OAR). - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#if HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#include -#include -#include - -void _POSIX_Thread_Evaluate_cancellation_and_enable_dispatch( - Thread_Control *the_thread -) -{ - POSIX_API_Control *thread_support; - - thread_support = the_thread->API_Extensions[ THREAD_API_POSIX ]; - - if ( thread_support->cancelability_state == PTHREAD_CANCEL_ENABLE && - thread_support->cancelability_type == PTHREAD_CANCEL_ASYNCHRONOUS && - thread_support->cancelation_requested ) { - /* FIXME: This path is broken on SMP */ - _Thread_Unnest_dispatch(); - /* FIXME: Cancelability state may change here */ - _POSIX_Thread_Exit( the_thread, PTHREAD_CANCELED ); - } else - _Objects_Put( &the_thread->Object ); - -} diff --git a/cpukit/posix/src/pthread.c b/cpukit/posix/src/pthread.c index 12c5ace537..766ac01e5f 100644 --- a/cpukit/posix/src/pthread.c +++ b/cpukit/posix/src/pthread.c @@ -33,7 +33,6 @@ #include #include #include -#include #include #include #include @@ -208,12 +207,6 @@ static bool _POSIX_Threads_Create_extension( api->schedparam.sched_priority = _POSIX_Priority_From_core( created->current_priority ); - /* - * POSIX 1003.1 1996, 18.2.2.2 - */ - RTEMS_STATIC_ASSERT( PTHREAD_CANCEL_ENABLE == 0, cancelability_state ); - RTEMS_STATIC_ASSERT( PTHREAD_CANCEL_DEFERRED == 0, cancelability_type ); - /* * If the thread is not a posix thread, then all posix signals are blocked * by default. diff --git a/cpukit/posix/src/pthreadcreate.c b/cpukit/posix/src/pthreadcreate.c index 33fae37776..7f95898b62 100644 --- a/cpukit/posix/src/pthreadcreate.c +++ b/cpukit/posix/src/pthreadcreate.c @@ -205,6 +205,8 @@ int pthread_create( the_thread->Life.state |= THREAD_LIFE_DETACHED; } + the_thread->Life.state |= THREAD_LIFE_CHANGE_DEFERRED; + #if defined(RTEMS_SMP) && __RTEMS_HAVE_SYS_CPUSET_H__ _ISR_lock_ISR_disable( &lock_context ); status = _Scheduler_Set_affinity( diff --git a/cpukit/posix/src/pthreadexit.c b/cpukit/posix/src/pthreadexit.c index 3c4d3ebaaf..53c42ff3d0 100644 --- a/cpukit/posix/src/pthreadexit.c +++ b/cpukit/posix/src/pthreadexit.c @@ -9,6 +9,8 @@ * COPYRIGHT (c) 1989-2011. * On-Line Applications Research Corporation (OAR). * + * Copyright (c) 2016 embedded brains GmbH. + * * The license and distribution terms for this file may be * found in the file LICENSE in this distribution or at * http://www.rtems.org/license/LICENSE. @@ -20,41 +22,18 @@ #include -#include -#include -#include #include -#include -void _POSIX_Thread_Exit( - Thread_Control *the_thread, - void *value_ptr -) +void pthread_exit( void *value_ptr ) { Thread_Control *executing; Per_CPU_Control *cpu_self; - _Assert( _Debug_Is_thread_dispatching_allowed() ); - cpu_self = _Thread_Dispatch_disable(); executing = _Per_CPU_Get_executing( cpu_self ); - /* - * Now shut down the thread - */ - if ( the_thread == executing ) { - _Thread_Exit( executing, THREAD_LIFE_TERMINATING, value_ptr ); - } else { - _Thread_Cancel( the_thread, executing, value_ptr ); - } + _Thread_Exit( executing, THREAD_LIFE_TERMINATING, value_ptr ); _Thread_Dispatch_enable( cpu_self ); -} - -void pthread_exit( - void *value_ptr -) -{ - _POSIX_Thread_Exit( _Thread_Get_executing(), value_ptr ); RTEMS_UNREACHABLE(); } diff --git a/cpukit/posix/src/pthreadinitthreads.c b/cpukit/posix/src/pthreadinitthreads.c index 05ceda2120..ff11e8a6b0 100644 --- a/cpukit/posix/src/pthreadinitthreads.c +++ b/cpukit/posix/src/pthreadinitthreads.c @@ -27,7 +27,6 @@ #include #include #include -#include #include #include #include diff --git a/cpukit/posix/src/setcancelstate.c b/cpukit/posix/src/setcancelstate.c index a451c2c4b4..b0a42e86b8 100644 --- a/cpukit/posix/src/setcancelstate.c +++ b/cpukit/posix/src/setcancelstate.c @@ -9,6 +9,8 @@ * COPYRIGHT (c) 1989-2009. * On-Line Applications Research Corporation (OAR). * + * Copyright (c) 2016 embedded brains GmbH. + * * The license and distribution terms for this file may be * found in the file LICENSE in this distribution or at * http://www.rtems.org/license/LICENSE. @@ -21,13 +23,8 @@ #include #include -#include -#include #include -#include -#include -#include -#include +#include /* * 18.2.2 Setting Cancelability State, P1003.1c/Draft 10, p. 183 @@ -38,36 +35,30 @@ int pthread_setcancelstate( int *oldstate ) { - POSIX_API_Control *thread_support; - Thread_Control *executing; - - /* - * Don't even think about deleting a resource from an ISR. - * Besides this request is supposed to be for _Thread_Executing - * and the ISR context is not a thread. - */ + Thread_Life_state new_life_protection; + Thread_Life_state previous_life_state; - if ( _ISR_Is_in_progress() ) + if ( _ISR_Is_in_progress() ) { return EPROTO; + } - if ( state != PTHREAD_CANCEL_ENABLE && state != PTHREAD_CANCEL_DISABLE ) + if ( state == PTHREAD_CANCEL_DISABLE ) { + new_life_protection = THREAD_LIFE_PROTECTED; + } else if ( state == PTHREAD_CANCEL_ENABLE ) { + new_life_protection = 0; + } else { return EINVAL; + } - _Thread_Disable_dispatch(); - - executing = _Thread_Executing; - thread_support = executing ->API_Extensions[ THREAD_API_POSIX ]; - - if (oldstate != NULL) - *oldstate = thread_support->cancelability_state; - - thread_support->cancelability_state = state; - - _POSIX_Thread_Evaluate_cancellation_and_enable_dispatch( executing ); + previous_life_state = _Thread_Set_life_protection( new_life_protection ); - /* - * _Thread_Enable_dispatch is invoked by above call. - */ + if ( oldstate != NULL ) { + if ( ( previous_life_state & THREAD_LIFE_PROTECTED ) != 0 ) { + *oldstate = PTHREAD_CANCEL_DISABLE; + } else { + *oldstate = PTHREAD_CANCEL_ENABLE; + } + } return 0; } diff --git a/cpukit/posix/src/setcanceltype.c b/cpukit/posix/src/setcanceltype.c index 8c4687a981..701317f1d6 100644 --- a/cpukit/posix/src/setcanceltype.c +++ b/cpukit/posix/src/setcanceltype.c @@ -9,6 +9,8 @@ * COPYRIGHT (c) 1989-2009. * On-Line Applications Research Corporation (OAR). * + * Copyright (c) 2016 embedded brains GmbH. + * * The license and distribution terms for this file may be * found in the file LICENSE in this distribution or at * http://www.rtems.org/license/LICENSE. @@ -21,13 +23,8 @@ #include #include -#include -#include #include -#include -#include -#include -#include +#include /* * 18.2.2 Setting Cancelability State, P1003.1c/Draft 10, p. 183 @@ -38,35 +35,34 @@ int pthread_setcanceltype( int *oldtype ) { - POSIX_API_Control *thread_support; - Thread_Control *executing; - - /* - * Don't even think about deleting a resource from an ISR. - * Besides this request is supposed to be for _Thread_Executing - * and the ISR context is not a thread. - */ + Thread_Life_state set_life_state; + Thread_Life_state previous_life_state; - if ( _ISR_Is_in_progress() ) + if ( _ISR_Is_in_progress() ) { return EPROTO; + } - if ( type != PTHREAD_CANCEL_DEFERRED && type != PTHREAD_CANCEL_ASYNCHRONOUS ) + if ( type == PTHREAD_CANCEL_DEFERRED ) { + set_life_state = THREAD_LIFE_CHANGE_DEFERRED; + } else if ( type == PTHREAD_CANCEL_ASYNCHRONOUS ) { + set_life_state = 0; + } else { return EINVAL; + } - _Thread_Disable_dispatch(); - - executing = _Thread_Executing; - thread_support = executing ->API_Extensions[ THREAD_API_POSIX ]; - - if ( oldtype != NULL ) - *oldtype = thread_support->cancelability_type; - - thread_support->cancelability_type = type; + previous_life_state = _Thread_Change_life( + THREAD_LIFE_CHANGE_DEFERRED, + set_life_state, + 0 + ); - _POSIX_Thread_Evaluate_cancellation_and_enable_dispatch( executing ); + if ( oldtype != NULL ) { + if ( ( previous_life_state & THREAD_LIFE_CHANGE_DEFERRED ) != 0 ) { + *oldtype = PTHREAD_CANCEL_DEFERRED; + } else { + *oldtype = PTHREAD_CANCEL_ASYNCHRONOUS; + } + } - /* - * _Thread_Enable_dispatch is invoked by above call. - */ return 0; } diff --git a/cpukit/posix/src/testcancel.c b/cpukit/posix/src/testcancel.c index c78f26a62b..f50c7782ed 100644 --- a/cpukit/posix/src/testcancel.c +++ b/cpukit/posix/src/testcancel.c @@ -9,6 +9,8 @@ * COPYRIGHT (c) 1989-2008. * On-Line Applications Research Corporation (OAR). * + * Copyright (c) 2016 embedded brains GmbH. + * * The license and distribution terms for this file may be * found in the file LICENSE in this distribution or at * http://www.rtems.org/license/LICENSE. @@ -19,16 +21,9 @@ #endif #include -#include -#include -#include #include -#include -#include -#include -#include -#include +#include /* * 18.2.2 Setting Cancelability State, P1003.1c/Draft 10, p. 183 @@ -36,28 +31,9 @@ void pthread_testcancel( void ) { - POSIX_API_Control *thread_support; - Thread_Control *executing; - bool cancel = false; - - /* - * Don't even think about deleting a resource from an ISR. - * Besides this request is supposed to be for _Thread_Executing - * and the ISR context is not a thread. - */ - - if ( _ISR_Is_in_progress() ) + if ( _ISR_Is_in_progress() ) { return; + } - _Thread_Disable_dispatch(); - executing = _Thread_Executing; - thread_support = executing->API_Extensions[ THREAD_API_POSIX ]; - - if ( thread_support->cancelability_state == PTHREAD_CANCEL_ENABLE && - thread_support->cancelation_requested ) - cancel = true; - _Thread_Enable_dispatch(); - - if ( cancel ) - _POSIX_Thread_Exit( executing, PTHREAD_CANCELED ); + _Thread_Change_life( 0, 0, THREAD_LIFE_CHANGE_DEFERRED ); } -- cgit v1.2.3