score: Simplify global construction

Update #3243.
This commit is contained in:
Sebastian Huber
2017-11-22 09:40:22 +01:00
parent a8bf9a3f7a
commit a7dcef97e9
13 changed files with 192 additions and 122 deletions
+4 -22
View File
@@ -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;
}
}
}
+4 -20
View File
@@ -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;
}
}
}
-1
View File
@@ -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
+10 -13
View File
@@ -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
@@ -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 );
}
+46
View File
@@ -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
+1
View File
@@ -64,6 +64,7 @@ _SUBDIRS += spfatal28
_SUBDIRS += spthreadlife01
_SUBDIRS += spcache01
_SUBDIRS += sptls03
_SUBDIRS += sptls04
_SUBDIRS += spcpucounter01
if HAS_CPLUSPLUS
_SUBDIRS += spglobalcon01
+1
View File
@@ -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
+3 -3
View File
@@ -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'),
+19
View File
@@ -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
+85
View File
@@ -0,0 +1,85 @@
/*
* Copyright (c) 2017 embedded brains GmbH. All rights reserved.
*
* embedded brains GmbH
* Dornierstr. 4
* 82178 Puchheim
* Germany
* <rtems@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__ */
+12
View File
@@ -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.
+7
View File
@@ -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 ***