From 222dc775838c73708054db6283723027c5deb56c Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Thu, 26 Feb 2015 10:32:08 +0100 Subject: 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. --- cpukit/score/src/threaddispatch.c | 64 +++++++++++++++++++++------------------ 1 file changed, 34 insertions(+), 30 deletions(-) (limited to 'cpukit/score/src/threaddispatch.c') 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 ); + } +} -- cgit v1.2.3