forked from Imagelibrary/rtems
Added Sporadic Server support to posix threads which required changes
in the core to support multiple algorithms to handle cpu time budgetting which resulted in a change to the calling sequence of _Thread_Initialize.
This commit is contained in:
@@ -354,7 +354,10 @@ rtems_status_code rtems_task_create(
|
|||||||
is_fp,
|
is_fp,
|
||||||
core_priority,
|
core_priority,
|
||||||
_Modes_Is_preempt(initial_modes) ? TRUE : FALSE,
|
_Modes_Is_preempt(initial_modes) ? TRUE : FALSE,
|
||||||
_Modes_Is_timeslice(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),
|
_Modes_Get_interrupt_level(initial_modes),
|
||||||
&name
|
&name
|
||||||
);
|
);
|
||||||
@@ -777,7 +780,12 @@ rtems_status_code rtems_task_mode(
|
|||||||
asr = &api->Signal;
|
asr = &api->Signal;
|
||||||
|
|
||||||
old_mode = (executing->is_preemptible) ? RTEMS_PREEMPT : RTEMS_NO_PREEMPT;
|
old_mode = (executing->is_preemptible) ? RTEMS_PREEMPT : RTEMS_NO_PREEMPT;
|
||||||
old_mode |= (executing->is_timeslice) ? RTEMS_TIMESLICE : RTEMS_NO_TIMESLICE;
|
|
||||||
|
if ( executing->budget_algorithm == THREAD_CPU_BUDGET_ALGORITHM_NONE )
|
||||||
|
old_mode |= RTEMS_NO_TIMESLICE;
|
||||||
|
else
|
||||||
|
old_mode |= RTEMS_TIMESLICE;
|
||||||
|
|
||||||
old_mode |= (asr->is_enabled) ? RTEMS_ASR : RTEMS_NO_ASR;
|
old_mode |= (asr->is_enabled) ? RTEMS_ASR : RTEMS_NO_ASR;
|
||||||
old_mode |= _ISR_Get_level();
|
old_mode |= _ISR_Get_level();
|
||||||
|
|
||||||
@@ -790,8 +798,12 @@ rtems_status_code rtems_task_mode(
|
|||||||
if ( mask & RTEMS_PREEMPT_MASK )
|
if ( mask & RTEMS_PREEMPT_MASK )
|
||||||
executing->is_preemptible = _Modes_Is_preempt(mode_set) ? TRUE : FALSE;
|
executing->is_preemptible = _Modes_Is_preempt(mode_set) ? TRUE : FALSE;
|
||||||
|
|
||||||
if ( mask & RTEMS_TIMESLICE_MASK )
|
if ( mask & RTEMS_TIMESLICE_MASK ) {
|
||||||
executing->is_timeslice = _Modes_Is_timeslice(mode_set) ? TRUE : FALSE;
|
if ( _Modes_Is_timeslice(mode_set) )
|
||||||
|
executing->budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_RESET_TIMESLICE;
|
||||||
|
else
|
||||||
|
executing->budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set the new interrupt level
|
* Set the new interrupt level
|
||||||
|
|||||||
@@ -115,7 +115,8 @@ void _MPCI_Create_server( void )
|
|||||||
CPU_ALL_TASKS_ARE_FP,
|
CPU_ALL_TASKS_ARE_FP,
|
||||||
PRIORITY_MINIMUM,
|
PRIORITY_MINIMUM,
|
||||||
FALSE, /* no preempt */
|
FALSE, /* no preempt */
|
||||||
FALSE, /* not timesliced */
|
THREAD_CPU_BUDGET_ALGORITHM_NONE,
|
||||||
|
NULL, /* no budget algorithm callout */
|
||||||
0, /* all interrupts enabled */
|
0, /* all interrupts enabled */
|
||||||
_MPCI_Internal_name
|
_MPCI_Internal_name
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -136,7 +136,8 @@ void _Thread_Create_idle( void )
|
|||||||
CPU_IDLE_TASK_IS_FP,
|
CPU_IDLE_TASK_IS_FP,
|
||||||
PRIORITY_MAXIMUM,
|
PRIORITY_MAXIMUM,
|
||||||
TRUE, /* preemptable */
|
TRUE, /* preemptable */
|
||||||
FALSE, /* not timesliced */
|
THREAD_CPU_BUDGET_ALGORITHM_NONE,
|
||||||
|
NULL, /* no budget algorithm callout */
|
||||||
0, /* all interrupts enabled */
|
0, /* all interrupts enabled */
|
||||||
_Thread_Idle_name
|
_Thread_Idle_name
|
||||||
);
|
);
|
||||||
@@ -243,6 +244,7 @@ void _Thread_Dispatch( void )
|
|||||||
|
|
||||||
_User_extensions_Thread_switch( executing, heir );
|
_User_extensions_Thread_switch( executing, heir );
|
||||||
|
|
||||||
|
if ( heir->budget_algorithm == THREAD_CPU_BUDGET_ALGORITHM_RESET_TIMESLICE )
|
||||||
heir->cpu_time_budget = _Thread_Ticks_per_timeslice;
|
heir->cpu_time_budget = _Thread_Ticks_per_timeslice;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -385,15 +387,15 @@ static void _Thread_Stack_Free(
|
|||||||
boolean _Thread_Initialize(
|
boolean _Thread_Initialize(
|
||||||
Objects_Information *information,
|
Objects_Information *information,
|
||||||
Thread_Control *the_thread,
|
Thread_Control *the_thread,
|
||||||
void *stack_area, /* NULL if to be allocated */
|
void *stack_area,
|
||||||
unsigned32 stack_size, /* insure it is >= min */
|
unsigned32 stack_size,
|
||||||
boolean is_fp, /* TRUE if thread uses FP */
|
boolean is_fp,
|
||||||
Priority_Control priority,
|
Priority_Control priority,
|
||||||
boolean is_preemptible,
|
boolean is_preemptible,
|
||||||
boolean is_timeslice,
|
Thread_CPU_budget_algorithms budget_algorithm,
|
||||||
|
Thread_CPU_budget_algorithm_callout budget_callout,
|
||||||
unsigned32 isr_level,
|
unsigned32 isr_level,
|
||||||
Objects_Name name
|
Objects_Name name
|
||||||
|
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
unsigned32 actual_stack_size = 0;
|
unsigned32 actual_stack_size = 0;
|
||||||
@@ -481,7 +483,8 @@ boolean _Thread_Initialize(
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
the_thread->Start.is_preemptible = is_preemptible;
|
the_thread->Start.is_preemptible = is_preemptible;
|
||||||
the_thread->Start.is_timeslice = is_timeslice;
|
the_thread->Start.budget_algorithm = budget_algorithm;
|
||||||
|
the_thread->Start.budget_callout = budget_callout;
|
||||||
the_thread->Start.isr_level = isr_level;
|
the_thread->Start.isr_level = isr_level;
|
||||||
|
|
||||||
the_thread->current_state = STATES_DORMANT;
|
the_thread->current_state = STATES_DORMANT;
|
||||||
@@ -574,7 +577,8 @@ boolean _Thread_Restart(
|
|||||||
_Thread_Set_transient( the_thread );
|
_Thread_Set_transient( the_thread );
|
||||||
the_thread->resource_count = 0;
|
the_thread->resource_count = 0;
|
||||||
the_thread->is_preemptible = the_thread->Start.is_preemptible;
|
the_thread->is_preemptible = the_thread->Start.is_preemptible;
|
||||||
the_thread->is_timeslice = the_thread->Start.is_timeslice;
|
the_thread->budget_algorithm = the_thread->Start.budget_algorithm;
|
||||||
|
the_thread->budget_callout = the_thread->Start.budget_callout;
|
||||||
|
|
||||||
the_thread->Start.pointer_argument = pointer_argument;
|
the_thread->Start.pointer_argument = pointer_argument;
|
||||||
the_thread->Start.numeric_argument = numeric_argument;
|
the_thread->Start.numeric_argument = numeric_argument;
|
||||||
@@ -874,7 +878,6 @@ void _Thread_Reset_timeslice( void )
|
|||||||
_ISR_Disable( level );
|
_ISR_Disable( level );
|
||||||
if ( _Chain_Has_only_one_node( ready ) ) {
|
if ( _Chain_Has_only_one_node( ready ) ) {
|
||||||
_ISR_Enable( level );
|
_ISR_Enable( level );
|
||||||
executing->cpu_time_budget = _Thread_Ticks_per_timeslice;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_Chain_Extract_unprotected( &executing->Object.Node );
|
_Chain_Extract_unprotected( &executing->Object.Node );
|
||||||
@@ -905,13 +908,32 @@ void _Thread_Reset_timeslice( void )
|
|||||||
|
|
||||||
void _Thread_Tickle_timeslice( void )
|
void _Thread_Tickle_timeslice( void )
|
||||||
{
|
{
|
||||||
if ( !_Thread_Executing->is_timeslice ||
|
Thread_Control *executing;
|
||||||
!_Thread_Executing->is_preemptible ||
|
|
||||||
!_States_Is_ready( _Thread_Executing->current_state ) )
|
executing = _Thread_Executing;
|
||||||
|
|
||||||
|
if ( !executing->is_preemptible )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if ( --_Thread_Executing->cpu_time_budget == 0 ) {
|
if ( !_States_Is_ready( executing->current_state ) )
|
||||||
|
return;
|
||||||
|
|
||||||
|
switch ( executing->budget_algorithm ) {
|
||||||
|
case THREAD_CPU_BUDGET_ALGORITHM_NONE:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case THREAD_CPU_BUDGET_ALGORITHM_RESET_TIMESLICE:
|
||||||
|
case THREAD_CPU_BUDGET_ALGORITHM_EXHAUST_TIMESLICE:
|
||||||
|
if ( --executing->cpu_time_budget == 0 ) {
|
||||||
_Thread_Reset_timeslice();
|
_Thread_Reset_timeslice();
|
||||||
|
executing->cpu_time_budget = _Thread_Ticks_per_timeslice;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case THREAD_CPU_BUDGET_ALGORITHM_CALLOUT:
|
||||||
|
if ( --executing->cpu_time_budget == 0 )
|
||||||
|
(*executing->budget_callout)( executing );
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -987,7 +1009,8 @@ void _Thread_Load_environment(
|
|||||||
|
|
||||||
the_thread->do_post_task_switch_extension = FALSE;
|
the_thread->do_post_task_switch_extension = FALSE;
|
||||||
the_thread->is_preemptible = the_thread->Start.is_preemptible;
|
the_thread->is_preemptible = the_thread->Start.is_preemptible;
|
||||||
the_thread->is_timeslice = the_thread->Start.is_timeslice;
|
the_thread->budget_algorithm = the_thread->Start.budget_algorithm;
|
||||||
|
the_thread->budget_callout = the_thread->Start.budget_callout;
|
||||||
|
|
||||||
_Context_Initialize(
|
_Context_Initialize(
|
||||||
&the_thread->Registers,
|
&the_thread->Registers,
|
||||||
|
|||||||
@@ -354,7 +354,10 @@ rtems_status_code rtems_task_create(
|
|||||||
is_fp,
|
is_fp,
|
||||||
core_priority,
|
core_priority,
|
||||||
_Modes_Is_preempt(initial_modes) ? TRUE : FALSE,
|
_Modes_Is_preempt(initial_modes) ? TRUE : FALSE,
|
||||||
_Modes_Is_timeslice(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),
|
_Modes_Get_interrupt_level(initial_modes),
|
||||||
&name
|
&name
|
||||||
);
|
);
|
||||||
@@ -777,7 +780,12 @@ rtems_status_code rtems_task_mode(
|
|||||||
asr = &api->Signal;
|
asr = &api->Signal;
|
||||||
|
|
||||||
old_mode = (executing->is_preemptible) ? RTEMS_PREEMPT : RTEMS_NO_PREEMPT;
|
old_mode = (executing->is_preemptible) ? RTEMS_PREEMPT : RTEMS_NO_PREEMPT;
|
||||||
old_mode |= (executing->is_timeslice) ? RTEMS_TIMESLICE : RTEMS_NO_TIMESLICE;
|
|
||||||
|
if ( executing->budget_algorithm == THREAD_CPU_BUDGET_ALGORITHM_NONE )
|
||||||
|
old_mode |= RTEMS_NO_TIMESLICE;
|
||||||
|
else
|
||||||
|
old_mode |= RTEMS_TIMESLICE;
|
||||||
|
|
||||||
old_mode |= (asr->is_enabled) ? RTEMS_ASR : RTEMS_NO_ASR;
|
old_mode |= (asr->is_enabled) ? RTEMS_ASR : RTEMS_NO_ASR;
|
||||||
old_mode |= _ISR_Get_level();
|
old_mode |= _ISR_Get_level();
|
||||||
|
|
||||||
@@ -790,8 +798,12 @@ rtems_status_code rtems_task_mode(
|
|||||||
if ( mask & RTEMS_PREEMPT_MASK )
|
if ( mask & RTEMS_PREEMPT_MASK )
|
||||||
executing->is_preemptible = _Modes_Is_preempt(mode_set) ? TRUE : FALSE;
|
executing->is_preemptible = _Modes_Is_preempt(mode_set) ? TRUE : FALSE;
|
||||||
|
|
||||||
if ( mask & RTEMS_TIMESLICE_MASK )
|
if ( mask & RTEMS_TIMESLICE_MASK ) {
|
||||||
executing->is_timeslice = _Modes_Is_timeslice(mode_set) ? TRUE : FALSE;
|
if ( _Modes_Is_timeslice(mode_set) )
|
||||||
|
executing->budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_RESET_TIMESLICE;
|
||||||
|
else
|
||||||
|
executing->budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set the new interrupt level
|
* Set the new interrupt level
|
||||||
|
|||||||
@@ -115,7 +115,8 @@ void _MPCI_Create_server( void )
|
|||||||
CPU_ALL_TASKS_ARE_FP,
|
CPU_ALL_TASKS_ARE_FP,
|
||||||
PRIORITY_MINIMUM,
|
PRIORITY_MINIMUM,
|
||||||
FALSE, /* no preempt */
|
FALSE, /* no preempt */
|
||||||
FALSE, /* not timesliced */
|
THREAD_CPU_BUDGET_ALGORITHM_NONE,
|
||||||
|
NULL, /* no budget algorithm callout */
|
||||||
0, /* all interrupts enabled */
|
0, /* all interrupts enabled */
|
||||||
_MPCI_Internal_name
|
_MPCI_Internal_name
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -136,7 +136,8 @@ void _Thread_Create_idle( void )
|
|||||||
CPU_IDLE_TASK_IS_FP,
|
CPU_IDLE_TASK_IS_FP,
|
||||||
PRIORITY_MAXIMUM,
|
PRIORITY_MAXIMUM,
|
||||||
TRUE, /* preemptable */
|
TRUE, /* preemptable */
|
||||||
FALSE, /* not timesliced */
|
THREAD_CPU_BUDGET_ALGORITHM_NONE,
|
||||||
|
NULL, /* no budget algorithm callout */
|
||||||
0, /* all interrupts enabled */
|
0, /* all interrupts enabled */
|
||||||
_Thread_Idle_name
|
_Thread_Idle_name
|
||||||
);
|
);
|
||||||
@@ -243,6 +244,7 @@ void _Thread_Dispatch( void )
|
|||||||
|
|
||||||
_User_extensions_Thread_switch( executing, heir );
|
_User_extensions_Thread_switch( executing, heir );
|
||||||
|
|
||||||
|
if ( heir->budget_algorithm == THREAD_CPU_BUDGET_ALGORITHM_RESET_TIMESLICE )
|
||||||
heir->cpu_time_budget = _Thread_Ticks_per_timeslice;
|
heir->cpu_time_budget = _Thread_Ticks_per_timeslice;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -385,15 +387,15 @@ static void _Thread_Stack_Free(
|
|||||||
boolean _Thread_Initialize(
|
boolean _Thread_Initialize(
|
||||||
Objects_Information *information,
|
Objects_Information *information,
|
||||||
Thread_Control *the_thread,
|
Thread_Control *the_thread,
|
||||||
void *stack_area, /* NULL if to be allocated */
|
void *stack_area,
|
||||||
unsigned32 stack_size, /* insure it is >= min */
|
unsigned32 stack_size,
|
||||||
boolean is_fp, /* TRUE if thread uses FP */
|
boolean is_fp,
|
||||||
Priority_Control priority,
|
Priority_Control priority,
|
||||||
boolean is_preemptible,
|
boolean is_preemptible,
|
||||||
boolean is_timeslice,
|
Thread_CPU_budget_algorithms budget_algorithm,
|
||||||
|
Thread_CPU_budget_algorithm_callout budget_callout,
|
||||||
unsigned32 isr_level,
|
unsigned32 isr_level,
|
||||||
Objects_Name name
|
Objects_Name name
|
||||||
|
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
unsigned32 actual_stack_size = 0;
|
unsigned32 actual_stack_size = 0;
|
||||||
@@ -481,7 +483,8 @@ boolean _Thread_Initialize(
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
the_thread->Start.is_preemptible = is_preemptible;
|
the_thread->Start.is_preemptible = is_preemptible;
|
||||||
the_thread->Start.is_timeslice = is_timeslice;
|
the_thread->Start.budget_algorithm = budget_algorithm;
|
||||||
|
the_thread->Start.budget_callout = budget_callout;
|
||||||
the_thread->Start.isr_level = isr_level;
|
the_thread->Start.isr_level = isr_level;
|
||||||
|
|
||||||
the_thread->current_state = STATES_DORMANT;
|
the_thread->current_state = STATES_DORMANT;
|
||||||
@@ -574,7 +577,8 @@ boolean _Thread_Restart(
|
|||||||
_Thread_Set_transient( the_thread );
|
_Thread_Set_transient( the_thread );
|
||||||
the_thread->resource_count = 0;
|
the_thread->resource_count = 0;
|
||||||
the_thread->is_preemptible = the_thread->Start.is_preemptible;
|
the_thread->is_preemptible = the_thread->Start.is_preemptible;
|
||||||
the_thread->is_timeslice = the_thread->Start.is_timeslice;
|
the_thread->budget_algorithm = the_thread->Start.budget_algorithm;
|
||||||
|
the_thread->budget_callout = the_thread->Start.budget_callout;
|
||||||
|
|
||||||
the_thread->Start.pointer_argument = pointer_argument;
|
the_thread->Start.pointer_argument = pointer_argument;
|
||||||
the_thread->Start.numeric_argument = numeric_argument;
|
the_thread->Start.numeric_argument = numeric_argument;
|
||||||
@@ -874,7 +878,6 @@ void _Thread_Reset_timeslice( void )
|
|||||||
_ISR_Disable( level );
|
_ISR_Disable( level );
|
||||||
if ( _Chain_Has_only_one_node( ready ) ) {
|
if ( _Chain_Has_only_one_node( ready ) ) {
|
||||||
_ISR_Enable( level );
|
_ISR_Enable( level );
|
||||||
executing->cpu_time_budget = _Thread_Ticks_per_timeslice;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_Chain_Extract_unprotected( &executing->Object.Node );
|
_Chain_Extract_unprotected( &executing->Object.Node );
|
||||||
@@ -905,13 +908,32 @@ void _Thread_Reset_timeslice( void )
|
|||||||
|
|
||||||
void _Thread_Tickle_timeslice( void )
|
void _Thread_Tickle_timeslice( void )
|
||||||
{
|
{
|
||||||
if ( !_Thread_Executing->is_timeslice ||
|
Thread_Control *executing;
|
||||||
!_Thread_Executing->is_preemptible ||
|
|
||||||
!_States_Is_ready( _Thread_Executing->current_state ) )
|
executing = _Thread_Executing;
|
||||||
|
|
||||||
|
if ( !executing->is_preemptible )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if ( --_Thread_Executing->cpu_time_budget == 0 ) {
|
if ( !_States_Is_ready( executing->current_state ) )
|
||||||
|
return;
|
||||||
|
|
||||||
|
switch ( executing->budget_algorithm ) {
|
||||||
|
case THREAD_CPU_BUDGET_ALGORITHM_NONE:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case THREAD_CPU_BUDGET_ALGORITHM_RESET_TIMESLICE:
|
||||||
|
case THREAD_CPU_BUDGET_ALGORITHM_EXHAUST_TIMESLICE:
|
||||||
|
if ( --executing->cpu_time_budget == 0 ) {
|
||||||
_Thread_Reset_timeslice();
|
_Thread_Reset_timeslice();
|
||||||
|
executing->cpu_time_budget = _Thread_Ticks_per_timeslice;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case THREAD_CPU_BUDGET_ALGORITHM_CALLOUT:
|
||||||
|
if ( --executing->cpu_time_budget == 0 )
|
||||||
|
(*executing->budget_callout)( executing );
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -987,7 +1009,8 @@ void _Thread_Load_environment(
|
|||||||
|
|
||||||
the_thread->do_post_task_switch_extension = FALSE;
|
the_thread->do_post_task_switch_extension = FALSE;
|
||||||
the_thread->is_preemptible = the_thread->Start.is_preemptible;
|
the_thread->is_preemptible = the_thread->Start.is_preemptible;
|
||||||
the_thread->is_timeslice = the_thread->Start.is_timeslice;
|
the_thread->budget_algorithm = the_thread->Start.budget_algorithm;
|
||||||
|
the_thread->budget_callout = the_thread->Start.budget_callout;
|
||||||
|
|
||||||
_Context_Initialize(
|
_Context_Initialize(
|
||||||
&the_thread->Registers,
|
&the_thread->Registers,
|
||||||
|
|||||||
Reference in New Issue
Block a user