score: Introduce Thread_Entry_information

This avoids potential dead code in _Thread_Handler().  It gets rid of
the dangerous function pointer casts.

Update #2514.
This commit is contained in:
Sebastian Huber
2016-01-07 09:55:45 +01:00
parent 3d1becf925
commit ccd54344d9
36 changed files with 234 additions and 198 deletions

View File

@@ -45,7 +45,7 @@ extern "C" {
/** /**
* @brief Support for simulated clock tick * @brief Support for simulated clock tick
*/ */
Thread clock_driver_sim_idle_body(uintptr_t); void *clock_driver_sim_idle_body(uintptr_t);
#define BSP_IDLE_TASK_BODY clock_driver_sim_idle_body #define BSP_IDLE_TASK_BODY clock_driver_sim_idle_body
/* /*

View File

@@ -56,7 +56,7 @@ extern "C" {
* *
* @{ * @{
*/ */
Thread clock_driver_sim_idle_body(uintptr_t); void *clock_driver_sim_idle_body(uintptr_t);
#define BSP_IDLE_TASK_BODY clock_driver_sim_idle_body #define BSP_IDLE_TASK_BODY clock_driver_sim_idle_body
/** @} */ /** @} */

View File

@@ -198,7 +198,7 @@ void rtems_irq_mngt_init(void); /* from 'irq_init.c' */
* *
* @brief Clock Tick Support Package * @brief Clock Tick Support Package
*/ */
Thread clock_driver_sim_idle_body(uintptr_t); void *clock_driver_sim_idle_body(uintptr_t);
#define BSP_IDLE_TASK_BODY clock_driver_sim_idle_body #define BSP_IDLE_TASK_BODY clock_driver_sim_idle_body
/* /*
* hack to kill some time. Hopefully hitting a hardware register is slower * hack to kill some time. Hopefully hitting a hardware register is slower

View File

@@ -42,7 +42,7 @@ extern "C" {
* @brief Clock Tick Support Package * @brief Clock Tick Support Package
*/ */
Thread clock_driver_sim_idle_body(uintptr_t); void *clock_driver_sim_idle_body(uintptr_t);
#define BSP_IDLE_TASK_BODY clock_driver_sim_idle_body #define BSP_IDLE_TASK_BODY clock_driver_sim_idle_body
#ifdef __cplusplus #ifdef __cplusplus

View File

@@ -28,7 +28,7 @@ extern "C" {
#endif #endif
/* support for simulated clock tick */ /* support for simulated clock tick */
Thread clock_driver_sim_idle_body(uintptr_t); void *clock_driver_sim_idle_body(uintptr_t);
#define BSP_IDLE_TASK_BODY clock_driver_sim_idle_body #define BSP_IDLE_TASK_BODY clock_driver_sim_idle_body
#ifdef __cplusplus #ifdef __cplusplus

View File

@@ -44,7 +44,7 @@ extern "C" {
/* Constants */ /* Constants */
Thread clock_driver_sim_idle_body(uintptr_t); void *clock_driver_sim_idle_body(uintptr_t);
#define BSP_IDLE_TASK_BODY clock_driver_sim_idle_body #define BSP_IDLE_TASK_BODY clock_driver_sim_idle_body
/* /*

View File

@@ -46,7 +46,7 @@ volatile bool clock_driver_enabled;
* fake time passing. This will not let preemption from an * fake time passing. This will not let preemption from an
* interrupt work but is enough for many tests. * interrupt work but is enough for many tests.
*/ */
Thread clock_driver_sim_idle_body( void *clock_driver_sim_idle_body(
uintptr_t ignored uintptr_t ignored
) )
{ {

View File

@@ -105,8 +105,8 @@ rtems_isr Clock_isr(
while ( while (
_Thread_Heir == _Thread_Executing _Thread_Heir == _Thread_Executing
&& _Thread_Executing->Start.entry_point && _Thread_Executing->Start.Entry.Kinds.Idle.entry
== (Thread_Entry) rtems_configuration_get_idle_task() == rtems_configuration_get_idle_task()
) { ) {
_Timecounter_Tick_simple(interval, (*tc->tc_get_timecount)(tc)); _Timecounter_Tick_simple(interval, (*tc->tc_get_timecount)(tc));
} }

View File

@@ -26,7 +26,7 @@ extern "C" {
/* support for simulated clock tick */ /* support for simulated clock tick */
/* /*
Thread clock_driver_sim_idle_body(uintptr_t); void *clock_driver_sim_idle_body(uintptr_t);
#define BSP_IDLE_TASK_BODY clock_driver_sim_idle_body #define BSP_IDLE_TASK_BODY clock_driver_sim_idle_body
*/ */

View File

@@ -27,7 +27,7 @@ extern "C" {
/* support for simulated clock tick */ /* support for simulated clock tick */
/* /*
Thread clock_driver_sim_idle_body(uintptr_t); void *clock_driver_sim_idle_body(uintptr_t);
#define BSP_IDLE_TASK_BODY clock_driver_sim_idle_body #define BSP_IDLE_TASK_BODY clock_driver_sim_idle_body
*/ */

View File

@@ -28,7 +28,7 @@ extern "C" {
#endif #endif
/* support for simulated clock tick */ /* support for simulated clock tick */
Thread clock_driver_sim_idle_body(uintptr_t); void *clock_driver_sim_idle_body(uintptr_t);
#define BSP_IDLE_TASK_BODY clock_driver_sim_idle_body #define BSP_IDLE_TASK_BODY clock_driver_sim_idle_body
#ifdef __cplusplus #ifdef __cplusplus

View File

@@ -37,8 +37,8 @@ static rtems_isr clockISR(rtems_vector_number vector) {
rtems_clock_tick(); rtems_clock_tick();
} while ( } while (
_Thread_Heir == _Thread_Executing _Thread_Heir == _Thread_Executing
&& _Thread_Executing->Start.entry_point && _Thread_Executing->Start.Entry.Kinds.Idle.entry
== (Thread_Entry) rtems_configuration_get_idle_task() == rtems_configuration_get_idle_task()
); );
#else #else
rtems_clock_tick(); rtems_clock_tick();

View File

@@ -107,8 +107,8 @@ static void clockHandler(void)
while ( while (
_Thread_Heir == _Thread_Executing _Thread_Heir == _Thread_Executing
&& _Thread_Executing->Start.entry_point && _Thread_Executing->Start.Entry.Kinds.Idle.entry
== (Thread_Entry) rtems_configuration_get_idle_task() == rtems_configuration_get_idle_task()
) { ) {
tb += Clock_Decrementer_value; tb += Clock_Decrementer_value;
ppc_set_time_base( tb ); ppc_set_time_base( tb );

View File

@@ -484,7 +484,7 @@ rtems_cpuusage_top_thread (rtems_task_argument arg)
*/ */
rtems_object_get_name(thread->Object.id, sizeof(name), name); rtems_object_get_name(thread->Object.id, sizeof(name), name);
if (name[0] == '\0') if (name[0] == '\0')
snprintf(name, sizeof(name) - 1, "(%p)", thread->Start.entry_point); snprintf(name, sizeof(name) - 1, "(%p)", thread->Start.Entry.Kinds.Numeric.entry);
(*data->plugin.print)(data->plugin.context, (*data->plugin.print)(data->plugin.context,
" 0x%08" PRIx32 " | %-19s | %3" PRId32 " | %3" PRId32 " | ", " 0x%08" PRIx32 " | %-19s | %3" PRId32 " | %3" PRId32 " | ",

View File

@@ -25,8 +25,7 @@ rtems_monitor_task_canonical(
api = rtems_thread->API_Extensions[ THREAD_API_RTEMS ]; api = rtems_thread->API_Extensions[ THREAD_API_RTEMS ];
canonical_task->entry = rtems_thread->Start.entry_point; canonical_task->entry = rtems_thread->Start.Entry;
canonical_task->argument = rtems_thread->Start.numeric_argument;
canonical_task->stack = rtems_thread->Start.Initial_stack.area; canonical_task->stack = rtems_thread->Start.Initial_stack.area;
canonical_task->stack_size = rtems_thread->Start.Initial_stack.size; canonical_task->stack_size = rtems_thread->Start.Initial_stack.size;
canonical_task->cpu = _Per_CPU_Get_index( _Thread_Get_CPU( rtems_thread ) ); canonical_task->cpu = _Per_CPU_Get_index( _Thread_Get_CPU( rtems_thread ) );

View File

@@ -95,8 +95,7 @@ typedef struct {
rtems_id id; rtems_id id;
rtems_name name; rtems_name name;
/* end of common portion */ /* end of common portion */
Thread_Entry entry; Thread_Entry_information entry;
Thread_Entry_numeric_type argument;
void *stack; void *stack;
uint32_t stack_size; uint32_t stack_size;
uint32_t cpu; uint32_t cpu;

View File

@@ -52,6 +52,15 @@ int pthread_create(
void *arg void *arg
) )
{ {
Thread_Entry_information entry = {
.adaptor = _Thread_Entry_adaptor_pointer,
.Kinds = {
.Pointer = {
.entry = start_routine,
.argument = arg
}
}
};
const pthread_attr_t *the_attr; const pthread_attr_t *the_attr;
Priority_Control core_priority; Priority_Control core_priority;
Thread_CPU_budget_algorithms budget_algorithm; Thread_CPU_budget_algorithms budget_algorithm;
@@ -219,14 +228,7 @@ int pthread_create(
/* /*
* POSIX threads are allocated and started in one operation. * POSIX threads are allocated and started in one operation.
*/ */
status = _Thread_Start( status = _Thread_Start( the_thread, &entry, NULL );
the_thread,
THREAD_START_POINTER,
start_routine,
arg,
0, /* unused */
NULL
);
#if defined(RTEMS_DEBUG) #if defined(RTEMS_DEBUG)
/* /*

View File

@@ -37,11 +37,14 @@
static void *_POSIX_Global_construction( void *arg ) static void *_POSIX_Global_construction( void *arg )
{ {
Thread_Entry entry_point = (Thread_Entry) Configuration_POSIX_API 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; .User_initialization_threads_table[ 0 ].thread_entry;
(void) arg; (void) arg;
_Thread_Global_construction( entry_point ); _Thread_Global_construction( executing, &entry );
} }
void _POSIX_Threads_Initialize_user_threads_body(void) void _POSIX_Threads_Initialize_user_threads_body(void)

View File

@@ -33,11 +33,14 @@
static void _RTEMS_Global_construction( rtems_task_argument arg ) static void _RTEMS_Global_construction( rtems_task_argument arg )
{ {
Thread_Entry entry_point = (Thread_Entry) 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; Configuration_RTEMS_API.User_initialization_tasks_table[ 0 ].entry_point;
(void) arg; (void) arg;
_Thread_Global_construction( entry_point ); _Thread_Global_construction( executing, &entry );
} }
/* /*

View File

@@ -28,12 +28,15 @@ rtems_status_code rtems_task_restart(
{ {
Thread_Control *the_thread; Thread_Control *the_thread;
Objects_Locations location; Objects_Locations location;
Thread_Entry_information entry;
the_thread = _Thread_Get( id, &location ); the_thread = _Thread_Get( id, &location );
switch ( location ) { switch ( location ) {
case OBJECTS_LOCAL: case OBJECTS_LOCAL:
if ( _Thread_Restart( the_thread, _Thread_Executing, NULL, argument ) ) { entry = the_thread->Start.Entry;
entry.Kinds.Numeric.argument = argument;
if ( _Thread_Restart( the_thread, _Thread_Executing, &entry ) ) {
_Objects_Put( &the_thread->Object ); _Objects_Put( &the_thread->Object );
return RTEMS_SUCCESSFUL; return RTEMS_SUCCESSFUL;
} }

View File

@@ -44,9 +44,18 @@ rtems_status_code rtems_task_start(
rtems_task_argument argument rtems_task_argument argument
) )
{ {
Thread_Control *the_thread; Thread_Entry_information entry = {
Objects_Locations location; .adaptor = _Thread_Entry_adaptor_numeric,
bool successfully_started; .Kinds = {
.Numeric = {
.entry = entry_point,
.argument = argument
}
}
};
Thread_Control *the_thread;
Objects_Locations location;
bool successfully_started;
if ( entry_point == NULL ) if ( entry_point == NULL )
return RTEMS_INVALID_ADDRESS; return RTEMS_INVALID_ADDRESS;
@@ -55,14 +64,7 @@ rtems_status_code rtems_task_start(
switch ( location ) { switch ( location ) {
case OBJECTS_LOCAL: case OBJECTS_LOCAL:
successfully_started = _Thread_Start( successfully_started = _Thread_Start( the_thread, &entry, NULL );
the_thread,
THREAD_START_NUMERIC,
entry_point,
NULL,
argument,
NULL
);
_Objects_Put( &the_thread->Object ); _Objects_Put( &the_thread->Object );

View File

@@ -181,7 +181,7 @@ typedef struct {
* This element points to the BSP's optional idle task which may override * This element points to the BSP's optional idle task which may override
* the default one provided with RTEMS. * the default one provided with RTEMS.
*/ */
Thread (*idle_task)( uintptr_t ); void *(*idle_task)( uintptr_t );
/** /**
* This field specifies the size of the IDLE task's stack. If less than or * This field specifies the size of the IDLE task's stack. If less than or

View File

@@ -301,6 +301,9 @@ libscore_a_SOURCES += src/thread.c src/threadchangepriority.c \
src/threadsetstate.c \ src/threadsetstate.c \
src/threadstackallocate.c src/threadstackfree.c src/threadstart.c \ src/threadstackallocate.c src/threadstackfree.c src/threadstart.c \
src/threadstartmultitasking.c src/iterateoverthreads.c src/threadstartmultitasking.c src/iterateoverthreads.c
libscore_a_SOURCES += src/threadentryadaptoridle.c
libscore_a_SOURCES += src/threadentryadaptornumeric.c
libscore_a_SOURCES += src/threadentryadaptorpointer.c
libscore_a_SOURCES += src/threadglobalconstruction.c libscore_a_SOURCES += src/threadglobalconstruction.c
libscore_a_SOURCES += src/threadtimeout.c libscore_a_SOURCES += src/threadtimeout.c
libscore_a_SOURCES += src/threadyield.c libscore_a_SOURCES += src/threadyield.c

View File

@@ -88,15 +88,11 @@ extern "C" {
typedef Timestamp_Control Thread_CPU_usage_t; typedef Timestamp_Control Thread_CPU_usage_t;
/** /*
* The following defines the "return type" of a thread. * Only provided for backward compatiblity to not break application
* * configurations.
* @note This cannot always be right. Some APIs have void
* tasks/threads, others return pointers, others may
* return a numeric value. Hopefully a pointer is
* always at least as big as an uint32_t . :)
*/ */
typedef void *Thread; typedef void *Thread RTEMS_DEPRECATED;
/** /**
* @brief Type of the numeric argument of a thread entry function with at * @brief Type of the numeric argument of a thread entry function with at
@@ -110,44 +106,52 @@ typedef void *Thread;
typedef CPU_Uint32ptr Thread_Entry_numeric_type; typedef CPU_Uint32ptr Thread_Entry_numeric_type;
/** /**
* The following defines the ways in which the entry point for a * @brief Data for idle thread entry.
* thread can be invoked. Basically, it can be passed any
* combination/permutation of a pointer and an uint32_t value.
*
* @note For now, we are ignoring the return type.
*/ */
typedef enum { typedef struct {
THREAD_START_NUMERIC, void *( *entry )( uintptr_t argument );
THREAD_START_POINTER, } Thread_Entry_idle;
#if defined(FUNCTIONALITY_NOT_CURRENTLY_USED_BY_ANY_API)
THREAD_START_BOTH_POINTER_FIRST,
THREAD_START_BOTH_NUMERIC_FIRST
#endif
} Thread_Start_types;
/** This type corresponds to a very simple style thread entry point. */ /**
typedef Thread ( *Thread_Entry )( void ); /* basic type */ * @brief Data for thread entry with one numeric argument and no return value.
/** This type corresponds to a thread entry point which takes a single
* unsigned thirty-two bit integer as an argument.
*/ */
typedef Thread ( *Thread_Entry_numeric )( Thread_Entry_numeric_type ); typedef struct {
void ( *entry )( Thread_Entry_numeric_type argument );
Thread_Entry_numeric_type argument;
} Thread_Entry_numeric;
/** This type corresponds to a thread entry point which takes a single /**
* untyped pointer as an argument. * @brief Data for thread entry with one pointer argument and a pointer return
* value.
*/ */
typedef Thread ( *Thread_Entry_pointer )( void * ); typedef struct {
void *( *entry )( void *argument );
void *argument;
} Thread_Entry_pointer;
/** This type corresponds to a thread entry point which takes a single /**
* untyped pointer and an unsigned thirty-two bit integer as arguments. * @brief Thread entry information.
*/ */
typedef Thread ( *Thread_Entry_both_pointer_first )( void *, Thread_Entry_numeric_type ); typedef struct {
/**
* @brief Thread entry adaptor.
*
* Calls the corresponding thread entry with the right parameters.
*
* @param executing The executing thread.
*/
void ( *adaptor )( Thread_Control *executing );
/** This type corresponds to a thread entry point which takes a single /**
* unsigned thirty-two bit integer and an untyped pointer and an * @brief Thread entry data used by the adaptor to call the thread entry
* as arguments. * function with the right parameters.
*/ */
typedef Thread ( *Thread_Entry_both_numeric_first )( Thread_Entry_numeric_type, void * ); union {
Thread_Entry_idle Idle;
Thread_Entry_numeric Numeric;
Thread_Entry_pointer Pointer;
} Kinds;
} Thread_Entry_information;
/** /**
* The following lists the algorithms used to manage the thread cpu budget. * The following lists the algorithms used to manage the thread cpu budget.
@@ -206,14 +210,8 @@ typedef struct {
* the starting state of a thread. * the starting state of a thread.
*/ */
typedef struct { typedef struct {
/** This field is the starting address for the thread. */ /** This field contains the thread entry information. */
Thread_Entry entry_point; Thread_Entry_information Entry;
/** This field indicates the how task is invoked. */
Thread_Start_types prototype;
/** This field is the pointer argument passed at thread start. */
void *pointer_argument;
/** This field is the numeric argument passed at thread start. */
Thread_Entry_numeric_type numeric_argument;
/*-------------- initial execution modes ----------------- */ /*-------------- initial execution modes ----------------- */
/** This field indicates whether the thread was preemptible when /** This field indicates whether the thread was preemptible when
* it started. * it started.

View File

@@ -185,29 +185,22 @@ bool _Thread_Initialize(
* and makes it ready to execute. After this routine executes, the * and makes it ready to execute. After this routine executes, the
* thread competes with all other threads for CPU time. * thread competes with all other threads for CPU time.
* *
* @param the_thread is the thread to be initialized * @param the_thread The thread to be started.
* @param the_prototype * @param entry The thread entry information.
* @param entry_point
* @param pointer_argument
* @param numeric_argument
* @param[in,out] cpu The processor if used to start an idle thread * @param[in,out] cpu The processor if used to start an idle thread
* during system initialization. Must be set to @c NULL to start a normal * during system initialization. Must be set to @c NULL to start a normal
* thread. * thread.
*/ */
bool _Thread_Start( bool _Thread_Start(
Thread_Control *the_thread, Thread_Control *the_thread,
Thread_Start_types the_prototype, const Thread_Entry_information *entry,
void *entry_point, Per_CPU_Control *cpu
void *pointer_argument,
Thread_Entry_numeric_type numeric_argument,
Per_CPU_Control *cpu
); );
bool _Thread_Restart( bool _Thread_Restart(
Thread_Control *the_thread, Thread_Control *the_thread,
Thread_Control *executing, Thread_Control *executing,
void *pointer_argument, const Thread_Entry_information *entry
Thread_Entry_numeric_type numeric_argument
); );
void _Thread_Yield( Thread_Control *executing ); void _Thread_Yield( Thread_Control *executing );
@@ -300,6 +293,12 @@ void _Thread_Load_environment(
Thread_Control *the_thread Thread_Control *the_thread
); );
void _Thread_Entry_adaptor_idle( Thread_Control *executing );
void _Thread_Entry_adaptor_numeric( Thread_Control *executing );
void _Thread_Entry_adaptor_pointer( Thread_Control *executing );
/** /**
* @brief Wrapper function for all threads. * @brief Wrapper function for all threads.
* *
@@ -325,7 +324,10 @@ void _Thread_Handler( void );
* the first POSIX initialization thread in case no RTEMS initialization tasks * the first POSIX initialization thread in case no RTEMS initialization tasks
* are present. * are present.
*/ */
void _Thread_Global_construction( Thread_Entry entry_point ) RTEMS_NO_RETURN; void _Thread_Global_construction(
Thread_Control *executing,
const Thread_Entry_information *entry
) RTEMS_NO_RETURN;
/** /**
* @brief Ended the delay of a thread. * @brief Ended the delay of a thread.

View File

@@ -25,6 +25,14 @@
static void _Thread_Create_idle_for_cpu( Per_CPU_Control *cpu ) static void _Thread_Create_idle_for_cpu( Per_CPU_Control *cpu )
{ {
Thread_Entry_information entry = {
.adaptor = _Thread_Entry_adaptor_idle,
.Kinds = {
.Idle = {
.entry = rtems_configuration_get_idle_task()
}
}
};
Objects_Name name; Objects_Name name;
Thread_Control *idle; Thread_Control *idle;
@@ -59,14 +67,7 @@ static void _Thread_Create_idle_for_cpu( Per_CPU_Control *cpu )
cpu->heir = cpu->heir =
cpu->executing = idle; cpu->executing = idle;
_Thread_Start( _Thread_Start( idle, &entry, cpu );
idle,
THREAD_START_NUMERIC,
rtems_configuration_get_idle_task(),
NULL,
0,
cpu
);
} }
void _Thread_Create_idle( void ) void _Thread_Create_idle( void )

View File

@@ -0,0 +1,26 @@
/*
* Copyright (c) 2015 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.
*/
#if HAVE_CONFIG_H
#include "config.h"
#endif
#include <rtems/score/threadimpl.h>
void _Thread_Entry_adaptor_idle( Thread_Control *executing )
{
const Thread_Entry_idle *idle = &executing->Start.Entry.Kinds.Idle;
( *idle->entry )( 0 );
}

View File

@@ -0,0 +1,26 @@
/*
* Copyright (c) 2015 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.
*/
#if HAVE_CONFIG_H
#include "config.h"
#endif
#include <rtems/score/threadimpl.h>
void _Thread_Entry_adaptor_numeric( Thread_Control *executing )
{
const Thread_Entry_numeric *numeric = &executing->Start.Entry.Kinds.Numeric;
( *numeric->entry )( numeric->argument );
}

View File

@@ -0,0 +1,26 @@
/*
* Copyright (c) 2015 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.
*/
#if HAVE_CONFIG_H
#include "config.h"
#endif
#include <rtems/score/threadimpl.h>
void _Thread_Entry_adaptor_pointer( Thread_Control *executing )
{
const Thread_Entry_pointer *pointer = &executing->Start.Entry.Kinds.Pointer;
executing->Wait.return_argument = ( *pointer->entry )( pointer->argument );
}

View File

@@ -44,10 +44,11 @@
#define EXECUTE_GLOBAL_CONSTRUCTORS #define EXECUTE_GLOBAL_CONSTRUCTORS
#endif #endif
void _Thread_Global_construction( Thread_Entry entry_point ) void _Thread_Global_construction(
Thread_Control *executing,
const Thread_Entry_information *entry
)
{ {
Thread_Control *executing;
#if defined(EXECUTE_GLOBAL_CONSTRUCTORS) #if defined(EXECUTE_GLOBAL_CONSTRUCTORS)
/* /*
* _init could be a weak symbol and we SHOULD test it but it isn't * _init could be a weak symbol and we SHOULD test it but it isn't
@@ -58,17 +59,7 @@ void _Thread_Global_construction( Thread_Entry entry_point )
#endif #endif
_Thread_Disable_dispatch(); _Thread_Disable_dispatch();
_Thread_Restart( executing, executing, entry );
executing = _Thread_Executing;
executing->Start.entry_point = entry_point;
_Thread_Restart(
executing,
executing,
executing->Start.pointer_argument,
executing->Start.numeric_argument
);
_Thread_Enable_dispatch(); _Thread_Enable_dispatch();
_Assert_Not_reached(); _Assert_Not_reached();

View File

@@ -90,41 +90,12 @@ void _Thread_Handler( void )
* thread/task prototype. The following code supports invoking the * thread/task prototype. The following code supports invoking the
* user thread entry point using the prototype expected. * user thread entry point using the prototype expected.
*/ */
if ( executing->Start.prototype == THREAD_START_NUMERIC ) { ( *executing->Start.Entry.adaptor )( executing );
executing->Wait.return_argument =
(*(Thread_Entry_numeric) executing->Start.entry_point)(
executing->Start.numeric_argument
);
}
#if defined(RTEMS_POSIX_API)
else if ( executing->Start.prototype == THREAD_START_POINTER ) {
executing->Wait.return_argument =
(*(Thread_Entry_pointer) executing->Start.entry_point)(
executing->Start.pointer_argument
);
}
#endif
#if defined(FUNCTIONALITY_NOT_CURRENTLY_USED_BY_ANY_API)
else if ( executing->Start.prototype == THREAD_START_BOTH_POINTER_FIRST ) {
executing->Wait.return_argument =
(*(Thread_Entry_both_pointer_first) executing->Start.entry_point)(
executing->Start.pointer_argument,
executing->Start.numeric_argument
);
}
else if ( executing->Start.prototype == THREAD_START_BOTH_NUMERIC_FIRST ) {
executing->Wait.return_argument =
(*(Thread_Entry_both_numeric_first) executing->Start.entry_point)(
executing->Start.numeric_argument,
executing->Start.pointer_argument
);
}
#endif
/* /*
* In the switch above, the return code from the user thread body * In the call above, the return code from the user thread body which return
* was placed in return_argument. This assumed that if it returned * something was placed in return_argument. This assumed that if it
* anything (which is not supporting in all APIs), then it would be * returned anything (which is not supporting in all APIs), then it would be
* able to fit in a (void *). * able to fit in a (void *).
*/ */

View File

@@ -356,15 +356,13 @@ void _Thread_Close( Thread_Control *the_thread, Thread_Control *executing )
} }
bool _Thread_Restart( bool _Thread_Restart(
Thread_Control *the_thread, Thread_Control *the_thread,
Thread_Control *executing, Thread_Control *executing,
void *pointer_argument, const Thread_Entry_information *entry
Thread_Entry_numeric_type numeric_argument
) )
{ {
if ( !_States_Is_dormant( the_thread->current_state ) ) { if ( !_States_Is_dormant( the_thread->current_state ) ) {
the_thread->Start.pointer_argument = pointer_argument; the_thread->Start.Entry = *entry;
the_thread->Start.numeric_argument = numeric_argument;
_Thread_Request_life_change( _Thread_Request_life_change(
the_thread, the_thread,

View File

@@ -25,22 +25,13 @@
#include <rtems/score/userextimpl.h> #include <rtems/score/userextimpl.h>
bool _Thread_Start( bool _Thread_Start(
Thread_Control *the_thread, Thread_Control *the_thread,
Thread_Start_types the_prototype, const Thread_Entry_information *entry,
void *entry_point, Per_CPU_Control *cpu
void *pointer_argument,
Thread_Entry_numeric_type numeric_argument,
Per_CPU_Control *cpu
) )
{ {
if ( _States_Is_dormant( the_thread->current_state ) ) { if ( _States_Is_dormant( the_thread->current_state ) ) {
the_thread->Start.Entry = *entry;
the_thread->Start.entry_point = (Thread_Entry) entry_point;
the_thread->Start.prototype = the_prototype;
the_thread->Start.pointer_argument = pointer_argument;
the_thread->Start.numeric_argument = numeric_argument;
_Thread_Load_environment( the_thread ); _Thread_Load_environment( the_thread );
if ( cpu == NULL ) { if ( cpu == NULL ) {

View File

@@ -20,18 +20,15 @@
#include <bsp.h> #include <bsp.h>
#include <rtems/score/thread.h> #include <rtems/score/thread.h>
/* forward declarations to avoid warnings */ static void *Init( uintptr_t ignored )
rtems_task Init(rtems_task_argument argument);
rtems_task Init(
rtems_task_argument ignored
)
{ {
/* initialize application */ /* initialize application */
/* Real application would call idle loop functionality */ /* Real application would call idle loop functionality */
/* but in this case, just return and fall into a fatal error */ /* but in this case, just return and fall into a fatal error */
return NULL;
} }
/* configuration information */ /* configuration information */
@@ -98,7 +95,7 @@ rtems_task Init(
* In this application, the initialization task performs the system * In this application, the initialization task performs the system
* initialization and then transforms itself into the idle task. * initialization and then transforms itself into the idle task.
*/ */
#define CONFIGURE_IDLE_TASK_BODY (Thread_Entry_numeric) Init #define CONFIGURE_IDLE_TASK_BODY Init
#define CONFIGURE_IDLE_TASK_INITIALIZES_APPLICATION #define CONFIGURE_IDLE_TASK_INITIALIZES_APPLICATION
/* /*

View File

@@ -22,12 +22,7 @@
const char rtems_test_name[] = "SP 54"; const char rtems_test_name[] = "SP 54";
/* forward declarations to avoid warnings */ static void *Init( uintptr_t ignored )
rtems_task Init(rtems_task_argument argument);
rtems_task Init(
rtems_task_argument ignored
)
{ {
rtems_status_code status; rtems_status_code status;
rtems_task_priority pri; rtems_task_priority pri;
@@ -68,7 +63,7 @@ rtems_task Init(
* In this application, the initialization task performs the system * In this application, the initialization task performs the system
* initialization and then transforms itself into the idle task. * initialization and then transforms itself into the idle task.
*/ */
#define CONFIGURE_IDLE_TASK_BODY (Thread_Entry_numeric) Init #define CONFIGURE_IDLE_TASK_BODY Init
#define CONFIGURE_IDLE_TASK_INITIALIZES_APPLICATION #define CONFIGURE_IDLE_TASK_INITIALIZES_APPLICATION
/* /*

View File

@@ -175,8 +175,8 @@ bool interrupt_critical_section_test_support_delay(void)
static bool is_idle( const Thread_Control *thread ) static bool is_idle( const Thread_Control *thread )
{ {
return thread->Start.entry_point return thread->Start.Entry.Kinds.Idle.entry
== (Thread_Entry) rtems_configuration_get_idle_task(); == rtems_configuration_get_idle_task();
} }
static void thread_switch( Thread_Control *executing, Thread_Control *heir ) static void thread_switch( Thread_Control *executing, Thread_Control *heir )