source: rtems/cpukit/include/rtems/score/threaddispatch.h @ 21275b58

5
Last change on this file since 21275b58 was ba0e9631, checked in by Sebastian Huber <sebastian.huber@…>, on 08/10/18 at 05:34:03

score: Do not inline _Thread_Dispatch_enable()

This function is slighly too complex for inlining with two if
statements. The caller already needs a stack frame due to the potential
call to _Thread_Do_dispatch(). In _Thread_Dispatch_enable() the call to
_Thread_Do_dispatch() can be optimized to a tail call.

A text size comparision

(text size after patch - text size before patch)

/ text size before patch

on sparc/erc32 with SMP enabled showed these results:

Minimum -0.000697892 (fsdosfsname01.exe)
Median -0.00745021 (psxtimes01.exe)
Maximum -0.0233032 (spscheduler01.exe)

A text size comparision

text size after patch - text size before patch

on sparc/erc32 with SMP enabled showed these results:

Minimum -3312 (ada_sp09.exe)
Median -1024 (tm15.exe)
Maximum -592 (spglobalcon01.exe)

  • Property mode set to 100644
File size: 6.6 KB
RevLine 
[4fc370e]1/**
2 * @brief Constants and Structures Related with Thread Dispatch
3 */
4
5/*
6 * COPYRIGHT (c) 1989-2009.
7 * On-Line Applications Research Corporation (OAR).
8 *
9 * The license and distribution terms for this file may be
10 * found in the file LICENSE in this distribution or at
[c499856]11 * http://www.rtems.org/license/LICENSE.
[4fc370e]12 */
13
14#ifndef _RTEMS_SCORE_THREADDISPATCH_H
15#define _RTEMS_SCORE_THREADDISPATCH_H
16
[d19cce29]17#include <rtems/score/percpu.h>
[d5423295]18#include <rtems/score/isrlock.h>
[f980561]19#include <rtems/score/profiling.h>
[4fc370e]20
21#ifdef __cplusplus
22extern "C" {
23#endif /* __cplusplus */
24
25/**
26 * @addtogroup ScoreThread
27 *
28 * @{
29 */
30
[84e6f15]31#if defined(RTEMS_SMP) || ( CPU_ENABLE_ROBUST_THREAD_DISPATCH == TRUE )
32/**
33 * @brief Enables a robust thread dispatch.
34 *
35 * On each change of the thread dispatch disable level from one to zero the
36 * interrupt status is checked.  In case interrupts are disabled and SMP is
37 * enabled or the CPU port needs it, then the system terminates with the fatal
38 * internal error INTERNAL_ERROR_BAD_THREAD_DISPATCH_ENVIRONMENT.
39 */
40#define RTEMS_SCORE_ROBUST_THREAD_DISPATCH
41#endif
42
[49cdf40]43/**
44 * @brief Indicates if the executing thread is inside a thread dispatch
45 * critical section.
46 *
47 * @retval true Thread dispatching is enabled.
48 * @retval false The executing thread is inside a thread dispatch critical
49 * section and dispatching is not allowed.
50 */
51RTEMS_INLINE_ROUTINE bool _Thread_Dispatch_is_enabled(void)
52{
[d19cce29]53  bool enabled;
[49cdf40]54
[4fc370e]55#if defined(RTEMS_SMP)
[d19cce29]56  ISR_Level level;
[4fc370e]57
[4b04cb61]58  _ISR_Local_disable( level );
[d19cce29]59#endif
60
61  enabled = _Thread_Dispatch_disable_level == 0;
62
63#if defined(RTEMS_SMP)
[4b04cb61]64  _ISR_Local_enable( level );
[d19cce29]65#endif
66
67  return enabled;
68}
69
70/**
[cc69334f]71 * @brief Gets thread dispatch disable level.
[d19cce29]72 *
73 * @return The value of the thread dispatch level.
74 */
75RTEMS_INLINE_ROUTINE uint32_t _Thread_Dispatch_get_disable_level(void)
76{
77  return _Thread_Dispatch_disable_level;
78}
79
80/**
81 * @brief Thread dispatch initialization.
82 *
83 * This routine initializes the thread dispatching subsystem.
84 */
85RTEMS_INLINE_ROUTINE void _Thread_Dispatch_initialization( void )
86{
87  _Thread_Dispatch_disable_level = 1;
88}
[4fc370e]89
90/**
[222dc775]91 * @brief Performs a thread dispatch if necessary.
[4fc370e]92 *
[222dc775]93 * This routine is responsible for transferring control of the processor from
94 * the executing thread to the heir thread.  Once the heir is running an
95 * attempt is made to run the pending post-switch thread actions.
[4fc370e]96 *
[222dc775]97 * As part of this process, it is responsible for the following actions
98 *   - update timing information of the executing thread,
99 *   - save the context of the executing thread,
100 *   - invokation of the thread switch user extensions,
101 *   - restore the context of the heir thread, and
102 *   - run of pending post-switch thread actions of the resulting executing
103 *     thread.
104 *
105 * On entry the thread dispatch level must be equal to zero.
[4fc370e]106 */
107void _Thread_Dispatch( void );
108
[d78d529]109/**
110 * @brief Directly do a thread dispatch.
111 *
112 * Must be called with a thread dispatch disable level of one, otherwise the
113 * INTERNAL_ERROR_BAD_THREAD_DISPATCH_DISABLE_LEVEL will occur.  This function
114 * is useful for operations which synchronously block, e.g. self restart, self
115 * deletion, yield, sleep.
116 *
117 * @param[in] cpu_self The current processor.
118 *
119 * @see _Thread_Dispatch().
120 */
121void _Thread_Dispatch_direct( Per_CPU_Control *cpu_self );
122
[222dc775]123/**
124 * @brief Performs a thread dispatch on the current processor.
125 *
126 * On entry the thread dispatch disable level must be equal to one and
127 * interrupts must be disabled.
128 *
129 * This function assumes that a thread dispatch is necessary.
130 *
131 * @param[in] cpu_self The current processor.
132 * @param[in] level The previous interrupt level.
133 *
134 * @see _Thread_Dispatch().
135 */
136void _Thread_Do_dispatch( Per_CPU_Control *cpu_self, ISR_Level level );
137
[4fc370e]138/**
[1512761]139 * @brief Disables thread dispatching inside a critical section (interrupts
[0475cca]140 * disabled) with the current processor.
[1512761]141 *
[0475cca]142 * @param[in] cpu_self The current processor.
[d5423295]143 * @param[in] lock_context The lock context of the corresponding
144 * _ISR_lock_ISR_disable() that started the critical section.
145 *
[413b9e28]146 * @return The current processor.
[4fc370e]147 */
[0475cca]148RTEMS_INLINE_ROUTINE Per_CPU_Control *_Thread_Dispatch_disable_with_CPU(
149  Per_CPU_Control        *cpu_self,
[d5423295]150  const ISR_lock_Context *lock_context
151)
[4fc370e]152{
[0475cca]153  uint32_t disable_level;
[1512761]154
[413b9e28]155  disable_level = cpu_self->thread_dispatch_disable_level;
[d5423295]156  _Profiling_Thread_dispatch_disable_critical(
157    cpu_self,
158    disable_level,
159    lock_context
160  );
[1512761]161  cpu_self->thread_dispatch_disable_level = disable_level + 1;
[413b9e28]162
163  return cpu_self;
[4fc370e]164}
165
[0475cca]166/**
167 * @brief Disables thread dispatching inside a critical section (interrupts
168 * disabled).
169 *
170 * @param[in] lock_context The lock context of the corresponding
171 * _ISR_lock_ISR_disable() that started the critical section.
172 *
173 * @return The current processor.
174 */
175RTEMS_INLINE_ROUTINE Per_CPU_Control *_Thread_Dispatch_disable_critical(
176  const ISR_lock_Context *lock_context
177)
178{
179  return _Thread_Dispatch_disable_with_CPU( _Per_CPU_Get(), lock_context );
180}
181
[1512761]182/**
183 * @brief Disables thread dispatching.
184 *
185 * @return The current processor.
186 */
187RTEMS_INLINE_ROUTINE Per_CPU_Control *_Thread_Dispatch_disable( void )
[d2ffb7dc]188{
[d5423295]189  Per_CPU_Control  *cpu_self;
190  ISR_lock_Context  lock_context;
[1512761]191
192#if defined( RTEMS_SMP ) || defined( RTEMS_PROFILING )
[d5423295]193  _ISR_lock_ISR_disable( &lock_context );
[1512761]194#endif
[222dc775]195
[d5423295]196  cpu_self = _Thread_Dispatch_disable_critical( &lock_context );
[222dc775]197
[1512761]198#if defined( RTEMS_SMP ) || defined( RTEMS_PROFILING )
[d5423295]199  _ISR_lock_ISR_enable( &lock_context );
[222dc775]200#endif
201
[1512761]202  return cpu_self;
203}
204
205/**
206 * @brief Enables thread dispatching.
207 *
[ba0e9631]208 * May perform a thread dispatch if necessary as a side-effect.
[1512761]209 *
210 * @param[in] cpu_self The current processor.
211 */
[ba0e9631]212void _Thread_Dispatch_enable( Per_CPU_Control *cpu_self );
[d2ffb7dc]213
[d2bacb6c]214/**
215 * @brief Unnests thread dispatching.
216 *
217 * @param[in] cpu_self The current processor.
218 */
219RTEMS_INLINE_ROUTINE void _Thread_Dispatch_unnest( Per_CPU_Control *cpu_self )
220{
[fe7012a0]221  _Assert( cpu_self->thread_dispatch_disable_level > 0 );
[d2bacb6c]222  --cpu_self->thread_dispatch_disable_level;
223}
224
[9bb3ce39]225/**
226 * @brief Requests a thread dispatch on the target processor.
227 *
228 * @param[in] cpu_self The current processor.
229 * @param[in] cpu_target The target processor to request a thread dispatch.
230 */
231RTEMS_INLINE_ROUTINE void _Thread_Dispatch_request(
232  Per_CPU_Control *cpu_self,
233  Per_CPU_Control *cpu_target
234)
235{
236#if defined( RTEMS_SMP )
237  if ( cpu_self == cpu_target ) {
238    cpu_self->dispatch_necessary = true;
239  } else {
240    _Atomic_Fetch_or_ulong( &cpu_target->message, 0, ATOMIC_ORDER_RELEASE );
241    _CPU_SMP_Send_interrupt( _Per_CPU_Get_index( cpu_target ) );
242  }
243#else
244 cpu_self->dispatch_necessary = true;
245 (void) cpu_target;
246#endif
247}
248
[4fc370e]249/** @} */
250
251#ifdef __cplusplus
252}
253#endif /* __cplusplus */
254
255#endif /* _RTEMS_SCORE_THREADDISPATCH_H */
Note: See TracBrowser for help on using the repository browser.