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 +++++++++++++++ testsuites/sptests/Makefile.am | 1 + testsuites/sptests/configure.ac | 1 + testsuites/sptests/spextensions01/init.c | 6 +- testsuites/sptests/sptls04/Makefile.am | 19 ++++++ testsuites/sptests/sptls04/init.c | 85 +++++++++++++++++++++++++++ testsuites/sptests/sptls04/sptls04.doc | 12 ++++ testsuites/sptests/sptls04/sptls04.scn | 7 +++ 13 files changed, 192 insertions(+), 122 deletions(-) delete mode 100644 cpukit/score/src/threadglobalconstruction.c create mode 100644 testsuites/sptests/sptls04/Makefile.am create mode 100644 testsuites/sptests/sptls04/init.c create mode 100644 testsuites/sptests/sptls04/sptls04.doc create mode 100644 testsuites/sptests/sptls04/sptls04.scn
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 <rtems/posix/pthreadimpl.h> #include <rtems/posix/priorityimpl.h> #include <rtems/posix/config.h> -#include <rtems/rtems/config.h> - -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 <rtems/score/thread.h> #include <rtems/score/wkspace.h> -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 @@ -70,6 +70,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 <rtems/score/threadimpl.h> - -/* - * 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 <rtems/score/isrlevel.h> #include <rtems/score/userextimpl.h> +/* + * 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 diff --git a/testsuites/sptests/Makefile.am b/testsuites/sptests/Makefile.am index e52316a825..00f7571902 100644 --- a/testsuites/sptests/Makefile.am +++ b/testsuites/sptests/Makefile.am @@ -64,6 +64,7 @@ _SUBDIRS += spfatal28 _SUBDIRS += spthreadlife01 _SUBDIRS += spcache01 _SUBDIRS += sptls03 +_SUBDIRS += sptls04 _SUBDIRS += spcpucounter01 if HAS_CPLUSPLUS _SUBDIRS += spglobalcon01 diff --git a/testsuites/sptests/configure.ac b/testsuites/sptests/configure.ac index 0872f678f7..6a303b25c5 100644 --- a/testsuites/sptests/configure.ac +++ b/testsuites/sptests/configure.ac @@ -36,6 +36,7 @@ AM_CONDITIONAL(HAS_SMP,test "$rtems_cv_RTEMS_SMP" = "yes") # Explicitly list all Makefiles here AC_CONFIG_FILES([Makefile +sptls04/Makefile spconsole01/Makefile spintrcritical24/Makefile spfatal31/Makefile diff --git a/testsuites/sptests/spextensions01/init.c b/testsuites/sptests/spextensions01/init.c index 35fce4878e..f9e3c11140 100644 --- a/testsuites/sptests/spextensions01/init.c +++ b/testsuites/sptests/spextensions01/init.c @@ -318,7 +318,7 @@ static void three_fatal( { if (source == RTEMS_FATAL_SOURCE_EXIT) { assert_forward_order(3); - assert(counter == 72); + assert(counter == 68); TEST_END(); } } @@ -453,8 +453,8 @@ static void test(void) #endif active_extensions = 4; - assert(counter == 14); - counter = 16; + assert(counter == 10); + counter = 12; sc = rtems_task_create( rtems_build_name('W', 'O', 'R', 'K'), diff --git a/testsuites/sptests/sptls04/Makefile.am b/testsuites/sptests/sptls04/Makefile.am new file mode 100644 index 0000000000..9d4afd2158 --- /dev/null +++ b/testsuites/sptests/sptls04/Makefile.am @@ -0,0 +1,19 @@ +rtems_tests_PROGRAMS = sptls04 +sptls04_SOURCES = init.c + +dist_rtems_tests_DATA = sptls04.scn sptls04.doc + +include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg +include $(top_srcdir)/../automake/compile.am +include $(top_srcdir)/../automake/leaf.am + +AM_CPPFLAGS += -I$(top_srcdir)/../support/include + +LINK_OBJS = $(sptls04_OBJECTS) +LINK_LIBS = $(sptls04_LDLIBS) + +sptls04$(EXEEXT): $(sptls04_OBJECTS) $(sptls04_DEPENDENCIES) + @rm -f sptls04$(EXEEXT) + $(make-exe) + +include $(top_srcdir)/../automake/local.am diff --git a/testsuites/sptests/sptls04/init.c b/testsuites/sptests/sptls04/init.c new file mode 100644 index 0000000000..d73b0f4642 --- /dev/null +++ b/testsuites/sptests/sptls04/init.c @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2017 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Dornierstr. 4 + * 82178 Puchheim + * Germany + * <rt...@embedded-brains.de> + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + */ + +/* + * This test program runs also on GNU/Linux and FreeBSD. Use + * + * cc init.c && ./a.out + * + * to run it. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef __rtems__ + +#include <tmacros.h> + +#else /* __rtems__ */ + +#include <assert.h> + +#define rtems_test_assert(x) assert(x) + +#endif /* __rtems__ */ + +static __thread int i; + +static __thread int j; + +static __attribute__((__constructor__)) void con(void) +{ + i = 1; +} + +static void test(void) +{ + rtems_test_assert(i == 1); + rtems_test_assert(j == 0); +} + +#ifdef __rtems__ + +const char rtems_test_name[] = "SPTLS 4"; + +static void Init(rtems_task_argument arg) +{ + TEST_BEGIN(); + test(); + TEST_END(); + rtems_test_exit(0); +} + +#define CONFIGURE_APPLICATION_DOES_NOT_NEED_CLOCK_DRIVER +#define CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER + +#define CONFIGURE_MAXIMUM_TASKS 1 + +#define CONFIGURE_RTEMS_INIT_TASKS_TABLE + +#define CONFIGURE_INIT + +#include <rtems/confdefs.h> + +#else /* __rtems__ */ + +int main(void) +{ + test(); + return 0; +} + +#endif /* __rtems__ */ diff --git a/testsuites/sptests/sptls04/sptls04.doc b/testsuites/sptests/sptls04/sptls04.doc new file mode 100644 index 0000000000..4c77dace65 --- /dev/null +++ b/testsuites/sptests/sptls04/sptls04.doc @@ -0,0 +1,12 @@ +This file describes the directives and concepts tested by this test set. + +test set name: sptls04 + +directives: + + - None + +concepts: + + - Ensure that global construction affects the thread-local variables of the + first initialization thread to be in line with GNU/Linux and FreeBSD. diff --git a/testsuites/sptests/sptls04/sptls04.scn b/testsuites/sptests/sptls04/sptls04.scn new file mode 100644 index 0000000000..f07cef1723 --- /dev/null +++ b/testsuites/sptests/sptls04/sptls04.scn @@ -0,0 +1,7 @@ +*** BEGIN OF TEST SPTLS 4 *** +*** TEST VERSION: 5.0.0.b926da560283088c42555a3f2e03a0ae9508087a +*** TEST STATE: EXPECTED-PASS +*** TEST BUILD: default +*** TEST TOOLS: 7.2.0 20170814 (RTEMS 5, RSB d1e6dfcb1e14d2f9d42c79e1137ddca6d8fc67d5, Newlib 2.5.0.20170922) + +*** END OF TEST SPTLS 4 *** -- 2.12.3 _______________________________________________ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel