From a7dcef97e93240b1947a0094b1af91e9b9324a30 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Fri, 17 Nov 2017 06:36:54 +0100 Subject: score: Simplify global construction Update #3243. --- cpukit/posix/src/pthreadinitthreads.c | 26 ++--------- cpukit/rtems/src/taskinitusers.c | 24 ++-------- cpukit/score/Makefile.am | 1 - cpukit/score/include/rtems/score/threadimpl.h | 23 +++++----- cpukit/score/src/threadglobalconstruction.c | 63 --------------------------- cpukit/score/src/threadhandler.c | 46 +++++++++++++++++++ 6 files changed, 64 insertions(+), 119 deletions(-) delete mode 100644 cpukit/score/src/threadglobalconstruction.c (limited to 'cpukit') diff --git a/cpukit/posix/src/pthreadinitthreads.c b/cpukit/posix/src/pthreadinitthreads.c index 7695879aae..1777ec9b6d 100644 --- a/cpukit/posix/src/pthreadinitthreads.c +++ b/cpukit/posix/src/pthreadinitthreads.c @@ -31,19 +31,6 @@ #include #include #include -#include - -static void *_POSIX_Global_construction( void *arg ) -{ - Thread_Control *executing = _Thread_Get_executing(); - Thread_Entry_information entry = executing->Start.Entry; - - entry.Kinds.Pointer.entry = Configuration_POSIX_API - .User_initialization_threads_table[ 0 ].thread_entry; - - (void) arg; - _Thread_Global_construction( executing, &entry ); -} void _POSIX_Threads_Initialize_user_threads_body(void) { @@ -53,7 +40,6 @@ void _POSIX_Threads_Initialize_user_threads_body(void) posix_initialization_threads_table *user_threads; pthread_t thread_id; pthread_attr_t attr; - bool register_global_construction; void *(*thread_entry)(void *); user_threads = Configuration_POSIX_API.User_initialization_threads_table; @@ -62,9 +48,6 @@ void _POSIX_Threads_Initialize_user_threads_body(void) if ( !user_threads ) return; - register_global_construction = - Configuration_RTEMS_API.number_of_initialization_tasks == 0; - /* * Be careful .. if the default attribute set changes, this may need to. * @@ -88,11 +71,6 @@ void _POSIX_Threads_Initialize_user_threads_body(void) _Internal_error( INTERNAL_ERROR_POSIX_INIT_THREAD_ENTRY_IS_NULL ); } - if ( register_global_construction ) { - register_global_construction = false; - thread_entry = _POSIX_Global_construction; - } - eno = pthread_create( &thread_id, &attr, @@ -102,5 +80,9 @@ void _POSIX_Threads_Initialize_user_threads_body(void) if ( eno != 0 ) { _Internal_error( INTERNAL_ERROR_POSIX_INIT_THREAD_CREATE_FAILED ); } + + if ( _Thread_Global_constructor == 0 ) { + _Thread_Global_constructor = thread_id; + } } } diff --git a/cpukit/rtems/src/taskinitusers.c b/cpukit/rtems/src/taskinitusers.c index 41b7edc1c4..c14d95d756 100644 --- a/cpukit/rtems/src/taskinitusers.c +++ b/cpukit/rtems/src/taskinitusers.c @@ -29,18 +29,6 @@ #include #include -static void _RTEMS_Global_construction( rtems_task_argument arg ) -{ - Thread_Control *executing = _Thread_Get_executing(); - Thread_Entry_information entry = executing->Start.Entry; - - entry.Kinds.Numeric.entry = - Configuration_RTEMS_API.User_initialization_tasks_table[ 0 ].entry_point; - - (void) arg; - _Thread_Global_construction( executing, &entry ); -} - /* * _RTEMS_tasks_Initialize_user_tasks_body * @@ -59,7 +47,6 @@ void _RTEMS_tasks_Initialize_user_tasks_body( void ) rtems_id id; rtems_status_code return_value; rtems_initialization_tasks_table *user_tasks; - bool register_global_construction; rtems_task_entry entry_point; /* @@ -74,8 +61,6 @@ void _RTEMS_tasks_Initialize_user_tasks_body( void ) if ( !user_tasks ) return; - register_global_construction = true; - /* * Now iterate over the initialization tasks and create/start them. */ @@ -97,11 +82,6 @@ void _RTEMS_tasks_Initialize_user_tasks_body( void ) _Internal_error( INTERNAL_ERROR_RTEMS_INIT_TASK_ENTRY_IS_NULL ); } - if ( register_global_construction ) { - register_global_construction = false; - entry_point = _RTEMS_Global_construction; - } - return_value = rtems_task_start( id, entry_point, @@ -109,5 +89,9 @@ void _RTEMS_tasks_Initialize_user_tasks_body( void ) ); _Assert( rtems_is_status_successful( return_value ) ); (void) return_value; + + if ( _Thread_Global_constructor == 0 ) { + _Thread_Global_constructor = id; + } } } diff --git a/cpukit/score/Makefile.am b/cpukit/score/Makefile.am index 11bf59cca8..1c815b1af4 100644 --- a/cpukit/score/Makefile.am +++ b/cpukit/score/Makefile.am @@ -292,7 +292,6 @@ libscore_a_SOURCES += src/threadentryadaptoridle.c libscore_a_SOURCES += src/threadentryadaptornumeric.c libscore_a_SOURCES += src/threadentryadaptorpointer.c libscore_a_SOURCES += src/threadgetcputimeused.c -libscore_a_SOURCES += src/threadglobalconstruction.c libscore_a_SOURCES += src/threaditerate.c libscore_a_SOURCES += src/threadname.c libscore_a_SOURCES += src/threadscheduler.c diff --git a/cpukit/score/include/rtems/score/threadimpl.h b/cpukit/score/include/rtems/score/threadimpl.h index 5f6a5eb2d0..b6722fae19 100644 --- a/cpukit/score/include/rtems/score/threadimpl.h +++ b/cpukit/score/include/rtems/score/threadimpl.h @@ -69,6 +69,16 @@ typedef struct { */ extern Thread_Information _Thread_Internal_information; +/** + * @brief Object identifier of the global constructor thread. + * + * This variable is set by _RTEMS_tasks_Initialize_user_tasks_body() or + * _POSIX_Threads_Initialize_user_threads_body(). + * + * It is consumed by _Thread_Handler(). + */ +extern Objects_Id _Thread_Global_constructor; + /** * The following points to the thread whose floating point * context is currently loaded. @@ -345,19 +355,6 @@ void _Thread_Entry_adaptor_pointer( Thread_Control *executing ); */ void _Thread_Handler( void ); -/** - * @brief Executes the global constructors and then restarts itself as the - * first initialization thread. - * - * The first initialization thread is the first RTEMS initialization task or - * the first POSIX initialization thread in case no RTEMS initialization tasks - * are present. - */ -void _Thread_Global_construction( - Thread_Control *executing, - const Thread_Entry_information *entry -) RTEMS_NO_RETURN; - RTEMS_INLINE_ROUTINE void _Thread_State_acquire_critical( Thread_Control *the_thread, ISR_lock_Context *lock_context diff --git a/cpukit/score/src/threadglobalconstruction.c b/cpukit/score/src/threadglobalconstruction.c deleted file mode 100644 index 7ce1862d8c..0000000000 --- a/cpukit/score/src/threadglobalconstruction.c +++ /dev/null @@ -1,63 +0,0 @@ -/** - * @file - * - * @brief Thread Global Construction - * - * @ingroup ScoreThread - */ - -/* - * COPYRIGHT (c) 1989-2012. - * 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 - -/* - * Conditional magic to determine what style of C++ constructor - * initialization this target and compiler version uses. - */ -#if defined(__USE_INIT_FINI__) - #if defined(__ARM_EABI__) - #define INIT_NAME __libc_init_array - #else - #define INIT_NAME _init - #endif - - extern void INIT_NAME(void); - #define EXECUTE_GLOBAL_CONSTRUCTORS -#endif - -#if defined(__USE__MAIN__) - extern void __main(void); - #define INIT_NAME __main - #define EXECUTE_GLOBAL_CONSTRUCTORS -#endif - -void _Thread_Global_construction( - Thread_Control *executing, - const Thread_Entry_information *entry -) -{ - ISR_lock_Context lock_context; - -#if defined(EXECUTE_GLOBAL_CONSTRUCTORS) - /* - * _init could be a weak symbol and we SHOULD test it but it isn't - * in any configuration I know of and it generates a warning on every - * RTEMS target configuration. --joel (12 May 2007) - */ - INIT_NAME(); -#endif - - _ISR_lock_ISR_disable( &lock_context ); - _Thread_Restart_self( _Thread_Executing, entry, &lock_context ); -} diff --git a/cpukit/score/src/threadhandler.c b/cpukit/score/src/threadhandler.c index 7267577baf..9201c55607 100644 --- a/cpukit/score/src/threadhandler.c +++ b/cpukit/score/src/threadhandler.c @@ -24,6 +24,50 @@ #include #include +/* + * Conditional magic to determine what style of C++ constructor + * initialization this target and compiler version uses. + */ +#if defined(__USE_INIT_FINI__) + #if defined(__ARM_EABI__) + #define INIT_NAME __libc_init_array + #else + #define INIT_NAME _init + #endif + + extern void INIT_NAME(void); + #define EXECUTE_GLOBAL_CONSTRUCTORS +#endif + +#if defined(__USE__MAIN__) + extern void __main(void); + #define INIT_NAME __main + #define EXECUTE_GLOBAL_CONSTRUCTORS +#endif + +Objects_Id _Thread_Global_constructor; + +static void _Thread_Global_construction( Thread_Control *executing ) +{ +#if defined(EXECUTE_GLOBAL_CONSTRUCTORS) + if ( executing->Object.id == _Thread_Global_constructor ) { + /* + * Prevent double construction in case the initialization thread is deleted + * and then recycled. There is not need for extra synchronization since + * this variable is set during the sequential system boot procedure. + */ + _Thread_Global_constructor = 0; + + /* + * _init could be a weak symbol and we SHOULD test it but it isn't + * in any configuration I know of and it generates a warning on every + * RTEMS target configuration. --joel (12 May 2007) + */ + INIT_NAME(); + } +#endif +} + void _Thread_Handler( void ) { Thread_Control *executing; @@ -80,6 +124,8 @@ void _Thread_Handler( void ) */ _User_extensions_Thread_begin( executing ); + _Thread_Global_construction( executing ); + /* * RTEMS supports multiple APIs and each API can define a different * thread/task prototype. The following code supports invoking the -- cgit v1.2.3