summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--c/src/exec/rtems/src/tasks.c20
-rw-r--r--c/src/exec/score/src/mpci.c3
-rw-r--r--c/src/exec/score/src/thread.c75
-rw-r--r--cpukit/rtems/src/tasks.c20
-rw-r--r--cpukit/score/src/mpci.c3
-rw-r--r--cpukit/score/src/thread.c75
6 files changed, 134 insertions, 62 deletions
diff --git a/c/src/exec/rtems/src/tasks.c b/c/src/exec/rtems/src/tasks.c
index aec54fc7f4..403a26e0d4 100644
--- a/c/src/exec/rtems/src/tasks.c
+++ b/c/src/exec/rtems/src/tasks.c
@@ -354,7 +354,10 @@ rtems_status_code rtems_task_create(
is_fp,
core_priority,
_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),
&name
);
@@ -777,7 +780,12 @@ rtems_status_code rtems_task_mode(
asr = &api->Signal;
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 |= _ISR_Get_level();
@@ -790,8 +798,12 @@ rtems_status_code rtems_task_mode(
if ( mask & RTEMS_PREEMPT_MASK )
executing->is_preemptible = _Modes_Is_preempt(mode_set) ? TRUE : FALSE;
- if ( mask & RTEMS_TIMESLICE_MASK )
- executing->is_timeslice = _Modes_Is_timeslice(mode_set) ? TRUE : FALSE;
+ if ( mask & RTEMS_TIMESLICE_MASK ) {
+ 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
diff --git a/c/src/exec/score/src/mpci.c b/c/src/exec/score/src/mpci.c
index c3090aacc1..bc3381c925 100644
--- a/c/src/exec/score/src/mpci.c
+++ b/c/src/exec/score/src/mpci.c
@@ -115,7 +115,8 @@ void _MPCI_Create_server( void )
CPU_ALL_TASKS_ARE_FP,
PRIORITY_MINIMUM,
FALSE, /* no preempt */
- FALSE, /* not timesliced */
+ THREAD_CPU_BUDGET_ALGORITHM_NONE,
+ NULL, /* no budget algorithm callout */
0, /* all interrupts enabled */
_MPCI_Internal_name
);
diff --git a/c/src/exec/score/src/thread.c b/c/src/exec/score/src/thread.c
index 0d0d5cd43b..868407b3cd 100644
--- a/c/src/exec/score/src/thread.c
+++ b/c/src/exec/score/src/thread.c
@@ -136,7 +136,8 @@ void _Thread_Create_idle( void )
CPU_IDLE_TASK_IS_FP,
PRIORITY_MAXIMUM,
TRUE, /* preemptable */
- FALSE, /* not timesliced */
+ THREAD_CPU_BUDGET_ALGORITHM_NONE,
+ NULL, /* no budget algorithm callout */
0, /* all interrupts enabled */
_Thread_Idle_name
);
@@ -243,7 +244,8 @@ void _Thread_Dispatch( void )
_User_extensions_Thread_switch( executing, heir );
- heir->cpu_time_budget = _Thread_Ticks_per_timeslice;
+ if ( heir->budget_algorithm == THREAD_CPU_BUDGET_ALGORITHM_RESET_TIMESLICE )
+ heir->cpu_time_budget = _Thread_Ticks_per_timeslice;
/*
* If the CPU has hardware floating point, then we must address saving
@@ -383,17 +385,17 @@ static void _Thread_Stack_Free(
*/
boolean _Thread_Initialize(
- Objects_Information *information,
- Thread_Control *the_thread,
- void *stack_area, /* NULL if to be allocated */
- unsigned32 stack_size, /* insure it is >= min */
- boolean is_fp, /* TRUE if thread uses FP */
- Priority_Control priority,
- boolean is_preemptible,
- boolean is_timeslice,
- unsigned32 isr_level,
- Objects_Name name
-
+ Objects_Information *information,
+ Thread_Control *the_thread,
+ void *stack_area,
+ unsigned32 stack_size,
+ boolean is_fp,
+ Priority_Control priority,
+ boolean is_preemptible,
+ Thread_CPU_budget_algorithms budget_algorithm,
+ Thread_CPU_budget_algorithm_callout budget_callout,
+ unsigned32 isr_level,
+ Objects_Name name
)
{
unsigned32 actual_stack_size = 0;
@@ -480,9 +482,10 @@ boolean _Thread_Initialize(
* General initialization
*/
- the_thread->Start.is_preemptible = is_preemptible;
- the_thread->Start.is_timeslice = is_timeslice;
- the_thread->Start.isr_level = isr_level;
+ the_thread->Start.is_preemptible = is_preemptible;
+ the_thread->Start.budget_algorithm = budget_algorithm;
+ the_thread->Start.budget_callout = budget_callout;
+ the_thread->Start.isr_level = isr_level;
the_thread->current_state = STATES_DORMANT;
the_thread->resource_count = 0;
@@ -573,8 +576,9 @@ boolean _Thread_Restart(
_Thread_Set_transient( the_thread );
the_thread->resource_count = 0;
- the_thread->is_preemptible = the_thread->Start.is_preemptible;
- the_thread->is_timeslice = the_thread->Start.is_timeslice;
+ the_thread->is_preemptible = the_thread->Start.is_preemptible;
+ 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.numeric_argument = numeric_argument;
@@ -874,7 +878,6 @@ void _Thread_Reset_timeslice( void )
_ISR_Disable( level );
if ( _Chain_Has_only_one_node( ready ) ) {
_ISR_Enable( level );
- executing->cpu_time_budget = _Thread_Ticks_per_timeslice;
return;
}
_Chain_Extract_unprotected( &executing->Object.Node );
@@ -905,13 +908,32 @@ void _Thread_Reset_timeslice( void )
void _Thread_Tickle_timeslice( void )
{
- if ( !_Thread_Executing->is_timeslice ||
- !_Thread_Executing->is_preemptible ||
- !_States_Is_ready( _Thread_Executing->current_state ) )
+ Thread_Control *executing;
+
+ executing = _Thread_Executing;
+
+ if ( !executing->is_preemptible )
+ return;
+
+ if ( !_States_Is_ready( executing->current_state ) )
return;
- if ( --_Thread_Executing->cpu_time_budget == 0 ) {
- _Thread_Reset_timeslice();
+ 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();
+ 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;
}
}
@@ -986,8 +1008,9 @@ void _Thread_Load_environment(
}
the_thread->do_post_task_switch_extension = FALSE;
- the_thread->is_preemptible = the_thread->Start.is_preemptible;
- the_thread->is_timeslice = the_thread->Start.is_timeslice;
+ the_thread->is_preemptible = the_thread->Start.is_preemptible;
+ the_thread->budget_algorithm = the_thread->Start.budget_algorithm;
+ the_thread->budget_callout = the_thread->Start.budget_callout;
_Context_Initialize(
&the_thread->Registers,
diff --git a/cpukit/rtems/src/tasks.c b/cpukit/rtems/src/tasks.c
index aec54fc7f4..403a26e0d4 100644
--- a/cpukit/rtems/src/tasks.c
+++ b/cpukit/rtems/src/tasks.c
@@ -354,7 +354,10 @@ rtems_status_code rtems_task_create(
is_fp,
core_priority,
_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),
&name
);
@@ -777,7 +780,12 @@ rtems_status_code rtems_task_mode(
asr = &api->Signal;
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 |= _ISR_Get_level();
@@ -790,8 +798,12 @@ rtems_status_code rtems_task_mode(
if ( mask & RTEMS_PREEMPT_MASK )
executing->is_preemptible = _Modes_Is_preempt(mode_set) ? TRUE : FALSE;
- if ( mask & RTEMS_TIMESLICE_MASK )
- executing->is_timeslice = _Modes_Is_timeslice(mode_set) ? TRUE : FALSE;
+ if ( mask & RTEMS_TIMESLICE_MASK ) {
+ 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
diff --git a/cpukit/score/src/mpci.c b/cpukit/score/src/mpci.c
index c3090aacc1..bc3381c925 100644
--- a/cpukit/score/src/mpci.c
+++ b/cpukit/score/src/mpci.c
@@ -115,7 +115,8 @@ void _MPCI_Create_server( void )
CPU_ALL_TASKS_ARE_FP,
PRIORITY_MINIMUM,
FALSE, /* no preempt */
- FALSE, /* not timesliced */
+ THREAD_CPU_BUDGET_ALGORITHM_NONE,
+ NULL, /* no budget algorithm callout */
0, /* all interrupts enabled */
_MPCI_Internal_name
);
diff --git a/cpukit/score/src/thread.c b/cpukit/score/src/thread.c
index 0d0d5cd43b..868407b3cd 100644
--- a/cpukit/score/src/thread.c
+++ b/cpukit/score/src/thread.c
@@ -136,7 +136,8 @@ void _Thread_Create_idle( void )
CPU_IDLE_TASK_IS_FP,
PRIORITY_MAXIMUM,
TRUE, /* preemptable */
- FALSE, /* not timesliced */
+ THREAD_CPU_BUDGET_ALGORITHM_NONE,
+ NULL, /* no budget algorithm callout */
0, /* all interrupts enabled */
_Thread_Idle_name
);
@@ -243,7 +244,8 @@ void _Thread_Dispatch( void )
_User_extensions_Thread_switch( executing, heir );
- heir->cpu_time_budget = _Thread_Ticks_per_timeslice;
+ if ( heir->budget_algorithm == THREAD_CPU_BUDGET_ALGORITHM_RESET_TIMESLICE )
+ heir->cpu_time_budget = _Thread_Ticks_per_timeslice;
/*
* If the CPU has hardware floating point, then we must address saving
@@ -383,17 +385,17 @@ static void _Thread_Stack_Free(
*/
boolean _Thread_Initialize(
- Objects_Information *information,
- Thread_Control *the_thread,
- void *stack_area, /* NULL if to be allocated */
- unsigned32 stack_size, /* insure it is >= min */
- boolean is_fp, /* TRUE if thread uses FP */
- Priority_Control priority,
- boolean is_preemptible,
- boolean is_timeslice,
- unsigned32 isr_level,
- Objects_Name name
-
+ Objects_Information *information,
+ Thread_Control *the_thread,
+ void *stack_area,
+ unsigned32 stack_size,
+ boolean is_fp,
+ Priority_Control priority,
+ boolean is_preemptible,
+ Thread_CPU_budget_algorithms budget_algorithm,
+ Thread_CPU_budget_algorithm_callout budget_callout,
+ unsigned32 isr_level,
+ Objects_Name name
)
{
unsigned32 actual_stack_size = 0;
@@ -480,9 +482,10 @@ boolean _Thread_Initialize(
* General initialization
*/
- the_thread->Start.is_preemptible = is_preemptible;
- the_thread->Start.is_timeslice = is_timeslice;
- the_thread->Start.isr_level = isr_level;
+ the_thread->Start.is_preemptible = is_preemptible;
+ the_thread->Start.budget_algorithm = budget_algorithm;
+ the_thread->Start.budget_callout = budget_callout;
+ the_thread->Start.isr_level = isr_level;
the_thread->current_state = STATES_DORMANT;
the_thread->resource_count = 0;
@@ -573,8 +576,9 @@ boolean _Thread_Restart(
_Thread_Set_transient( the_thread );
the_thread->resource_count = 0;
- the_thread->is_preemptible = the_thread->Start.is_preemptible;
- the_thread->is_timeslice = the_thread->Start.is_timeslice;
+ the_thread->is_preemptible = the_thread->Start.is_preemptible;
+ 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.numeric_argument = numeric_argument;
@@ -874,7 +878,6 @@ void _Thread_Reset_timeslice( void )
_ISR_Disable( level );
if ( _Chain_Has_only_one_node( ready ) ) {
_ISR_Enable( level );
- executing->cpu_time_budget = _Thread_Ticks_per_timeslice;
return;
}
_Chain_Extract_unprotected( &executing->Object.Node );
@@ -905,13 +908,32 @@ void _Thread_Reset_timeslice( void )
void _Thread_Tickle_timeslice( void )
{
- if ( !_Thread_Executing->is_timeslice ||
- !_Thread_Executing->is_preemptible ||
- !_States_Is_ready( _Thread_Executing->current_state ) )
+ Thread_Control *executing;
+
+ executing = _Thread_Executing;
+
+ if ( !executing->is_preemptible )
+ return;
+
+ if ( !_States_Is_ready( executing->current_state ) )
return;
- if ( --_Thread_Executing->cpu_time_budget == 0 ) {
- _Thread_Reset_timeslice();
+ 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();
+ 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;
}
}
@@ -986,8 +1008,9 @@ void _Thread_Load_environment(
}
the_thread->do_post_task_switch_extension = FALSE;
- the_thread->is_preemptible = the_thread->Start.is_preemptible;
- the_thread->is_timeslice = the_thread->Start.is_timeslice;
+ the_thread->is_preemptible = the_thread->Start.is_preemptible;
+ the_thread->budget_algorithm = the_thread->Start.budget_algorithm;
+ the_thread->budget_callout = the_thread->Start.budget_callout;
_Context_Initialize(
&the_thread->Registers,