[PATCH 1/2] score: Simplify global construction
Sebastian Huber
sebastian.huber at embedded-brains.de
Tue Nov 21 07:14:41 UTC 2017
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 at .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
+ * <rtems at 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
More information about the devel
mailing list