forked from Imagelibrary/rtems
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:
@@ -45,7 +45,7 @@ extern "C" {
|
||||
/**
|
||||
* @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
|
||||
|
||||
/*
|
||||
|
||||
@@ -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
|
||||
/** @} */
|
||||
|
||||
|
||||
@@ -198,7 +198,7 @@ void rtems_irq_mngt_init(void); /* from 'irq_init.c' */
|
||||
*
|
||||
* @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
|
||||
/*
|
||||
* hack to kill some time. Hopefully hitting a hardware register is slower
|
||||
|
||||
@@ -42,7 +42,7 @@ extern "C" {
|
||||
* @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
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -28,7 +28,7 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
/* 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
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -44,7 +44,7 @@ extern "C" {
|
||||
|
||||
/* 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
|
||||
|
||||
/*
|
||||
|
||||
@@ -46,7 +46,7 @@ volatile bool clock_driver_enabled;
|
||||
* fake time passing. This will not let preemption from an
|
||||
* interrupt work but is enough for many tests.
|
||||
*/
|
||||
Thread clock_driver_sim_idle_body(
|
||||
void *clock_driver_sim_idle_body(
|
||||
uintptr_t ignored
|
||||
)
|
||||
{
|
||||
|
||||
@@ -105,8 +105,8 @@ rtems_isr Clock_isr(
|
||||
|
||||
while (
|
||||
_Thread_Heir == _Thread_Executing
|
||||
&& _Thread_Executing->Start.entry_point
|
||||
== (Thread_Entry) rtems_configuration_get_idle_task()
|
||||
&& _Thread_Executing->Start.Entry.Kinds.Idle.entry
|
||||
== rtems_configuration_get_idle_task()
|
||||
) {
|
||||
_Timecounter_Tick_simple(interval, (*tc->tc_get_timecount)(tc));
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ extern "C" {
|
||||
|
||||
/* 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
|
||||
*/
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ extern "C" {
|
||||
|
||||
/* 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
|
||||
*/
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
/* 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
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -37,8 +37,8 @@ static rtems_isr clockISR(rtems_vector_number vector) {
|
||||
rtems_clock_tick();
|
||||
} while (
|
||||
_Thread_Heir == _Thread_Executing
|
||||
&& _Thread_Executing->Start.entry_point
|
||||
== (Thread_Entry) rtems_configuration_get_idle_task()
|
||||
&& _Thread_Executing->Start.Entry.Kinds.Idle.entry
|
||||
== rtems_configuration_get_idle_task()
|
||||
);
|
||||
#else
|
||||
rtems_clock_tick();
|
||||
|
||||
@@ -107,8 +107,8 @@ static void clockHandler(void)
|
||||
|
||||
while (
|
||||
_Thread_Heir == _Thread_Executing
|
||||
&& _Thread_Executing->Start.entry_point
|
||||
== (Thread_Entry) rtems_configuration_get_idle_task()
|
||||
&& _Thread_Executing->Start.Entry.Kinds.Idle.entry
|
||||
== rtems_configuration_get_idle_task()
|
||||
) {
|
||||
tb += Clock_Decrementer_value;
|
||||
ppc_set_time_base( tb );
|
||||
|
||||
@@ -484,7 +484,7 @@ rtems_cpuusage_top_thread (rtems_task_argument arg)
|
||||
*/
|
||||
rtems_object_get_name(thread->Object.id, sizeof(name), name);
|
||||
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,
|
||||
" 0x%08" PRIx32 " | %-19s | %3" PRId32 " | %3" PRId32 " | ",
|
||||
|
||||
@@ -25,8 +25,7 @@ rtems_monitor_task_canonical(
|
||||
|
||||
api = rtems_thread->API_Extensions[ THREAD_API_RTEMS ];
|
||||
|
||||
canonical_task->entry = rtems_thread->Start.entry_point;
|
||||
canonical_task->argument = rtems_thread->Start.numeric_argument;
|
||||
canonical_task->entry = rtems_thread->Start.Entry;
|
||||
canonical_task->stack = rtems_thread->Start.Initial_stack.area;
|
||||
canonical_task->stack_size = rtems_thread->Start.Initial_stack.size;
|
||||
canonical_task->cpu = _Per_CPU_Get_index( _Thread_Get_CPU( rtems_thread ) );
|
||||
|
||||
@@ -95,8 +95,7 @@ typedef struct {
|
||||
rtems_id id;
|
||||
rtems_name name;
|
||||
/* end of common portion */
|
||||
Thread_Entry entry;
|
||||
Thread_Entry_numeric_type argument;
|
||||
Thread_Entry_information entry;
|
||||
void *stack;
|
||||
uint32_t stack_size;
|
||||
uint32_t cpu;
|
||||
|
||||
@@ -52,6 +52,15 @@ int pthread_create(
|
||||
void *arg
|
||||
)
|
||||
{
|
||||
Thread_Entry_information entry = {
|
||||
.adaptor = _Thread_Entry_adaptor_pointer,
|
||||
.Kinds = {
|
||||
.Pointer = {
|
||||
.entry = start_routine,
|
||||
.argument = arg
|
||||
}
|
||||
}
|
||||
};
|
||||
const pthread_attr_t *the_attr;
|
||||
Priority_Control core_priority;
|
||||
Thread_CPU_budget_algorithms budget_algorithm;
|
||||
@@ -219,14 +228,7 @@ int pthread_create(
|
||||
/*
|
||||
* POSIX threads are allocated and started in one operation.
|
||||
*/
|
||||
status = _Thread_Start(
|
||||
the_thread,
|
||||
THREAD_START_POINTER,
|
||||
start_routine,
|
||||
arg,
|
||||
0, /* unused */
|
||||
NULL
|
||||
);
|
||||
status = _Thread_Start( the_thread, &entry, NULL );
|
||||
|
||||
#if defined(RTEMS_DEBUG)
|
||||
/*
|
||||
|
||||
@@ -37,11 +37,14 @@
|
||||
|
||||
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;
|
||||
|
||||
(void) arg;
|
||||
_Thread_Global_construction( entry_point );
|
||||
_Thread_Global_construction( executing, &entry );
|
||||
}
|
||||
|
||||
void _POSIX_Threads_Initialize_user_threads_body(void)
|
||||
|
||||
@@ -33,11 +33,14 @@
|
||||
|
||||
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;
|
||||
|
||||
(void) arg;
|
||||
_Thread_Global_construction( entry_point );
|
||||
_Thread_Global_construction( executing, &entry );
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -28,12 +28,15 @@ rtems_status_code rtems_task_restart(
|
||||
{
|
||||
Thread_Control *the_thread;
|
||||
Objects_Locations location;
|
||||
Thread_Entry_information entry;
|
||||
|
||||
the_thread = _Thread_Get( id, &location );
|
||||
switch ( location ) {
|
||||
|
||||
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 );
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
@@ -44,9 +44,18 @@ rtems_status_code rtems_task_start(
|
||||
rtems_task_argument argument
|
||||
)
|
||||
{
|
||||
Thread_Control *the_thread;
|
||||
Objects_Locations location;
|
||||
bool successfully_started;
|
||||
Thread_Entry_information entry = {
|
||||
.adaptor = _Thread_Entry_adaptor_numeric,
|
||||
.Kinds = {
|
||||
.Numeric = {
|
||||
.entry = entry_point,
|
||||
.argument = argument
|
||||
}
|
||||
}
|
||||
};
|
||||
Thread_Control *the_thread;
|
||||
Objects_Locations location;
|
||||
bool successfully_started;
|
||||
|
||||
if ( entry_point == NULL )
|
||||
return RTEMS_INVALID_ADDRESS;
|
||||
@@ -55,14 +64,7 @@ rtems_status_code rtems_task_start(
|
||||
switch ( location ) {
|
||||
|
||||
case OBJECTS_LOCAL:
|
||||
successfully_started = _Thread_Start(
|
||||
the_thread,
|
||||
THREAD_START_NUMERIC,
|
||||
entry_point,
|
||||
NULL,
|
||||
argument,
|
||||
NULL
|
||||
);
|
||||
successfully_started = _Thread_Start( the_thread, &entry, NULL );
|
||||
|
||||
_Objects_Put( &the_thread->Object );
|
||||
|
||||
|
||||
@@ -181,7 +181,7 @@ typedef struct {
|
||||
* This element points to the BSP's optional idle task which may override
|
||||
* 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
|
||||
|
||||
@@ -301,6 +301,9 @@ libscore_a_SOURCES += src/thread.c src/threadchangepriority.c \
|
||||
src/threadsetstate.c \
|
||||
src/threadstackallocate.c src/threadstackfree.c src/threadstart.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/threadtimeout.c
|
||||
libscore_a_SOURCES += src/threadyield.c
|
||||
|
||||
@@ -88,15 +88,11 @@ extern "C" {
|
||||
|
||||
typedef Timestamp_Control Thread_CPU_usage_t;
|
||||
|
||||
/**
|
||||
* The following defines the "return type" of a thread.
|
||||
*
|
||||
* @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 . :)
|
||||
/*
|
||||
* Only provided for backward compatiblity to not break application
|
||||
* configurations.
|
||||
*/
|
||||
typedef void *Thread;
|
||||
typedef void *Thread RTEMS_DEPRECATED;
|
||||
|
||||
/**
|
||||
* @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;
|
||||
|
||||
/**
|
||||
* The following defines the ways in which the entry point for a
|
||||
* 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.
|
||||
* @brief Data for idle thread entry.
|
||||
*/
|
||||
typedef enum {
|
||||
THREAD_START_NUMERIC,
|
||||
THREAD_START_POINTER,
|
||||
#if defined(FUNCTIONALITY_NOT_CURRENTLY_USED_BY_ANY_API)
|
||||
THREAD_START_BOTH_POINTER_FIRST,
|
||||
THREAD_START_BOTH_NUMERIC_FIRST
|
||||
#endif
|
||||
} Thread_Start_types;
|
||||
typedef struct {
|
||||
void *( *entry )( uintptr_t argument );
|
||||
} Thread_Entry_idle;
|
||||
|
||||
/** This type corresponds to a very simple style thread entry point. */
|
||||
typedef Thread ( *Thread_Entry )( void ); /* basic type */
|
||||
|
||||
/** This type corresponds to a thread entry point which takes a single
|
||||
* unsigned thirty-two bit integer as an argument.
|
||||
/**
|
||||
* @brief Data for thread entry with one numeric argument and no return value.
|
||||
*/
|
||||
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
|
||||
* as arguments.
|
||||
*/
|
||||
typedef Thread ( *Thread_Entry_both_numeric_first )( Thread_Entry_numeric_type, void * );
|
||||
/**
|
||||
* @brief Thread entry data used by the adaptor to call the thread entry
|
||||
* function with the right parameters.
|
||||
*/
|
||||
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.
|
||||
@@ -206,14 +210,8 @@ typedef struct {
|
||||
* the starting state of a thread.
|
||||
*/
|
||||
typedef struct {
|
||||
/** This field is the starting address for the thread. */
|
||||
Thread_Entry entry_point;
|
||||
/** 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;
|
||||
/** This field contains the thread entry information. */
|
||||
Thread_Entry_information Entry;
|
||||
/*-------------- initial execution modes ----------------- */
|
||||
/** This field indicates whether the thread was preemptible when
|
||||
* it started.
|
||||
|
||||
@@ -185,29 +185,22 @@ bool _Thread_Initialize(
|
||||
* and makes it ready to execute. After this routine executes, the
|
||||
* thread competes with all other threads for CPU time.
|
||||
*
|
||||
* @param the_thread is the thread to be initialized
|
||||
* @param the_prototype
|
||||
* @param entry_point
|
||||
* @param pointer_argument
|
||||
* @param numeric_argument
|
||||
* @param the_thread The thread to be started.
|
||||
* @param entry The thread entry information.
|
||||
* @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
|
||||
* thread.
|
||||
*/
|
||||
bool _Thread_Start(
|
||||
Thread_Control *the_thread,
|
||||
Thread_Start_types the_prototype,
|
||||
void *entry_point,
|
||||
void *pointer_argument,
|
||||
Thread_Entry_numeric_type numeric_argument,
|
||||
Per_CPU_Control *cpu
|
||||
Thread_Control *the_thread,
|
||||
const Thread_Entry_information *entry,
|
||||
Per_CPU_Control *cpu
|
||||
);
|
||||
|
||||
bool _Thread_Restart(
|
||||
Thread_Control *the_thread,
|
||||
Thread_Control *executing,
|
||||
void *pointer_argument,
|
||||
Thread_Entry_numeric_type numeric_argument
|
||||
Thread_Control *the_thread,
|
||||
Thread_Control *executing,
|
||||
const Thread_Entry_information *entry
|
||||
);
|
||||
|
||||
void _Thread_Yield( Thread_Control *executing );
|
||||
@@ -300,6 +293,12 @@ void _Thread_Load_environment(
|
||||
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.
|
||||
*
|
||||
@@ -325,7 +324,10 @@ void _Thread_Handler( void );
|
||||
* the first POSIX initialization thread in case no RTEMS initialization tasks
|
||||
* 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.
|
||||
|
||||
@@ -25,6 +25,14 @@
|
||||
|
||||
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;
|
||||
Thread_Control *idle;
|
||||
|
||||
@@ -59,14 +67,7 @@ static void _Thread_Create_idle_for_cpu( Per_CPU_Control *cpu )
|
||||
cpu->heir =
|
||||
cpu->executing = idle;
|
||||
|
||||
_Thread_Start(
|
||||
idle,
|
||||
THREAD_START_NUMERIC,
|
||||
rtems_configuration_get_idle_task(),
|
||||
NULL,
|
||||
0,
|
||||
cpu
|
||||
);
|
||||
_Thread_Start( idle, &entry, cpu );
|
||||
}
|
||||
|
||||
void _Thread_Create_idle( void )
|
||||
|
||||
26
cpukit/score/src/threadentryadaptoridle.c
Normal file
26
cpukit/score/src/threadentryadaptoridle.c
Normal 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 );
|
||||
}
|
||||
26
cpukit/score/src/threadentryadaptornumeric.c
Normal file
26
cpukit/score/src/threadentryadaptornumeric.c
Normal 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 );
|
||||
}
|
||||
26
cpukit/score/src/threadentryadaptorpointer.c
Normal file
26
cpukit/score/src/threadentryadaptorpointer.c
Normal 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 );
|
||||
}
|
||||
@@ -44,10 +44,11 @@
|
||||
#define EXECUTE_GLOBAL_CONSTRUCTORS
|
||||
#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)
|
||||
/*
|
||||
* _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
|
||||
|
||||
_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_Restart( executing, executing, entry );
|
||||
_Thread_Enable_dispatch();
|
||||
|
||||
_Assert_Not_reached();
|
||||
|
||||
@@ -90,41 +90,12 @@ void _Thread_Handler( void )
|
||||
* thread/task prototype. The following code supports invoking the
|
||||
* user thread entry point using the prototype expected.
|
||||
*/
|
||||
if ( executing->Start.prototype == THREAD_START_NUMERIC ) {
|
||||
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
|
||||
( *executing->Start.Entry.adaptor )( executing );
|
||||
|
||||
/*
|
||||
* In the switch above, the return code from the user thread body
|
||||
* was placed in return_argument. This assumed that if it returned
|
||||
* anything (which is not supporting in all APIs), then it would be
|
||||
* In the call above, the return code from the user thread body which return
|
||||
* something was placed in return_argument. This assumed that if it
|
||||
* returned anything (which is not supporting in all APIs), then it would be
|
||||
* able to fit in a (void *).
|
||||
*/
|
||||
|
||||
|
||||
@@ -356,15 +356,13 @@ void _Thread_Close( Thread_Control *the_thread, Thread_Control *executing )
|
||||
}
|
||||
|
||||
bool _Thread_Restart(
|
||||
Thread_Control *the_thread,
|
||||
Thread_Control *executing,
|
||||
void *pointer_argument,
|
||||
Thread_Entry_numeric_type numeric_argument
|
||||
Thread_Control *the_thread,
|
||||
Thread_Control *executing,
|
||||
const Thread_Entry_information *entry
|
||||
)
|
||||
{
|
||||
if ( !_States_Is_dormant( the_thread->current_state ) ) {
|
||||
the_thread->Start.pointer_argument = pointer_argument;
|
||||
the_thread->Start.numeric_argument = numeric_argument;
|
||||
the_thread->Start.Entry = *entry;
|
||||
|
||||
_Thread_Request_life_change(
|
||||
the_thread,
|
||||
|
||||
@@ -25,22 +25,13 @@
|
||||
#include <rtems/score/userextimpl.h>
|
||||
|
||||
bool _Thread_Start(
|
||||
Thread_Control *the_thread,
|
||||
Thread_Start_types the_prototype,
|
||||
void *entry_point,
|
||||
void *pointer_argument,
|
||||
Thread_Entry_numeric_type numeric_argument,
|
||||
Per_CPU_Control *cpu
|
||||
Thread_Control *the_thread,
|
||||
const Thread_Entry_information *entry,
|
||||
Per_CPU_Control *cpu
|
||||
)
|
||||
{
|
||||
if ( _States_Is_dormant( the_thread->current_state ) ) {
|
||||
|
||||
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;
|
||||
|
||||
the_thread->Start.Entry = *entry;
|
||||
_Thread_Load_environment( the_thread );
|
||||
|
||||
if ( cpu == NULL ) {
|
||||
|
||||
@@ -20,18 +20,15 @@
|
||||
#include <bsp.h>
|
||||
#include <rtems/score/thread.h>
|
||||
|
||||
/* forward declarations to avoid warnings */
|
||||
rtems_task Init(rtems_task_argument argument);
|
||||
|
||||
rtems_task Init(
|
||||
rtems_task_argument ignored
|
||||
)
|
||||
static void *Init( uintptr_t ignored )
|
||||
{
|
||||
/* initialize application */
|
||||
|
||||
/* Real application would call idle loop functionality */
|
||||
|
||||
/* but in this case, just return and fall into a fatal error */
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* configuration information */
|
||||
@@ -98,7 +95,7 @@ rtems_task Init(
|
||||
* In this application, the initialization task performs the system
|
||||
* 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
|
||||
|
||||
/*
|
||||
|
||||
@@ -22,12 +22,7 @@
|
||||
|
||||
const char rtems_test_name[] = "SP 54";
|
||||
|
||||
/* forward declarations to avoid warnings */
|
||||
rtems_task Init(rtems_task_argument argument);
|
||||
|
||||
rtems_task Init(
|
||||
rtems_task_argument ignored
|
||||
)
|
||||
static void *Init( uintptr_t ignored )
|
||||
{
|
||||
rtems_status_code status;
|
||||
rtems_task_priority pri;
|
||||
@@ -68,7 +63,7 @@ rtems_task Init(
|
||||
* In this application, the initialization task performs the system
|
||||
* 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
|
||||
|
||||
/*
|
||||
|
||||
@@ -175,8 +175,8 @@ bool interrupt_critical_section_test_support_delay(void)
|
||||
|
||||
static bool is_idle( const Thread_Control *thread )
|
||||
{
|
||||
return thread->Start.entry_point
|
||||
== (Thread_Entry) rtems_configuration_get_idle_task();
|
||||
return thread->Start.Entry.Kinds.Idle.entry
|
||||
== rtems_configuration_get_idle_task();
|
||||
}
|
||||
|
||||
static void thread_switch( Thread_Control *executing, Thread_Control *heir )
|
||||
|
||||
Reference in New Issue
Block a user