From cef56750eb5ce8a2aa31ff4e3bc038bc656a0d96 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Mon, 14 Dec 2015 11:47:47 +0100 Subject: Optional POSIX Cleanup initialization Update #2408. --- cpukit/posix/Makefile.am | 4 +- cpukit/posix/include/rtems/posix/cancel.h | 13 ----- cpukit/posix/include/rtems/posix/threadsup.h | 4 -- cpukit/posix/src/cancelrun.c | 50 ------------------ cpukit/posix/src/cleanuppop.c | 44 ---------------- cpukit/posix/src/cleanuppush.c | 79 +++++++++++++++++++++++++--- cpukit/posix/src/pthread.c | 16 +----- cpukit/score/include/rtems/score/percpu.h | 7 +++ cpukit/score/include/rtems/score/thread.h | 7 +++ cpukit/score/include/rtems/sysinit.h | 1 + testsuites/sptests/spsysinit01/init.c | 26 +++++++++ 11 files changed, 115 insertions(+), 136 deletions(-) delete mode 100644 cpukit/posix/src/cancelrun.c delete mode 100644 cpukit/posix/src/cleanuppop.c diff --git a/cpukit/posix/Makefile.am b/cpukit/posix/Makefile.am index ad9d29f998..54a298aaeb 100644 --- a/cpukit/posix/Makefile.am +++ b/cpukit/posix/Makefile.am @@ -78,8 +78,8 @@ libposix_a_SOURCES += src/barrierattrdestroy.c src/barrierattrgetpshared.c \ src/pbarriertranslatereturncode.c src/pbarrierwait.c ## CANCEL_C_FILES -libposix_a_SOURCES += src/cancel.c src/canceleval.c src/cancelrun.c \ - src/cleanuppop.c src/cleanuppush.c src/setcancelstate.c \ +libposix_a_SOURCES += src/cancel.c src/canceleval.c \ + src/cleanuppush.c src/setcancelstate.c \ src/setcanceltype.c src/testcancel.c ## CONDITION_VARIABLE_C_FILES diff --git a/cpukit/posix/include/rtems/posix/cancel.h b/cpukit/posix/include/rtems/posix/cancel.h index 9e60c269ce..52bbcbccec 100644 --- a/cpukit/posix/include/rtems/posix/cancel.h +++ b/cpukit/posix/include/rtems/posix/cancel.h @@ -21,19 +21,6 @@ #include -/** - * @brief POSIX run thread cancelation. - * - * This support routine runs through the chain of cancel handlers that - * have been registered and executes them. - * - * @param[in] the_thread is a pointer to the thread whose cancelation handlers - * should be run - */ -void _POSIX_Threads_cancel_run( - Thread_Control *the_thread -); - /** * @brief POSIX evaluate thread cancelation and enable dispatch. * diff --git a/cpukit/posix/include/rtems/posix/threadsup.h b/cpukit/posix/include/rtems/posix/threadsup.h index bf80c6314a..55db35ddbd 100644 --- a/cpukit/posix/include/rtems/posix/threadsup.h +++ b/cpukit/posix/include/rtems/posix/threadsup.h @@ -85,10 +85,6 @@ typedef struct { int cancelability_type; /** This indicates if a cancelation has been requested. */ int cancelation_requested; - /** - * @brief LIFO list of cleanup contexts. - */ - struct _pthread_cleanup_context *last_cleanup_context; } POSIX_API_Control; /** diff --git a/cpukit/posix/src/cancelrun.c b/cpukit/posix/src/cancelrun.c deleted file mode 100644 index 3e93b3dd57..0000000000 --- a/cpukit/posix/src/cancelrun.c +++ /dev/null @@ -1,50 +0,0 @@ -/** - * @file - * - * @brief Executes a thread's cancellation handlers - * @ingroup POSIXAPI - */ - -/* - * COPYRIGHT (c) 1989-2008. - * 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_Threads_cancel_run( - Thread_Control *the_thread -) -{ - struct _pthread_cleanup_context *context; - POSIX_API_Control *thread_support; - - _Thread_Disable_dispatch(); - - thread_support = the_thread->API_Extensions[ THREAD_API_POSIX ]; - thread_support->cancelability_state = PTHREAD_CANCEL_DISABLE; - - context = thread_support->last_cleanup_context; - thread_support->last_cleanup_context = NULL; - - _Thread_Enable_dispatch(); - - while ( context != NULL ) { - ( *context->_routine )( context->_arg ); - - context = context->_previous; - } -} diff --git a/cpukit/posix/src/cleanuppop.c b/cpukit/posix/src/cleanuppop.c deleted file mode 100644 index 081c97af66..0000000000 --- a/cpukit/posix/src/cleanuppop.c +++ /dev/null @@ -1,44 +0,0 @@ -/** - * @file - * - * @brief Removes Routine from Top of Calling Thread's stack and Invoke it - * @ingroup POSIXAPI - */ - -/* - * COPYRIGHT (c) 1989-2008. - * 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 - -void _pthread_cleanup_pop( - struct _pthread_cleanup_context *context, - int execute -) -{ - POSIX_API_Control *thread_support; - - if ( execute != 0 ) { - ( *context->_routine )( context->_arg ); - } - - _Thread_Disable_dispatch(); - - thread_support = _Thread_Executing->API_Extensions[ THREAD_API_POSIX ]; - thread_support->last_cleanup_context = context->_previous; - - _Thread_Enable_dispatch(); -} diff --git a/cpukit/posix/src/cleanuppush.c b/cpukit/posix/src/cleanuppush.c index bf99b062bb..0e5545898d 100644 --- a/cpukit/posix/src/cleanuppush.c +++ b/cpukit/posix/src/cleanuppush.c @@ -1,7 +1,7 @@ /** * @file * - * @brief Establishing Cancellation Handlers + * @brief POSIX Cleanup Support * @ingroup POSIXAPI */ @@ -20,9 +20,10 @@ #include +#include #include #include -#include +#include void _pthread_cleanup_push( struct _pthread_cleanup_context *context, @@ -30,7 +31,8 @@ void _pthread_cleanup_push( void *arg ) { - POSIX_API_Control *thread_support; + Per_CPU_Control *cpu_self; + Thread_Control *executing; context->_routine = routine; context->_arg = arg; @@ -38,11 +40,72 @@ void _pthread_cleanup_push( /* This value is unused, just provide a deterministic value */ context->_canceltype = -1; - _Thread_Disable_dispatch(); + cpu_self = _Thread_Dispatch_disable(); - thread_support = _Thread_Executing->API_Extensions[ THREAD_API_POSIX ]; - context->_previous = thread_support->last_cleanup_context; - thread_support->last_cleanup_context = context; + executing = _Per_CPU_Get_executing( cpu_self ); + context->_previous = executing->last_cleanup_context; + executing->last_cleanup_context = context; - _Thread_Enable_dispatch(); + _Thread_Dispatch_enable( cpu_self ); } + +void _pthread_cleanup_pop( + struct _pthread_cleanup_context *context, + int execute +) +{ + Per_CPU_Control *cpu_self; + Thread_Control *executing; + + if ( execute != 0 ) { + ( *context->_routine )( context->_arg ); + } + + cpu_self = _Thread_Dispatch_disable(); + + executing = _Per_CPU_Get_executing( cpu_self ); + executing->last_cleanup_context = context->_previous; + + _Thread_Dispatch_enable( cpu_self ); +} + +static void _POSIX_Cleanup_terminate_extension( Thread_Control *the_thread ) +{ + struct _pthread_cleanup_context *context; + + context = the_thread->last_cleanup_context; + the_thread->last_cleanup_context = NULL; + + while ( context != NULL ) { + ( *context->_routine )( context->_arg ); + + context = context->_previous; + } +} + +static void _POSIX_Cleanup_restart_extension( + Thread_Control *executing, + Thread_Control *the_thread +) +{ + (void) executing; + _POSIX_Cleanup_terminate_extension( the_thread ); +} + +static User_extensions_Control _POSIX_Cleanup_extensions = { + .Callouts = { + .thread_restart = _POSIX_Cleanup_restart_extension, + .thread_terminate = _POSIX_Cleanup_terminate_extension + } +}; + +static void _POSIX_Cleanup_initialization( void ) +{ + _User_extensions_Add_API_set( &_POSIX_Cleanup_extensions ); +} + +RTEMS_SYSINIT_ITEM( + _POSIX_Cleanup_initialization, + RTEMS_SYSINIT_POSIX_CLEANUP, + RTEMS_SYSINIT_ORDER_MIDDLE +); diff --git a/cpukit/posix/src/pthread.c b/cpukit/posix/src/pthread.c index 691dfc3161..6c4ea5ca8a 100644 --- a/cpukit/posix/src/pthread.c +++ b/cpukit/posix/src/pthread.c @@ -240,15 +240,6 @@ static bool _POSIX_Threads_Create_extension( return true; } -static void _POSIX_Threads_Restart_extension( - Thread_Control *executing, - Thread_Control *restarted -) -{ - (void) executing; - _POSIX_Threads_cancel_run( restarted ); -} - static void _POSIX_Threads_Terminate_extension( Thread_Control *executing ) @@ -259,11 +250,6 @@ static void _POSIX_Threads_Terminate_extension( api = executing->API_Extensions[ THREAD_API_POSIX ]; - /* - * Run the POSIX cancellation handlers - */ - _POSIX_Threads_cancel_run( executing ); - _Thread_Disable_dispatch(); /* @@ -326,7 +312,7 @@ User_extensions_Control _POSIX_Threads_User_extensions = { { { NULL, NULL }, NULL }, { _POSIX_Threads_Create_extension, /* create */ NULL, /* start */ - _POSIX_Threads_Restart_extension, /* restart */ + NULL, /* restart */ NULL, /* delete */ NULL, /* switch */ NULL, /* begin */ diff --git a/cpukit/score/include/rtems/score/percpu.h b/cpukit/score/include/rtems/score/percpu.h index 806c290b7c..4ad530f7d7 100644 --- a/cpukit/score/include/rtems/score/percpu.h +++ b/cpukit/score/include/rtems/score/percpu.h @@ -516,6 +516,13 @@ static inline uint32_t _Per_CPU_Get_index( const Per_CPU_Control *cpu ) return ( uint32_t ) ( per_cpu_envelope - &_Per_CPU_Information[ 0 ] ); } +static inline struct _Thread_Control *_Per_CPU_Get_executing( + const Per_CPU_Control *cpu +) +{ + return cpu->executing; +} + static inline bool _Per_CPU_Is_processor_started( const Per_CPU_Control *cpu ) diff --git a/cpukit/score/include/rtems/score/thread.h b/cpukit/score/include/rtems/score/thread.h index f4d76d8725..69caef1095 100644 --- a/cpukit/score/include/rtems/score/thread.h +++ b/cpukit/score/include/rtems/score/thread.h @@ -39,6 +39,8 @@ #include #endif +struct _pthread_cleanup_context; + struct Per_CPU_Control; struct Scheduler_Control; @@ -850,6 +852,11 @@ struct _Thread_Control { Thread_Capture_control Capture; + /** + * @brief LIFO list of POSIX cleanup contexts. + */ + struct _pthread_cleanup_context *last_cleanup_context; + /** * @brief Variable length array of user extension pointers. * diff --git a/cpukit/score/include/rtems/sysinit.h b/cpukit/score/include/rtems/sysinit.h index 1da3b309ac..dcd0e18092 100644 --- a/cpukit/score/include/rtems/sysinit.h +++ b/cpukit/score/include/rtems/sysinit.h @@ -44,6 +44,7 @@ extern "C" { #define RTEMS_SYSINIT_CLASSIC_BARRIER 00034a #define RTEMS_SYSINIT_POSIX_SIGNALS 000360 #define RTEMS_SYSINIT_POSIX_THREADS 000361 +#define RTEMS_SYSINIT_POSIX_CLEANUP 00036a #define RTEMS_SYSINIT_IDLE_THREADS 000380 #define RTEMS_SYSINIT_BSP_LIBC 000400 #define RTEMS_SYSINIT_BEFORE_DRIVERS 000500 diff --git a/testsuites/sptests/spsysinit01/init.c b/testsuites/sptests/spsysinit01/init.c index 3bbea9c006..8925099ec7 100644 --- a/testsuites/sptests/spsysinit01/init.c +++ b/testsuites/sptests/spsysinit01/init.c @@ -17,6 +17,7 @@ #endif #include +#include #include #include @@ -40,6 +41,7 @@ #include #include #include +#include #include #include #include @@ -84,6 +86,8 @@ typedef enum { POSIX_SIGNALS_POST, POSIX_THREADS_PRE, POSIX_THREADS_POST, + POSIX_CLEANUP_PRE, + POSIX_CLEANUP_POST, #endif /* RTEMS_POSIX_API */ IDLE_THREADS_PRE, IDLE_THREADS_POST, @@ -358,6 +362,24 @@ LAST(RTEMS_SYSINIT_POSIX_THREADS) next_step(POSIX_THREADS_POST); } +static size_t user_extensions_pre_posix_cleanup; + +FIRST(RTEMS_SYSINIT_POSIX_CLEANUP) +{ + user_extensions_pre_posix_cleanup = + _Chain_Node_count_unprotected(&_User_extensions_List); + next_step(POSIX_CLEANUP_PRE); +} + +LAST(RTEMS_SYSINIT_POSIX_CLEANUP) +{ + assert( + user_extensions_pre_posix_cleanup + 1 == + _Chain_Node_count_unprotected(&_User_extensions_List) + ); + next_step(POSIX_CLEANUP_POST); +} + #endif /* RTEMS_POSIX_API */ FIRST(RTEMS_SYSINIT_IDLE_THREADS) @@ -435,6 +457,10 @@ LAST(RTEMS_SYSINIT_BSP_POST_DRIVERS) static void Init(rtems_task_argument arg) { +#ifdef RTEMS_POSIX_API + pthread_cleanup_push(NULL, NULL); + pthread_cleanup_pop(0); +#endif /* RTEMS_POSIX_API */ next_step(INIT_TASK); rtems_test_endk(); exit(0); -- cgit v1.2.3