summaryrefslogtreecommitdiffstats
path: root/cpukit/score/src/threaddispatch.c
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2015-02-26 10:32:08 +0100
committerSebastian Huber <sebastian.huber@embedded-brains.de>2015-03-05 11:36:19 +0100
commit222dc775838c73708054db6283723027c5deb56c (patch)
tree13ef9e9fa22774f804cef04a61d459dc7d2fd89e /cpukit/score/src/threaddispatch.c
parentscore: Simplify and fix signal delivery (diff)
downloadrtems-222dc775838c73708054db6283723027c5deb56c.tar.bz2
score: Add and use _Thread_Do_dispatch()
The _Thread_Dispatch() function is quite complex and the time to set up and tear down the stack frame is significant. Split this function into two parts. The complex part is now in _Thread_Do_dispatch(). Call _Thread_Do_dispatch() in _Thread_Enable_dispatch() only if necessary. This increases the average case performance. Simplify _Thread_Handler() for SMP configurations. Update #2273.
Diffstat (limited to 'cpukit/score/src/threaddispatch.c')
-rw-r--r--cpukit/score/src/threaddispatch.c64
1 files changed, 34 insertions, 30 deletions
diff --git a/cpukit/score/src/threaddispatch.c b/cpukit/score/src/threaddispatch.c
index cc023fc57f..f20f427bd6 100644
--- a/cpukit/score/src/threaddispatch.c
+++ b/cpukit/score/src/threaddispatch.c
@@ -60,40 +60,15 @@ static void _Thread_Run_post_switch_actions( Thread_Control *executing )
_Thread_Action_release_and_ISR_enable( cpu_self, level );
}
-void _Thread_Dispatch( void )
+void _Thread_Do_dispatch( Per_CPU_Control *cpu_self, ISR_Level level )
{
- Per_CPU_Control *cpu_self;
- Thread_Control *executing;
- ISR_Level level;
-
-#if defined( RTEMS_SMP )
- /*
- * On SMP the complete context switch must be atomic with respect to one
- * processor. See also _Thread_Handler() since _Context_switch() may branch
- * to this function.
- */
- _ISR_Disable_without_giant( level );
-#endif
+ Thread_Control *executing;
- cpu_self = _Per_CPU_Get();
- _Assert( cpu_self->thread_dispatch_disable_level == 0 );
- _Profiling_Thread_dispatch_disable( cpu_self, 0 );
- cpu_self->thread_dispatch_disable_level = 1;
+ _Assert( cpu_self->thread_dispatch_disable_level == 1 );
- /*
- * Now determine if we need to perform a dispatch on the current CPU.
- */
executing = cpu_self->executing;
-#if !defined( RTEMS_SMP )
- _ISR_Disable( level );
-#endif
-
-#if defined( RTEMS_SMP )
- if ( cpu_self->dispatch_necessary ) {
-#else
- while ( cpu_self->dispatch_necessary ) {
-#endif
+ do {
Thread_Control *heir = _Thread_Get_heir_and_make_it_executing( cpu_self );
/*
@@ -115,6 +90,11 @@ void _Thread_Dispatch( void )
if ( heir->budget_algorithm == THREAD_CPU_BUDGET_ALGORITHM_RESET_TIMESLICE )
heir->cpu_time_budget = rtems_configuration_get_ticks_per_timeslice();
+ /*
+ * On SMP the complete context switch must be atomic with respect to one
+ * processor. See also _Thread_Handler() since _Context_switch() may branch
+ * to this function.
+ */
#if !defined( RTEMS_SMP )
_ISR_Enable( level );
#endif
@@ -158,7 +138,13 @@ void _Thread_Dispatch( void )
#if !defined( RTEMS_SMP )
_ISR_Disable( level );
#endif
- }
+ } while (
+#if defined( RTEMS_SMP )
+ false
+#else
+ cpu_self->dispatch_necessary
+#endif
+ );
post_switch:
_Assert( cpu_self->thread_dispatch_disable_level == 1 );
@@ -169,3 +155,21 @@ post_switch:
_Thread_Run_post_switch_actions( executing );
}
+
+void _Thread_Dispatch( void )
+{
+ ISR_Level level;
+ Per_CPU_Control *cpu_self;
+
+ _ISR_Disable_without_giant( level );
+
+ cpu_self = _Per_CPU_Get();
+
+ if ( cpu_self->dispatch_necessary ) {
+ _Profiling_Thread_dispatch_disable( cpu_self, 0 );
+ cpu_self->thread_dispatch_disable_level = 1;
+ _Thread_Do_dispatch( cpu_self, level );
+ } else {
+ _ISR_Enable_without_giant( level );
+ }
+}