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
|
* @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
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -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
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -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
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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 );
|
||||||
|
|||||||
@@ -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 " | ",
|
||||||
|
|||||||
@@ -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 ) );
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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)
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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 );
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 );
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -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 )
|
||||||
|
|||||||
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
|
#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();
|
||||||
|
|||||||
@@ -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 *).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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 ) {
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -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 )
|
||||||
|
|||||||
Reference in New Issue
Block a user