summaryrefslogtreecommitdiffstats
path: root/cpukit/score/include/rtems/score/threaddispatch.h
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/include/rtems/score/threaddispatch.h
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/include/rtems/score/threaddispatch.h')
-rw-r--r--cpukit/score/include/rtems/score/threaddispatch.h71
1 files changed, 55 insertions, 16 deletions
diff --git a/cpukit/score/include/rtems/score/threaddispatch.h b/cpukit/score/include/rtems/score/threaddispatch.h
index aec436fb45..80de19d53b 100644
--- a/cpukit/score/include/rtems/score/threaddispatch.h
+++ b/cpukit/score/include/rtems/score/threaddispatch.h
@@ -193,26 +193,40 @@ RTEMS_INLINE_ROUTINE void _Thread_Dispatch_initialization( void )
#endif /* RTEMS_SMP */
/**
- * @brief Dispatch thread.
+ * @brief Performs a thread dispatch if necessary.
*
- * This routine is responsible for transferring control of the
- * processor from the executing thread to the heir thread. Once the
- * heir is running an attempt is made to dispatch any ASRs.
- * As part of this process, it is responsible for the following actions:
- * + saving the context of the executing thread
- * + restoring the context of the heir thread
- * + dispatching any signals for the resulting executing thread
-
- * ALTERNATE ENTRY POINTS:
- * void _Thread_Enable_dispatch();
+ * This routine is responsible for transferring control of the processor from
+ * the executing thread to the heir thread. Once the heir is running an
+ * attempt is made to run the pending post-switch thread actions.
*
- * - INTERRUPT LATENCY:
- * + dispatch thread
- * + no dispatch thread
+ * As part of this process, it is responsible for the following actions
+ * - update timing information of the executing thread,
+ * - save the context of the executing thread,
+ * - invokation of the thread switch user extensions,
+ * - restore the context of the heir thread, and
+ * - run of pending post-switch thread actions of the resulting executing
+ * thread.
+ *
+ * On entry the thread dispatch level must be equal to zero.
*/
void _Thread_Dispatch( void );
/**
+ * @brief Performs a thread dispatch on the current processor.
+ *
+ * On entry the thread dispatch disable level must be equal to one and
+ * interrupts must be disabled.
+ *
+ * This function assumes that a thread dispatch is necessary.
+ *
+ * @param[in] cpu_self The current processor.
+ * @param[in] level The previous interrupt level.
+ *
+ * @see _Thread_Dispatch().
+ */
+void _Thread_Do_dispatch( Per_CPU_Control *cpu_self, ISR_Level level );
+
+/**
* This routine prevents dispatching.
*/
@@ -228,8 +242,33 @@ RTEMS_INLINE_ROUTINE void _Thread_Disable_dispatch( void )
RTEMS_INLINE_ROUTINE void _Thread_Enable_dispatch_body( void )
{
- if ( _Thread_Dispatch_decrement_disable_level() == 0 )
- _Thread_Dispatch();
+ Per_CPU_Control *cpu_self;
+ uint32_t disable_level;
+
+ cpu_self = _Per_CPU_Get();
+
+#if defined( RTEMS_SMP )
+ _Giant_Release( cpu_self );
+#endif
+
+ disable_level = cpu_self->thread_dispatch_disable_level;
+
+ if ( disable_level == 1 ) {
+ ISR_Level level;
+
+ _ISR_Disable_without_giant( level );
+
+ if ( cpu_self->dispatch_necessary ) {
+ _Thread_Do_dispatch( cpu_self, level );
+ } else {
+ cpu_self->thread_dispatch_disable_level = 0;
+ _Profiling_Thread_dispatch_enable( cpu_self, 0 );
+ }
+
+ _ISR_Enable_without_giant( level );
+ } else {
+ cpu_self->thread_dispatch_disable_level = disable_level - 1;
+ }
}
/**