forked from Imagelibrary/rtems
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.
This commit is contained in:
@@ -34,6 +34,7 @@
|
||||
#include <rtems/posix/priorityimpl.h>
|
||||
#include <rtems/posix/config.h>
|
||||
#include <rtems/posix/time.h>
|
||||
#include <rtems/rtems/config.h>
|
||||
|
||||
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 )
|
||||
|
||||
@@ -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 ) )
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
|
||||
94
cpukit/score/src/threadglobalconstruction.c
Normal file
94
cpukit/score/src/threadglobalconstruction.c
Normal file
@@ -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 <rtems/score/threadimpl.h>
|
||||
#include <rtems/score/assert.h>
|
||||
#include <rtems/rtems/config.h>
|
||||
#include <rtems/posix/config.h>
|
||||
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
@@ -24,76 +24,11 @@
|
||||
#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(__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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
19
testsuites/psxtests/psxglobalcon01/Makefile.am
Normal file
19
testsuites/psxtests/psxglobalcon01/Makefile.am
Normal file
@@ -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
|
||||
58
testsuites/psxtests/psxglobalcon01/init.cc
Normal file
58
testsuites/psxtests/psxglobalcon01/init.cc
Normal file
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (c) 2014 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.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 <rtems/confdefs.h>
|
||||
12
testsuites/psxtests/psxglobalcon01/psxglobalcon01.doc
Normal file
12
testsuites/psxtests/psxglobalcon01/psxglobalcon01.doc
Normal file
@@ -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.
|
||||
2
testsuites/psxtests/psxglobalcon01/psxglobalcon01.scn
Normal file
2
testsuites/psxtests/psxglobalcon01/psxglobalcon01.scn
Normal file
@@ -0,0 +1,2 @@
|
||||
*** BEGIN OF TEST PSXGLOBALCON 1 ***
|
||||
*** END OF TEST PSXGLOBALCON 1 ***
|
||||
19
testsuites/psxtests/psxglobalcon02/Makefile.am
Normal file
19
testsuites/psxtests/psxglobalcon02/Makefile.am
Normal file
@@ -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
|
||||
73
testsuites/psxtests/psxglobalcon02/init.cc
Normal file
73
testsuites/psxtests/psxglobalcon02/init.cc
Normal file
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright (c) 2014 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.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 <rtems/confdefs.h>
|
||||
12
testsuites/psxtests/psxglobalcon02/psxglobalcon02.doc
Normal file
12
testsuites/psxtests/psxglobalcon02/psxglobalcon02.doc
Normal file
@@ -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.
|
||||
2
testsuites/psxtests/psxglobalcon02/psxglobalcon02.scn
Normal file
2
testsuites/psxtests/psxglobalcon02/psxglobalcon02.scn
Normal file
@@ -0,0 +1,2 @@
|
||||
*** BEGIN OF TEST PSXGLOBALCON 2 ***
|
||||
*** END OF TEST PSXGLOBALCON 2 ***
|
||||
@@ -50,6 +50,7 @@ _SUBDIRS += spcache01
|
||||
_SUBDIRS += sptls03
|
||||
_SUBDIRS += spcpucounter01
|
||||
if HAS_CPLUSPLUS
|
||||
_SUBDIRS += spglobalcon01
|
||||
_SUBDIRS += sptls02
|
||||
endif
|
||||
_SUBDIRS += sptls01
|
||||
|
||||
@@ -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
|
||||
|
||||
19
testsuites/sptests/spglobalcon01/Makefile.am
Normal file
19
testsuites/sptests/spglobalcon01/Makefile.am
Normal file
@@ -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
|
||||
61
testsuites/sptests/spglobalcon01/init.cc
Normal file
61
testsuites/sptests/spglobalcon01/init.cc
Normal file
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (c) 2014 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.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 <rtems/confdefs.h>
|
||||
12
testsuites/sptests/spglobalcon01/spglobalcon01.doc
Normal file
12
testsuites/sptests/spglobalcon01/spglobalcon01.doc
Normal file
@@ -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.
|
||||
2
testsuites/sptests/spglobalcon01/spglobalcon01.scn
Normal file
2
testsuites/sptests/spglobalcon01/spglobalcon01.scn
Normal file
@@ -0,0 +1,2 @@
|
||||
*** BEGIN OF TEST SPGLOBALCON 1 ***
|
||||
*** END OF TEST SPGLOBALCON 1 ***
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user