From a38ced268314dfe3f61cbba5b982eeb77c2b8de4 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Fri, 10 Oct 2014 09:09:19 +0200 Subject: score: Rework global construction Ensure that the global construction is performed in the context of the first initialization thread. On SMP this was not guaranteed in the previous implementation. --- cpukit/posix/src/pthreadinitthreads.c | 17 +++- cpukit/rtems/src/taskinitusers.c | 13 ++- cpukit/score/Makefile.am | 1 + cpukit/score/include/rtems/score/threadimpl.h | 10 +++ cpukit/score/src/threadglobalconstruction.c | 94 ++++++++++++++++++++++ cpukit/score/src/threadhandler.c | 84 +------------------ testsuites/psxtests/Makefile.am | 4 + testsuites/psxtests/configure.ac | 9 ++- testsuites/psxtests/psxglobalcon01/Makefile.am | 19 +++++ testsuites/psxtests/psxglobalcon01/init.cc | 58 +++++++++++++ .../psxtests/psxglobalcon01/psxglobalcon01.doc | 12 +++ .../psxtests/psxglobalcon01/psxglobalcon01.scn | 2 + testsuites/psxtests/psxglobalcon02/Makefile.am | 19 +++++ testsuites/psxtests/psxglobalcon02/init.cc | 73 +++++++++++++++++ .../psxtests/psxglobalcon02/psxglobalcon02.doc | 12 +++ .../psxtests/psxglobalcon02/psxglobalcon02.scn | 2 + testsuites/sptests/Makefile.am | 1 + testsuites/sptests/configure.ac | 1 + testsuites/sptests/spglobalcon01/Makefile.am | 19 +++++ testsuites/sptests/spglobalcon01/init.cc | 61 ++++++++++++++ testsuites/sptests/spglobalcon01/spglobalcon01.doc | 12 +++ testsuites/sptests/spglobalcon01/spglobalcon01.scn | 2 + testsuites/sptests/spthreadlife01/init.c | 6 +- 23 files changed, 444 insertions(+), 87 deletions(-) create mode 100644 cpukit/score/src/threadglobalconstruction.c create mode 100644 testsuites/psxtests/psxglobalcon01/Makefile.am create mode 100644 testsuites/psxtests/psxglobalcon01/init.cc create mode 100644 testsuites/psxtests/psxglobalcon01/psxglobalcon01.doc create mode 100644 testsuites/psxtests/psxglobalcon01/psxglobalcon01.scn create mode 100644 testsuites/psxtests/psxglobalcon02/Makefile.am create mode 100644 testsuites/psxtests/psxglobalcon02/init.cc create mode 100644 testsuites/psxtests/psxglobalcon02/psxglobalcon02.doc create mode 100644 testsuites/psxtests/psxglobalcon02/psxglobalcon02.scn create mode 100644 testsuites/sptests/spglobalcon01/Makefile.am create mode 100644 testsuites/sptests/spglobalcon01/init.cc create mode 100644 testsuites/sptests/spglobalcon01/spglobalcon01.doc create mode 100644 testsuites/sptests/spglobalcon01/spglobalcon01.scn diff --git a/cpukit/posix/src/pthreadinitthreads.c b/cpukit/posix/src/pthreadinitthreads.c index ad8906b39a..3738dc44e1 100644 --- a/cpukit/posix/src/pthreadinitthreads.c +++ b/cpukit/posix/src/pthreadinitthreads.c @@ -34,6 +34,7 @@ #include #include #include +#include void _POSIX_Threads_Initialize_user_threads_body(void) { @@ -43,13 +44,18 @@ 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; maximum = Configuration_POSIX_API.number_of_initialization_threads; - if ( !user_threads || maximum == 0 ) + 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. * @@ -68,10 +74,17 @@ void _POSIX_Threads_Initialize_user_threads_body(void) eno = pthread_attr_setstacksize(&attr, user_threads[ index ].stack_size); _Assert( eno == 0 ); + thread_entry = user_threads[ index ].thread_entry; + + if ( register_global_construction && thread_entry != NULL ) { + register_global_construction = false; + thread_entry = (void *(*)(void *)) _Thread_Global_construction; + } + eno = pthread_create( &thread_id, &attr, - user_threads[ index ].thread_entry, + thread_entry, NULL ); if ( eno ) diff --git a/cpukit/rtems/src/taskinitusers.c b/cpukit/rtems/src/taskinitusers.c index 51fb474a3e..490ddc73eb 100644 --- a/cpukit/rtems/src/taskinitusers.c +++ b/cpukit/rtems/src/taskinitusers.c @@ -48,6 +48,8 @@ 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; /* * Move information into local variables @@ -61,6 +63,8 @@ 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. */ @@ -76,9 +80,16 @@ void _RTEMS_tasks_Initialize_user_tasks_body( void ) if ( !rtems_is_status_successful( return_value ) ) _Terminate( INTERNAL_ERROR_RTEMS_API, true, return_value ); + entry_point = user_tasks[ index ].entry_point; + + if ( register_global_construction && entry_point != NULL ) { + register_global_construction = false; + entry_point = (rtems_task_entry) _Thread_Global_construction; + } + return_value = rtems_task_start( id, - user_tasks[ index ].entry_point, + entry_point, user_tasks[ index ].argument ); if ( !rtems_is_status_successful( return_value ) ) diff --git a/cpukit/score/Makefile.am b/cpukit/score/Makefile.am index 55e10e9c4c..3e646a1725 100644 --- a/cpukit/score/Makefile.am +++ b/cpukit/score/Makefile.am @@ -289,6 +289,7 @@ libscore_a_SOURCES += src/thread.c src/threadchangepriority.c \ src/threadstackallocate.c src/threadstackfree.c src/threadstart.c \ src/threadstartmultitasking.c src/iterateoverthreads.c \ src/threadblockingoperationcancel.c +libscore_a_SOURCES += src/threadglobalconstruction.c libscore_a_SOURCES += src/threadyield.c if HAS_SMP diff --git a/cpukit/score/include/rtems/score/threadimpl.h b/cpukit/score/include/rtems/score/threadimpl.h index 9321c017b8..61b498a9cf 100644 --- a/cpukit/score/include/rtems/score/threadimpl.h +++ b/cpukit/score/include/rtems/score/threadimpl.h @@ -304,6 +304,16 @@ void _Thread_Load_environment( */ 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( void ); + /** * @brief Ended the delay of a thread. * diff --git a/cpukit/score/src/threadglobalconstruction.c b/cpukit/score/src/threadglobalconstruction.c new file mode 100644 index 0000000000..ff8af51242 --- /dev/null +++ b/cpukit/score/src/threadglobalconstruction.c @@ -0,0 +1,94 @@ +/** + * @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 +#include +#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(__M32R__) + #define INIT_NAME __init + #elif 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( void ) +{ + Thread_Control *executing; + Thread_Entry entry_point; + +#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 + +#if defined(RTEMS_POSIX_API) + if ( Configuration_RTEMS_API.number_of_initialization_tasks > 0 ) { +#endif + entry_point = (Thread_Entry) + Configuration_RTEMS_API.User_initialization_tasks_table[ 0 ].entry_point; +#if defined(RTEMS_POSIX_API) + } else { + entry_point = (Thread_Entry) + Configuration_POSIX_API + .User_initialization_threads_table[ 0 ].thread_entry; + } +#endif + + _Thread_Disable_dispatch(); + + executing = _Thread_Executing; + executing->Start.entry_point = entry_point; + + _Thread_Restart( + executing, + executing, + executing->Start.pointer_argument, + executing->Start.numeric_argument + ); + + _Thread_Enable_dispatch(); + + _Assert_Not_reached(); + + return NULL; +} diff --git a/cpukit/score/src/threadhandler.c b/cpukit/score/src/threadhandler.c index 5f6623f11f..f8a9a62429 100644 --- a/cpukit/score/src/threadhandler.c +++ b/cpukit/score/src/threadhandler.c @@ -24,76 +24,11 @@ #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(__M32R__) - #define INIT_NAME __init - #elif 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 - -#if defined(EXECUTE_GLOBAL_CONSTRUCTORS) - static bool _Thread_Handler_is_constructor_execution_required( - Thread_Control *executing - ) - { - static bool doneConstructors; - bool doCons = false; - - #if defined(RTEMS_SMP) - static SMP_lock_Control constructor_lock = - SMP_LOCK_INITIALIZER("constructor"); - - SMP_lock_Context lock_context; - - if ( !doneConstructors ) { - _SMP_lock_Acquire( &constructor_lock, &lock_context ); - #endif - - #if defined(RTEMS_MULTIPROCESSING) - doCons = !doneConstructors - && _Objects_Get_API( executing->Object.id ) != OBJECTS_INTERNAL_API; - if (doCons) - doneConstructors = true; - #else - (void) executing; - doCons = !doneConstructors; - doneConstructors = true; - #endif - - #if defined(RTEMS_SMP) - _SMP_lock_Release( &constructor_lock, &lock_context ); - } - #endif - - return doCons; - } -#endif - void _Thread_Handler( void ) { - ISR_Level level; - Thread_Control *executing; - #if defined(EXECUTE_GLOBAL_CONSTRUCTORS) - bool doCons; - #endif + Thread_Control *executing = _Thread_Executing; + ISR_Level level; - executing = _Thread_Executing; /* * Some CPUs need to tinker with the call frame or registers when the @@ -111,10 +46,6 @@ void _Thread_Handler( void ) _ISR_Set_level( level ); #endif - #if defined(EXECUTE_GLOBAL_CONSTRUCTORS) - doCons = _Thread_Handler_is_constructor_execution_required( executing ); - #endif - /* * Initialize the floating point context because we do not come * through _Thread_Dispatch on our first invocation. So the normal @@ -171,17 +102,6 @@ void _Thread_Handler( void ) _Thread_Enable_dispatch(); #endif - #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) - */ - if (doCons) /* && (volatile void *)_init) */ { - INIT_NAME (); - } - #endif - /* * RTEMS supports multiple APIs and each API can define a different * thread/task prototype. The following code supports invoking the diff --git a/testsuites/psxtests/Makefile.am b/testsuites/psxtests/Makefile.am index d8eee14a7e..e15d72f105 100644 --- a/testsuites/psxtests/Makefile.am +++ b/testsuites/psxtests/Makefile.am @@ -15,6 +15,10 @@ _SUBDIRS += psxhdrs psx01 psx02 psx03 psx04 psx05 psx06 psx07 psx08 psx09 \ psxtime psxtimer01 psxtimer02 psxualarm psxusleep psxfatal01 psxfatal02 \ psxintrcritical01 psxstack01 psxstack02 \ psxeintr_join psxgetattrnp01 +if HAS_CPLUSPLUS +_SUBDIRS += psxglobalcon01 +_SUBDIRS += psxglobalcon02 +endif endif ## File IO tests diff --git a/testsuites/psxtests/configure.ac b/testsuites/psxtests/configure.ac index 26e4b60ed3..23c7211647 100644 --- a/testsuites/psxtests/configure.ac +++ b/testsuites/psxtests/configure.ac @@ -11,17 +11,22 @@ RTEMS_CANONICAL_TARGET_CPU AM_INIT_AUTOMAKE([no-define foreign 1.12.2]) AM_MAINTAINER_MODE +RTEMS_ENABLE_CXX + RTEMS_ENV_RTEMSBSP RTEMS_PROJECT_ROOT RTEMS_PROG_CC_FOR_TARGET +RTEMS_PROG_CXX_FOR_TARGET RTEMS_CANONICALIZE_TOOLS RTEMS_CHECK_CUSTOM_BSP(RTEMS_BSP) +RTEMS_CHECK_CXX(RTEMS_BSP) -AM_CONDITIONAL([HAS_NETWORKING],[test "$HAS_NETWORKING" = "yes"]) +AM_CONDITIONAL([HAS_NETWORKING],[test x"$HAS_NETWORKING" = x"yes"]) +AM_CONDITIONAL([HAS_CPLUSPLUS],[test x"$HAS_CPLUSPLUS" = x"yes"]) RTEMS_CHECK_CPUOPTS([RTEMS_POSIX_API]) AM_CONDITIONAL(HAS_POSIX,test x"${rtems_cv_RTEMS_POSIX_API}" = x"yes") @@ -145,6 +150,8 @@ psxfile02/Makefile psxfilelock01/Makefile psxgetattrnp01/Makefile psxgetrusage01/Makefile +psxglobalcon01/Makefile +psxglobalcon02/Makefile psxhdrs/Makefile psxid01/Makefile psximfs01/Makefile diff --git a/testsuites/psxtests/psxglobalcon01/Makefile.am b/testsuites/psxtests/psxglobalcon01/Makefile.am new file mode 100644 index 0000000000..3b87ebe013 --- /dev/null +++ b/testsuites/psxtests/psxglobalcon01/Makefile.am @@ -0,0 +1,19 @@ +rtems_tests_PROGRAMS = psxglobalcon01 +psxglobalcon01_SOURCES = init.cc + +dist_rtems_tests_DATA = psxglobalcon01.scn psxglobalcon01.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 = $(psxglobalcon01_OBJECTS) +LINK_LIBS = $(psxglobalcon01_LDLIBS) + +psxglobalcon01$(EXEEXT): $(psxglobalcon01_OBJECTS) $(psxglobalcon01_DEPENDENCIES) + @rm -f psxglobalcon01$(EXEEXT) + $(make-exe) + +include $(top_srcdir)/../automake/local.am diff --git a/testsuites/psxtests/psxglobalcon01/init.cc b/testsuites/psxtests/psxglobalcon01/init.cc new file mode 100644 index 0000000000..f33efc3838 --- /dev/null +++ b/testsuites/psxtests/psxglobalcon01/init.cc @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2014 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Dornierstr. 4 + * 82178 Puchheim + * Germany + * + * + * 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. + */ + +#ifdef HAVE_CONFIG_H + #include "config.h" +#endif + +#include "tmacros.h" + +const char rtems_test_name[] = "PSXGLOBALCON 1"; + +class A { + public: + A() + { + ++i; + } + + static int i; +}; + +int A::i; + +static A a; + +static void *POSIX_Init(void *argument) +{ + TEST_BEGIN(); + + rtems_test_assert(a.i == 1); + + TEST_END(); + rtems_test_exit(0); +} + +#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER +#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER + +#define CONFIGURE_MAXIMUM_POSIX_THREADS 1 + +#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION + +#define CONFIGURE_POSIX_INIT_THREAD_TABLE + +#define CONFIGURE_INIT + +#include diff --git a/testsuites/psxtests/psxglobalcon01/psxglobalcon01.doc b/testsuites/psxtests/psxglobalcon01/psxglobalcon01.doc new file mode 100644 index 0000000000..7ed81dadaf --- /dev/null +++ b/testsuites/psxtests/psxglobalcon01/psxglobalcon01.doc @@ -0,0 +1,12 @@ +This file describes the directives and concepts tested by this test set. + +test set name: psxglobalcon01 + +directives: + + - _Thread_Global_construction() + +concepts: + + - Ensure that the global construction is performed exactly once in case only + a POSIX initialization thread is present. diff --git a/testsuites/psxtests/psxglobalcon01/psxglobalcon01.scn b/testsuites/psxtests/psxglobalcon01/psxglobalcon01.scn new file mode 100644 index 0000000000..13d7b65eb9 --- /dev/null +++ b/testsuites/psxtests/psxglobalcon01/psxglobalcon01.scn @@ -0,0 +1,2 @@ +*** BEGIN OF TEST PSXGLOBALCON 1 *** +*** END OF TEST PSXGLOBALCON 1 *** diff --git a/testsuites/psxtests/psxglobalcon02/Makefile.am b/testsuites/psxtests/psxglobalcon02/Makefile.am new file mode 100644 index 0000000000..0d29894baa --- /dev/null +++ b/testsuites/psxtests/psxglobalcon02/Makefile.am @@ -0,0 +1,19 @@ +rtems_tests_PROGRAMS = psxglobalcon02 +psxglobalcon02_SOURCES = init.cc + +dist_rtems_tests_DATA = psxglobalcon02.scn psxglobalcon02.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 = $(psxglobalcon02_OBJECTS) +LINK_LIBS = $(psxglobalcon02_LDLIBS) + +psxglobalcon02$(EXEEXT): $(psxglobalcon02_OBJECTS) $(psxglobalcon02_DEPENDENCIES) + @rm -f psxglobalcon02$(EXEEXT) + $(make-exe) + +include $(top_srcdir)/../automake/local.am diff --git a/testsuites/psxtests/psxglobalcon02/init.cc b/testsuites/psxtests/psxglobalcon02/init.cc new file mode 100644 index 0000000000..6de4fbd7c7 --- /dev/null +++ b/testsuites/psxtests/psxglobalcon02/init.cc @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2014 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Dornierstr. 4 + * 82178 Puchheim + * Germany + * + * + * 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. + */ + +#ifdef HAVE_CONFIG_H + #include "config.h" +#endif + +#include "tmacros.h" + +const char rtems_test_name[] = "PSXGLOBALCON 2"; + +class A { + public: + A() + { + ++i; + } + + static int i; +}; + +int A::i; + +static A a; + +static bool rtems_init_done; + +extern "C" void Init(rtems_task_argument argument) +{ + TEST_BEGIN(); + + rtems_test_assert(a.i == 1); + + rtems_init_done = true; + + rtems_task_delete(RTEMS_SELF); + rtems_test_assert(0); +} + +static void *POSIX_Init(void *argument) +{ + rtems_test_assert(rtems_init_done); + rtems_test_assert(a.i == 1); + + TEST_END(); + rtems_test_exit(0); +} + +#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER +#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER + +#define CONFIGURE_MAXIMUM_TASKS 1 +#define CONFIGURE_MAXIMUM_POSIX_THREADS 1 + +#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION + +#define CONFIGURE_RTEMS_INIT_TASKS_TABLE +#define CONFIGURE_POSIX_INIT_THREAD_TABLE + +#define CONFIGURE_INIT + +#include diff --git a/testsuites/psxtests/psxglobalcon02/psxglobalcon02.doc b/testsuites/psxtests/psxglobalcon02/psxglobalcon02.doc new file mode 100644 index 0000000000..4dc5bde09d --- /dev/null +++ b/testsuites/psxtests/psxglobalcon02/psxglobalcon02.doc @@ -0,0 +1,12 @@ +This file describes the directives and concepts tested by this test set. + +test set name: psxglobalcon02 + +directives: + + - _Thread_Global_construction() + +concepts: + + - Ensure that the global construction is performed exactly once in case a + RTEMS initialization task and a POSIX initialization thread are present. diff --git a/testsuites/psxtests/psxglobalcon02/psxglobalcon02.scn b/testsuites/psxtests/psxglobalcon02/psxglobalcon02.scn new file mode 100644 index 0000000000..54ae33b5f6 --- /dev/null +++ b/testsuites/psxtests/psxglobalcon02/psxglobalcon02.scn @@ -0,0 +1,2 @@ +*** BEGIN OF TEST PSXGLOBALCON 2 *** +*** END OF TEST PSXGLOBALCON 2 *** diff --git a/testsuites/sptests/Makefile.am b/testsuites/sptests/Makefile.am index 7764a3e8f8..a71c02436f 100644 --- a/testsuites/sptests/Makefile.am +++ b/testsuites/sptests/Makefile.am @@ -50,6 +50,7 @@ _SUBDIRS += spcache01 _SUBDIRS += sptls03 _SUBDIRS += spcpucounter01 if HAS_CPLUSPLUS +_SUBDIRS += spglobalcon01 _SUBDIRS += sptls02 endif _SUBDIRS += sptls01 diff --git a/testsuites/sptests/configure.ac b/testsuites/sptests/configure.ac index 282cbcf304..5acf7c0d75 100644 --- a/testsuites/sptests/configure.ac +++ b/testsuites/sptests/configure.ac @@ -40,6 +40,7 @@ AM_CONDITIONAL(HAS_SMP,test "$rtems_cv_RTEMS_SMP" = "yes") # Explicitly list all Makefiles here AC_CONFIG_FILES([Makefile +spglobalcon01/Makefile spintrcritical22/Makefile spsem03/Makefile spresource01/Makefile diff --git a/testsuites/sptests/spglobalcon01/Makefile.am b/testsuites/sptests/spglobalcon01/Makefile.am new file mode 100644 index 0000000000..a7d94af8fb --- /dev/null +++ b/testsuites/sptests/spglobalcon01/Makefile.am @@ -0,0 +1,19 @@ +rtems_tests_PROGRAMS = spglobalcon01 +spglobalcon01_SOURCES = init.cc + +dist_rtems_tests_DATA = spglobalcon01.scn spglobalcon01.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 = $(spglobalcon01_OBJECTS) +LINK_LIBS = $(spglobalcon01_LDLIBS) + +spglobalcon01$(EXEEXT): $(spglobalcon01_OBJECTS) $(spglobalcon01_DEPENDENCIES) + @rm -f spglobalcon01$(EXEEXT) + $(make-exe) + +include $(top_srcdir)/../automake/local.am diff --git a/testsuites/sptests/spglobalcon01/init.cc b/testsuites/sptests/spglobalcon01/init.cc new file mode 100644 index 0000000000..92a8a2c141 --- /dev/null +++ b/testsuites/sptests/spglobalcon01/init.cc @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2014 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Dornierstr. 4 + * 82178 Puchheim + * Germany + * + * + * 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. + */ + +#ifdef HAVE_CONFIG_H + #include "config.h" +#endif + +#define TESTS_USE_PRINTK +#include "tmacros.h" + +const char rtems_test_name[] = "SPGLOBALCON 1"; + +class A { + public: + A() + { + ++i; + } + + static int i; +}; + +int A::i; + +static A a; + +static void *idle_body(uintptr_t ignored) +{ + TEST_BEGIN(); + + rtems_test_assert(a.i == 0); + + TEST_END(); + rtems_test_exit(0); + + return NULL; +} + +#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER +#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER + +#define CONFIGURE_IDLE_TASK_INITIALIZES_APPLICATION + +#define CONFIGURE_IDLE_TASK_BODY idle_body + +#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION + +#define CONFIGURE_INIT + +#include diff --git a/testsuites/sptests/spglobalcon01/spglobalcon01.doc b/testsuites/sptests/spglobalcon01/spglobalcon01.doc new file mode 100644 index 0000000000..48c64c6aa1 --- /dev/null +++ b/testsuites/sptests/spglobalcon01/spglobalcon01.doc @@ -0,0 +1,12 @@ +This file describes the directives and concepts tested by this test set. + +test set name: spglobalcon01 + +directives: + + - _Thread_Global_construction() + +concepts: + + - Ensure that the global construction is not performed in case the idle + thread initializes the application. diff --git a/testsuites/sptests/spglobalcon01/spglobalcon01.scn b/testsuites/sptests/spglobalcon01/spglobalcon01.scn new file mode 100644 index 0000000000..b15a43187b --- /dev/null +++ b/testsuites/sptests/spglobalcon01/spglobalcon01.scn @@ -0,0 +1,2 @@ +*** BEGIN OF TEST SPGLOBALCON 1 *** +*** END OF TEST SPGLOBALCON 1 *** diff --git a/testsuites/sptests/spthreadlife01/init.c b/testsuites/sptests/spthreadlife01/init.c index 4e6c98487b..f4005169de 100644 --- a/testsuites/sptests/spthreadlife01/init.c +++ b/testsuites/sptests/spthreadlife01/init.c @@ -136,17 +136,21 @@ static void restart_extension( rtems_status_code sc; rtems_test_assert(executing == restarted); - rtems_test_assert(ctx->worker_task_id == rtems_task_self()); switch (ctx->current) { case RESTART_0: + rtems_test_assert(ctx->worker_task_id == rtems_task_self()); ctx->current = RESTART_1; sc = rtems_task_restart(RTEMS_SELF, 0); rtems_test_assert(sc == RTEMS_SUCCESSFUL); break; case RESTART_1: + rtems_test_assert(ctx->worker_task_id == rtems_task_self()); ctx->current = RESTART_2; break; + case INIT: + /* Restart via _Thread_Global_construction() */ + break; default: rtems_test_assert(0); break; -- cgit v1.2.3