forked from Imagelibrary/rtems
score: Add Thread_Configuration
Add the Thread_Configuration structure to reduce the parameter count of _Thread_Initialize(). This makes it easier to add more parameters in the future. It simplifies the code generation since most architectures do not have that many registers available for function parameters. Update #3835.
This commit is contained in:
@@ -124,6 +124,61 @@ void _Thread_Create_idle(void);
|
|||||||
*/
|
*/
|
||||||
void _Thread_Start_multitasking( void ) RTEMS_NO_RETURN;
|
void _Thread_Start_multitasking( void ) RTEMS_NO_RETURN;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief The configuration of a new thread to initialize.
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
/**
|
||||||
|
* @brief The scheduler control instance for the thread.
|
||||||
|
*/
|
||||||
|
const struct _Scheduler_Control *scheduler;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief The starting address of the thread area.
|
||||||
|
*/
|
||||||
|
void *stack_area;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief The size of the thread area in bytes.
|
||||||
|
*/
|
||||||
|
size_t stack_size;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief The new thread's priority.
|
||||||
|
*/
|
||||||
|
Priority_Control priority;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief The thread's budget algorithm.
|
||||||
|
*/
|
||||||
|
Thread_CPU_budget_algorithms budget_algorithm;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief The thread's initial budget callout.
|
||||||
|
*/
|
||||||
|
Thread_CPU_budget_algorithm_callout budget_callout;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Name of the object for the thread.
|
||||||
|
*/
|
||||||
|
Objects_Name name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief The thread's initial ISR level.
|
||||||
|
*/
|
||||||
|
uint32_t isr_level;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Indicates whether the thread needs a floating-point area.
|
||||||
|
*/
|
||||||
|
bool is_fp;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Indicates whether the new thread is preemptible.
|
||||||
|
*/
|
||||||
|
bool is_preemptible;
|
||||||
|
} Thread_Configuration;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Initializes thread.
|
* @brief Initializes thread.
|
||||||
*
|
*
|
||||||
@@ -138,34 +193,16 @@ void _Thread_Start_multitasking( void ) RTEMS_NO_RETURN;
|
|||||||
* guaranteed to be of at least minimum size.
|
* guaranteed to be of at least minimum size.
|
||||||
*
|
*
|
||||||
* @param information The thread information.
|
* @param information The thread information.
|
||||||
* @param[out] the_thread The thread to initialize.
|
* @param the_thread The thread to initialize.
|
||||||
* @param scheduler The scheduler control instance for the thread.
|
* @param config The configuration of the thread to initialize.
|
||||||
* @param stack_area The starting address of the thread area.
|
|
||||||
* @param stack_size The size of the thread area in bytes.
|
|
||||||
* @param is_fp Indicates whether the thread needs a floating point area.
|
|
||||||
* @param priority The new thread's priority.
|
|
||||||
* @param is_preemptible Indicates whether the new thread is preemptible.
|
|
||||||
* @param budget_algorithm The thread's budget algorithm.
|
|
||||||
* @param budget_callout The thread's initial budget callout.
|
|
||||||
* @param isr_level The thread's initial isr level.
|
|
||||||
* @param name Name of the object for the thread.
|
|
||||||
*
|
*
|
||||||
* @retval true The thread initialization was successful.
|
* @retval true The thread initialization was successful.
|
||||||
* @retval false The thread initialization failed.
|
* @retval false The thread initialization failed.
|
||||||
*/
|
*/
|
||||||
bool _Thread_Initialize(
|
bool _Thread_Initialize(
|
||||||
Thread_Information *information,
|
Thread_Information *information,
|
||||||
Thread_Control *the_thread,
|
Thread_Control *the_thread,
|
||||||
const struct _Scheduler_Control *scheduler,
|
const Thread_Configuration *config
|
||||||
void *stack_area,
|
|
||||||
size_t stack_size,
|
|
||||||
bool is_fp,
|
|
||||||
Priority_Control priority,
|
|
||||||
bool is_preemptible,
|
|
||||||
Thread_CPU_budget_algorithms budget_algorithm,
|
|
||||||
Thread_CPU_budget_algorithm_callout budget_callout,
|
|
||||||
uint32_t isr_level,
|
|
||||||
Objects_Name name
|
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -39,6 +39,8 @@
|
|||||||
#include <rtems/score/userextimpl.h>
|
#include <rtems/score/userextimpl.h>
|
||||||
#include <rtems/sysinit.h>
|
#include <rtems/sysinit.h>
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
static inline size_t _POSIX_Threads_Ensure_minimum_stack (
|
static inline size_t _POSIX_Threads_Ensure_minimum_stack (
|
||||||
size_t size
|
size_t size
|
||||||
)
|
)
|
||||||
@@ -68,18 +70,12 @@ int pthread_create(
|
|||||||
const pthread_attr_t *the_attr;
|
const pthread_attr_t *the_attr;
|
||||||
int normal_prio;
|
int normal_prio;
|
||||||
bool valid;
|
bool valid;
|
||||||
Priority_Control core_normal_prio;
|
Thread_Configuration config;
|
||||||
Thread_CPU_budget_algorithms budget_algorithm;
|
|
||||||
Thread_CPU_budget_algorithm_callout budget_callout;
|
|
||||||
bool is_fp;
|
|
||||||
bool status;
|
bool status;
|
||||||
Thread_Control *the_thread;
|
Thread_Control *the_thread;
|
||||||
Thread_Control *executing;
|
Thread_Control *executing;
|
||||||
const Scheduler_Control *scheduler;
|
|
||||||
int schedpolicy = SCHED_RR;
|
int schedpolicy = SCHED_RR;
|
||||||
struct sched_param schedparam;
|
struct sched_param schedparam;
|
||||||
size_t stacksize;
|
|
||||||
Objects_Name name;
|
|
||||||
int error;
|
int error;
|
||||||
ISR_lock_Context lock_context;
|
ISR_lock_Context lock_context;
|
||||||
#if defined(RTEMS_POSIX_API)
|
#if defined(RTEMS_POSIX_API)
|
||||||
@@ -96,11 +92,15 @@ int pthread_create(
|
|||||||
if ( !the_attr->is_initialized )
|
if ( !the_attr->is_initialized )
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
|
|
||||||
|
memset( &config, 0, sizeof( config ) );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Currently all POSIX threads are floating point if the hardware
|
* Currently all POSIX threads are floating point if the hardware
|
||||||
* supports it.
|
* supports it.
|
||||||
*/
|
*/
|
||||||
is_fp = true;
|
config.is_fp = true;
|
||||||
|
|
||||||
|
config.is_preemptible = true;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Core Thread Initialize ensures we get the minimum amount of
|
* Core Thread Initialize ensures we get the minimum amount of
|
||||||
@@ -110,13 +110,16 @@ int pthread_create(
|
|||||||
* twice the minimum.
|
* twice the minimum.
|
||||||
*/
|
*/
|
||||||
if ( the_attr->stackaddr != NULL ) {
|
if ( the_attr->stackaddr != NULL ) {
|
||||||
if ( !_Stack_Is_enough( the_attr->stacksize, is_fp ) ) {
|
if ( !_Stack_Is_enough( the_attr->stacksize, config.is_fp ) ) {
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
stacksize = the_attr->stacksize;
|
config.stack_area = the_attr->stackaddr;
|
||||||
|
config.stack_size = the_attr->stacksize;
|
||||||
} else {
|
} else {
|
||||||
stacksize = _POSIX_Threads_Ensure_minimum_stack( the_attr->stacksize );
|
config.stack_size = _POSIX_Threads_Ensure_minimum_stack(
|
||||||
|
the_attr->stacksize
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
@@ -164,8 +167,8 @@ int pthread_create(
|
|||||||
error = _POSIX_Thread_Translate_sched_param(
|
error = _POSIX_Thread_Translate_sched_param(
|
||||||
schedpolicy,
|
schedpolicy,
|
||||||
&schedparam,
|
&schedparam,
|
||||||
&budget_algorithm,
|
&config.budget_algorithm,
|
||||||
&budget_callout
|
&config.budget_callout
|
||||||
);
|
);
|
||||||
if ( error != 0 ) {
|
if ( error != 0 ) {
|
||||||
return error;
|
return error;
|
||||||
@@ -173,9 +176,13 @@ int pthread_create(
|
|||||||
|
|
||||||
normal_prio = schedparam.sched_priority;
|
normal_prio = schedparam.sched_priority;
|
||||||
|
|
||||||
scheduler = _Thread_Scheduler_get_home( executing );
|
config.scheduler = _Thread_Scheduler_get_home( executing );
|
||||||
|
|
||||||
core_normal_prio = _POSIX_Priority_To_core( scheduler, normal_prio, &valid );
|
config.priority = _POSIX_Priority_To_core(
|
||||||
|
config.scheduler,
|
||||||
|
normal_prio,
|
||||||
|
&valid
|
||||||
|
);
|
||||||
if ( !valid ) {
|
if ( !valid ) {
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
@@ -187,7 +194,7 @@ int pthread_create(
|
|||||||
low_prio = normal_prio;
|
low_prio = normal_prio;
|
||||||
}
|
}
|
||||||
|
|
||||||
core_low_prio = _POSIX_Priority_To_core( scheduler, low_prio, &valid );
|
core_low_prio = _POSIX_Priority_To_core( config.scheduler, low_prio, &valid );
|
||||||
if ( !valid ) {
|
if ( !valid ) {
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
@@ -211,20 +218,10 @@ int pthread_create(
|
|||||||
/*
|
/*
|
||||||
* Initialize the core thread for this task.
|
* Initialize the core thread for this task.
|
||||||
*/
|
*/
|
||||||
name.name_p = NULL; /* posix threads don't have a name by default */
|
|
||||||
status = _Thread_Initialize(
|
status = _Thread_Initialize(
|
||||||
&_POSIX_Threads_Information,
|
&_POSIX_Threads_Information,
|
||||||
the_thread,
|
the_thread,
|
||||||
scheduler,
|
&config
|
||||||
the_attr->stackaddr,
|
|
||||||
stacksize,
|
|
||||||
is_fp,
|
|
||||||
core_normal_prio,
|
|
||||||
true, /* preemptible */
|
|
||||||
budget_algorithm,
|
|
||||||
budget_callout,
|
|
||||||
0, /* isr level */
|
|
||||||
name /* posix threads don't have a name */
|
|
||||||
);
|
);
|
||||||
if ( !status ) {
|
if ( !status ) {
|
||||||
_POSIX_Threads_Free( the_thread );
|
_POSIX_Threads_Free( the_thread );
|
||||||
|
|||||||
@@ -30,6 +30,8 @@
|
|||||||
#include <rtems/score/userextimpl.h>
|
#include <rtems/score/userextimpl.h>
|
||||||
#include <rtems/sysinit.h>
|
#include <rtems/sysinit.h>
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
rtems_status_code rtems_task_create(
|
rtems_status_code rtems_task_create(
|
||||||
rtems_name name,
|
rtems_name name,
|
||||||
rtems_task_priority initial_priority,
|
rtems_task_priority initial_priority,
|
||||||
@@ -40,8 +42,7 @@ rtems_status_code rtems_task_create(
|
|||||||
)
|
)
|
||||||
{
|
{
|
||||||
Thread_Control *the_thread;
|
Thread_Control *the_thread;
|
||||||
const Scheduler_Control *scheduler;
|
Thread_Configuration config;
|
||||||
bool is_fp;
|
|
||||||
#if defined(RTEMS_MULTIPROCESSING)
|
#if defined(RTEMS_MULTIPROCESSING)
|
||||||
Objects_MP_Control *the_global_object = NULL;
|
Objects_MP_Control *the_global_object = NULL;
|
||||||
bool is_global;
|
bool is_global;
|
||||||
@@ -49,11 +50,9 @@ rtems_status_code rtems_task_create(
|
|||||||
bool status;
|
bool status;
|
||||||
rtems_attribute the_attribute_set;
|
rtems_attribute the_attribute_set;
|
||||||
bool valid;
|
bool valid;
|
||||||
Priority_Control priority;
|
|
||||||
RTEMS_API_Control *api;
|
RTEMS_API_Control *api;
|
||||||
ASR_Information *asr;
|
ASR_Information *asr;
|
||||||
|
|
||||||
|
|
||||||
if ( !id )
|
if ( !id )
|
||||||
return RTEMS_INVALID_ADDRESS;
|
return RTEMS_INVALID_ADDRESS;
|
||||||
|
|
||||||
@@ -78,10 +77,15 @@ rtems_status_code rtems_task_create(
|
|||||||
the_attribute_set =
|
the_attribute_set =
|
||||||
_Attributes_Clear( the_attribute_set, ATTRIBUTES_NOT_SUPPORTED );
|
_Attributes_Clear( the_attribute_set, ATTRIBUTES_NOT_SUPPORTED );
|
||||||
|
|
||||||
if ( _Attributes_Is_floating_point( the_attribute_set ) )
|
memset( &config, 0, sizeof( config ) );
|
||||||
is_fp = true;
|
config.stack_size = stack_size;
|
||||||
else
|
config.budget_algorithm = _Modes_Is_timeslice( initial_modes ) ?
|
||||||
is_fp = false;
|
THREAD_CPU_BUDGET_ALGORITHM_RESET_TIMESLICE
|
||||||
|
: THREAD_CPU_BUDGET_ALGORITHM_NONE,
|
||||||
|
config.isr_level = _Modes_Get_interrupt_level( initial_modes );
|
||||||
|
config.name.name_u32 = name;
|
||||||
|
config.is_fp = _Attributes_Is_floating_point( the_attribute_set );
|
||||||
|
config.is_preemptible = _Modes_Is_preempt( initial_modes );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Validate the RTEMS API priority and convert it to the core priority range.
|
* Validate the RTEMS API priority and convert it to the core priority range.
|
||||||
@@ -93,9 +97,13 @@ rtems_status_code rtems_task_create(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
scheduler = _Thread_Scheduler_get_home( _Thread_Get_executing() );
|
config.scheduler = _Thread_Scheduler_get_home( _Thread_Get_executing() );
|
||||||
|
|
||||||
priority = _RTEMS_Priority_To_core( scheduler, initial_priority, &valid );
|
config.priority = _RTEMS_Priority_To_core(
|
||||||
|
config.scheduler,
|
||||||
|
initial_priority,
|
||||||
|
&valid
|
||||||
|
);
|
||||||
if ( !valid ) {
|
if ( !valid ) {
|
||||||
return RTEMS_INVALID_PRIORITY;
|
return RTEMS_INVALID_PRIORITY;
|
||||||
}
|
}
|
||||||
@@ -144,22 +152,7 @@ rtems_status_code rtems_task_create(
|
|||||||
* Initialize the core thread for this task.
|
* Initialize the core thread for this task.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
status = _Thread_Initialize(
|
status = _Thread_Initialize( &_RTEMS_tasks_Information, the_thread, &config );
|
||||||
&_RTEMS_tasks_Information,
|
|
||||||
the_thread,
|
|
||||||
scheduler,
|
|
||||||
NULL,
|
|
||||||
stack_size,
|
|
||||||
is_fp,
|
|
||||||
priority,
|
|
||||||
_Modes_Is_preempt(initial_modes) ? true : false,
|
|
||||||
_Modes_Is_timeslice(initial_modes) ?
|
|
||||||
THREAD_CPU_BUDGET_ALGORITHM_RESET_TIMESLICE :
|
|
||||||
THREAD_CPU_BUDGET_ALGORITHM_NONE,
|
|
||||||
NULL, /* no budget algorithm callout */
|
|
||||||
_Modes_Get_interrupt_level(initial_modes),
|
|
||||||
(Objects_Name) name
|
|
||||||
);
|
|
||||||
|
|
||||||
if ( !status ) {
|
if ( !status ) {
|
||||||
#if defined(RTEMS_MULTIPROCESSING)
|
#if defined(RTEMS_MULTIPROCESSING)
|
||||||
|
|||||||
@@ -29,6 +29,8 @@
|
|||||||
#include <rtems/score/threadqimpl.h>
|
#include <rtems/score/threadqimpl.h>
|
||||||
#include <rtems/sysinit.h>
|
#include <rtems/sysinit.h>
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
RTEMS_STATIC_ASSERT(
|
RTEMS_STATIC_ASSERT(
|
||||||
sizeof(MPCI_Internal_packet) <= MP_PACKET_MINIMUM_PACKET_SIZE,
|
sizeof(MPCI_Internal_packet) <= MP_PACKET_MINIMUM_PACKET_SIZE,
|
||||||
MPCI_Internal_packet
|
MPCI_Internal_packet
|
||||||
@@ -111,8 +113,8 @@ static void _MPCI_Create_server( void )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
ISR_lock_Context lock_context;
|
Thread_Configuration config;
|
||||||
Objects_Name name;
|
ISR_lock_Context lock_context;
|
||||||
|
|
||||||
|
|
||||||
if ( !_System_state_Is_multiprocessing )
|
if ( !_System_state_Is_multiprocessing )
|
||||||
@@ -123,24 +125,19 @@ static void _MPCI_Create_server( void )
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
_MPCI_Receive_server_tcb = _Thread_Internal_allocate();
|
_MPCI_Receive_server_tcb = _Thread_Internal_allocate();
|
||||||
|
_Assert( _MPCI_Receive_server_tcb != NULL );
|
||||||
|
|
||||||
name.name_u32 = _Objects_Build_name( 'M', 'P', 'C', 'I' );
|
memset( &config, 0, sizeof( config ) );
|
||||||
_Thread_Initialize(
|
config.scheduler = &_Scheduler_Table[ 0 ];
|
||||||
&_Thread_Information,
|
config.stack_size = _Stack_Minimum()
|
||||||
_MPCI_Receive_server_tcb,
|
+ CPU_MPCI_RECEIVE_SERVER_EXTRA_STACK
|
||||||
&_Scheduler_Table[ 0 ],
|
+ _MPCI_Configuration.extra_mpci_receive_server_stack;
|
||||||
NULL, /* allocate the stack */
|
config.name.name_u32 = _Objects_Build_name( 'M', 'P', 'C', 'I' );
|
||||||
_Stack_Minimum() +
|
config.priority = PRIORITY_PSEUDO_ISR;
|
||||||
CPU_MPCI_RECEIVE_SERVER_EXTRA_STACK +
|
config.budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_NONE;
|
||||||
_MPCI_Configuration.extra_mpci_receive_server_stack,
|
config.is_fp = CPU_ALL_TASKS_ARE_FP;
|
||||||
CPU_ALL_TASKS_ARE_FP,
|
|
||||||
PRIORITY_PSEUDO_ISR,
|
_Thread_Initialize( &_Thread_Information, _MPCI_Receive_server_tcb, &config );
|
||||||
false, /* no preempt */
|
|
||||||
THREAD_CPU_BUDGET_ALGORITHM_NONE,
|
|
||||||
NULL, /* no budget algorithm callout */
|
|
||||||
0, /* all interrupts enabled */
|
|
||||||
name
|
|
||||||
);
|
|
||||||
|
|
||||||
_ISR_lock_ISR_disable( &lock_context );
|
_ISR_lock_ISR_disable( &lock_context );
|
||||||
_Thread_Start( _MPCI_Receive_server_tcb, &entry, &lock_context );
|
_Thread_Start( _MPCI_Receive_server_tcb, &entry, &lock_context );
|
||||||
|
|||||||
@@ -25,21 +25,31 @@
|
|||||||
#include <rtems/score/userextimpl.h>
|
#include <rtems/score/userextimpl.h>
|
||||||
#include <rtems/config.h>
|
#include <rtems/config.h>
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
static void _Thread_Create_idle_for_CPU( Per_CPU_Control *cpu )
|
static void _Thread_Create_idle_for_CPU( Per_CPU_Control *cpu )
|
||||||
{
|
{
|
||||||
Objects_Name name;
|
Thread_Configuration config;
|
||||||
Thread_Control *idle;
|
Thread_Control *idle;
|
||||||
const Scheduler_Control *scheduler;
|
|
||||||
|
|
||||||
scheduler = _Scheduler_Get_by_CPU( cpu );
|
memset( &config, 0, sizeof( config ) );
|
||||||
|
config.scheduler = _Scheduler_Get_by_CPU( cpu );
|
||||||
|
|
||||||
#if defined(RTEMS_SMP)
|
#if defined(RTEMS_SMP)
|
||||||
if (scheduler == NULL) {
|
if ( config.scheduler == NULL ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
name.name_u32 = _Objects_Build_name( 'I', 'D', 'L', 'E' );
|
config.stack_size = rtems_configuration_get_idle_task_stack_size();
|
||||||
|
config.priority = _Scheduler_Map_priority(
|
||||||
|
config.scheduler,
|
||||||
|
config.scheduler->maximum_priority
|
||||||
|
);
|
||||||
|
config.budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_NONE;
|
||||||
|
config.name.name_u32 = _Objects_Build_name( 'I', 'D', 'L', 'E' );
|
||||||
|
config.is_fp = CPU_IDLE_TASK_IS_FP;
|
||||||
|
config.is_preemptible = true;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The entire workspace is zeroed during its initialization. Thus, all
|
* The entire workspace is zeroed during its initialization. Thus, all
|
||||||
@@ -49,20 +59,7 @@ static void _Thread_Create_idle_for_CPU( Per_CPU_Control *cpu )
|
|||||||
idle = _Thread_Internal_allocate();
|
idle = _Thread_Internal_allocate();
|
||||||
_Assert( idle != NULL );
|
_Assert( idle != NULL );
|
||||||
|
|
||||||
_Thread_Initialize(
|
_Thread_Initialize( &_Thread_Information, idle, &config );
|
||||||
&_Thread_Information,
|
|
||||||
idle,
|
|
||||||
scheduler,
|
|
||||||
NULL, /* allocate the stack */
|
|
||||||
rtems_configuration_get_idle_task_stack_size(),
|
|
||||||
CPU_IDLE_TASK_IS_FP,
|
|
||||||
_Scheduler_Map_priority( scheduler, scheduler->maximum_priority ),
|
|
||||||
true, /* preemptable */
|
|
||||||
THREAD_CPU_BUDGET_ALGORITHM_NONE,
|
|
||||||
NULL, /* no budget algorithm callout */
|
|
||||||
0, /* all interrupts enabled */
|
|
||||||
name
|
|
||||||
);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* WARNING!!! This is necessary to "kick" start the system and
|
* WARNING!!! This is necessary to "kick" start the system and
|
||||||
@@ -78,7 +75,7 @@ static void _Thread_Create_idle_for_CPU( Per_CPU_Control *cpu )
|
|||||||
_Thread_Load_environment( idle );
|
_Thread_Load_environment( idle );
|
||||||
|
|
||||||
idle->current_state = STATES_READY;
|
idle->current_state = STATES_READY;
|
||||||
_Scheduler_Start_idle( scheduler, idle, cpu );
|
_Scheduler_Start_idle( config.scheduler, idle, cpu );
|
||||||
_User_extensions_Thread_start( idle );
|
_User_extensions_Thread_start( idle );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -28,23 +28,16 @@
|
|||||||
#include <rtems/config.h>
|
#include <rtems/config.h>
|
||||||
|
|
||||||
bool _Thread_Initialize(
|
bool _Thread_Initialize(
|
||||||
Thread_Information *information,
|
Thread_Information *information,
|
||||||
Thread_Control *the_thread,
|
Thread_Control *the_thread,
|
||||||
const Scheduler_Control *scheduler,
|
const Thread_Configuration *config
|
||||||
void *stack_area,
|
|
||||||
size_t stack_size,
|
|
||||||
bool is_fp,
|
|
||||||
Priority_Control priority,
|
|
||||||
bool is_preemptible,
|
|
||||||
Thread_CPU_budget_algorithms budget_algorithm,
|
|
||||||
Thread_CPU_budget_algorithm_callout budget_callout,
|
|
||||||
uint32_t isr_level,
|
|
||||||
Objects_Name name
|
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
uintptr_t tls_size;
|
uintptr_t tls_size;
|
||||||
bool extension_status;
|
bool extension_status;
|
||||||
size_t i;
|
size_t i;
|
||||||
|
char *stack_area;
|
||||||
|
size_t stack_size;
|
||||||
Scheduler_Node *scheduler_node;
|
Scheduler_Node *scheduler_node;
|
||||||
#if defined(RTEMS_SMP)
|
#if defined(RTEMS_SMP)
|
||||||
Scheduler_Node *scheduler_node_for_index;
|
Scheduler_Node *scheduler_node_for_index;
|
||||||
@@ -54,14 +47,14 @@ bool _Thread_Initialize(
|
|||||||
Per_CPU_Control *cpu = _Per_CPU_Get_by_index( 0 );
|
Per_CPU_Control *cpu = _Per_CPU_Get_by_index( 0 );
|
||||||
|
|
||||||
#if defined(RTEMS_SMP)
|
#if defined(RTEMS_SMP)
|
||||||
if ( !is_preemptible && rtems_configuration_is_smp_enabled() ) {
|
if ( !config->is_preemptible && rtems_configuration_is_smp_enabled() ) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(RTEMS_SMP) || CPU_ENABLE_ROBUST_THREAD_DISPATCH == TRUE
|
#if defined(RTEMS_SMP) || CPU_ENABLE_ROBUST_THREAD_DISPATCH == TRUE
|
||||||
if (
|
if (
|
||||||
isr_level != 0
|
config->isr_level != 0
|
||||||
#if CPU_ENABLE_ROBUST_THREAD_DISPATCH == FALSE
|
#if CPU_ENABLE_ROBUST_THREAD_DISPATCH == FALSE
|
||||||
&& rtems_configuration_is_smp_enabled()
|
&& rtems_configuration_is_smp_enabled()
|
||||||
#endif
|
#endif
|
||||||
@@ -87,12 +80,12 @@ bool _Thread_Initialize(
|
|||||||
|
|
||||||
/* Allocate the stack for this thread */
|
/* Allocate the stack for this thread */
|
||||||
#if defined(RTEMS_SCORE_THREAD_ENABLE_USER_PROVIDED_STACK_VIA_API)
|
#if defined(RTEMS_SCORE_THREAD_ENABLE_USER_PROVIDED_STACK_VIA_API)
|
||||||
if ( stack_area == NULL ) {
|
if ( config->stack_area == NULL ) {
|
||||||
#endif
|
#endif
|
||||||
stack_size = _Stack_Ensure_minimum( stack_size );
|
stack_size = _Stack_Ensure_minimum( config->stack_size );
|
||||||
|
|
||||||
#if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
|
#if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
|
||||||
if ( is_fp ) {
|
if ( config->is_fp ) {
|
||||||
stack_size += CONTEXT_FP_SIZE;
|
stack_size += CONTEXT_FP_SIZE;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -106,16 +99,19 @@ bool _Thread_Initialize(
|
|||||||
|
|
||||||
the_thread->Start.allocated_stack = stack_area;
|
the_thread->Start.allocated_stack = stack_area;
|
||||||
#if defined(RTEMS_SCORE_THREAD_ENABLE_USER_PROVIDED_STACK_VIA_API)
|
#if defined(RTEMS_SCORE_THREAD_ENABLE_USER_PROVIDED_STACK_VIA_API)
|
||||||
|
} else {
|
||||||
|
stack_area = config->stack_area;
|
||||||
|
stack_size = config->stack_size;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Allocate floating-point context in stack area */
|
/* Allocate floating-point context in stack area */
|
||||||
#if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
|
#if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
|
||||||
if ( is_fp ) {
|
if ( config->is_fp ) {
|
||||||
the_thread->fp_context = stack_area;
|
the_thread->fp_context = ( Context_Control_fp *) stack_area;
|
||||||
the_thread->Start.fp_context = stack_area;
|
the_thread->Start.fp_context = ( Context_Control_fp *) stack_area;
|
||||||
stack_size -= CONTEXT_FP_SIZE;
|
stack_size -= CONTEXT_FP_SIZE;
|
||||||
stack_area = (char *) stack_area + CONTEXT_FP_SIZE;
|
stack_area += CONTEXT_FP_SIZE;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -127,7 +123,7 @@ bool _Thread_Initialize(
|
|||||||
the_thread->Start.tls_area = (void *)
|
the_thread->Start.tls_area = (void *)
|
||||||
( ( (uintptr_t) stack_area + tls_align - 1 ) & ~( tls_align - 1 ) );
|
( ( (uintptr_t) stack_area + tls_align - 1 ) & ~( tls_align - 1 ) );
|
||||||
stack_size -= tls_size;
|
stack_size -= tls_size;
|
||||||
stack_area = (char *) stack_area + tls_size;
|
stack_area += tls_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
_Stack_Initialize(
|
_Stack_Initialize(
|
||||||
@@ -156,15 +152,15 @@ bool _Thread_Initialize(
|
|||||||
* General initialization
|
* General initialization
|
||||||
*/
|
*/
|
||||||
|
|
||||||
the_thread->is_fp = is_fp;
|
the_thread->is_fp = config->is_fp;
|
||||||
the_thread->Start.isr_level = isr_level;
|
the_thread->Start.isr_level = config->isr_level;
|
||||||
the_thread->Start.is_preemptible = is_preemptible;
|
the_thread->Start.is_preemptible = config->is_preemptible;
|
||||||
the_thread->Start.budget_algorithm = budget_algorithm;
|
the_thread->Start.budget_algorithm = config->budget_algorithm;
|
||||||
the_thread->Start.budget_callout = budget_callout;
|
the_thread->Start.budget_callout = config->budget_callout;
|
||||||
|
|
||||||
_Thread_Timer_initialize( &the_thread->Timer, cpu );
|
_Thread_Timer_initialize( &the_thread->Timer, cpu );
|
||||||
|
|
||||||
switch ( budget_algorithm ) {
|
switch ( config->budget_algorithm ) {
|
||||||
case THREAD_CPU_BUDGET_ALGORITHM_NONE:
|
case THREAD_CPU_BUDGET_ALGORITHM_NONE:
|
||||||
case THREAD_CPU_BUDGET_ALGORITHM_RESET_TIMESLICE:
|
case THREAD_CPU_BUDGET_ALGORITHM_RESET_TIMESLICE:
|
||||||
break;
|
break;
|
||||||
@@ -188,8 +184,8 @@ bool _Thread_Initialize(
|
|||||||
while ( scheduler_index < _Scheduler_Count ) {
|
while ( scheduler_index < _Scheduler_Count ) {
|
||||||
Priority_Control priority_for_index;
|
Priority_Control priority_for_index;
|
||||||
|
|
||||||
if ( scheduler_for_index == scheduler ) {
|
if ( scheduler_for_index == config->scheduler ) {
|
||||||
priority_for_index = priority;
|
priority_for_index = config->priority;
|
||||||
scheduler_node = scheduler_node_for_index;
|
scheduler_node = scheduler_node_for_index;
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
@@ -226,15 +222,15 @@ bool _Thread_Initialize(
|
|||||||
#else
|
#else
|
||||||
scheduler_node = _Thread_Scheduler_get_home_node( the_thread );
|
scheduler_node = _Thread_Scheduler_get_home_node( the_thread );
|
||||||
_Scheduler_Node_initialize(
|
_Scheduler_Node_initialize(
|
||||||
scheduler,
|
config->scheduler,
|
||||||
scheduler_node,
|
scheduler_node,
|
||||||
the_thread,
|
the_thread,
|
||||||
priority
|
config->priority
|
||||||
);
|
);
|
||||||
scheduler_index = 1;
|
scheduler_index = 1;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
_Priority_Node_initialize( &the_thread->Real_priority, priority );
|
_Priority_Node_initialize( &the_thread->Real_priority, config->priority );
|
||||||
_Priority_Initialize_one(
|
_Priority_Initialize_one(
|
||||||
&scheduler_node->Wait.Priority,
|
&scheduler_node->Wait.Priority,
|
||||||
&the_thread->Real_priority
|
&the_thread->Real_priority
|
||||||
@@ -242,7 +238,7 @@ bool _Thread_Initialize(
|
|||||||
|
|
||||||
#if defined(RTEMS_SMP)
|
#if defined(RTEMS_SMP)
|
||||||
RTEMS_STATIC_ASSERT( THREAD_SCHEDULER_BLOCKED == 0, Scheduler_state );
|
RTEMS_STATIC_ASSERT( THREAD_SCHEDULER_BLOCKED == 0, Scheduler_state );
|
||||||
the_thread->Scheduler.home_scheduler = scheduler;
|
the_thread->Scheduler.home_scheduler = config->scheduler;
|
||||||
_ISR_lock_Initialize( &the_thread->Scheduler.Lock, "Thread Scheduler" );
|
_ISR_lock_Initialize( &the_thread->Scheduler.Lock, "Thread Scheduler" );
|
||||||
_Processor_mask_Assign(
|
_Processor_mask_Assign(
|
||||||
&the_thread->Scheduler.Affinity,
|
&the_thread->Scheduler.Affinity,
|
||||||
@@ -260,7 +256,7 @@ bool _Thread_Initialize(
|
|||||||
|
|
||||||
the_thread->current_state = STATES_DORMANT;
|
the_thread->current_state = STATES_DORMANT;
|
||||||
the_thread->Wait.operations = &_Thread_queue_Operations_default;
|
the_thread->Wait.operations = &_Thread_queue_Operations_default;
|
||||||
the_thread->Start.initial_priority = priority;
|
the_thread->Start.initial_priority = config->priority;
|
||||||
|
|
||||||
RTEMS_STATIC_ASSERT( THREAD_WAIT_FLAGS_INITIAL == 0, Wait_flags );
|
RTEMS_STATIC_ASSERT( THREAD_WAIT_FLAGS_INITIAL == 0, Wait_flags );
|
||||||
|
|
||||||
@@ -273,7 +269,7 @@ bool _Thread_Initialize(
|
|||||||
/*
|
/*
|
||||||
* Open the object
|
* Open the object
|
||||||
*/
|
*/
|
||||||
_Objects_Open( &information->Objects, &the_thread->Object, name );
|
_Objects_Open( &information->Objects, &the_thread->Object, config->name );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We assume the Allocator Mutex is locked and dispatching is
|
* We assume the Allocator Mutex is locked and dispatching is
|
||||||
@@ -298,7 +294,7 @@ failed:
|
|||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
if ( scheduler_index > 0 ) {
|
if ( scheduler_index > 0 ) {
|
||||||
_Scheduler_Node_destroy( scheduler, scheduler_node );
|
_Scheduler_Node_destroy( config->scheduler, scheduler_node );
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user