source: rtems/cpukit/score/include/rtems/score/threaddispatch.h @ b99be6e

4.115
Last change on this file since b99be6e was b99be6e, checked in by Sebastian Huber <sebastian.huber@…>, on 02/26/15 at 10:32:45

score: Inline _Thread_Disable_dispatch() for SMP

  • Property mode set to 100644
File size: 6.7 KB
Line 
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
11 * http://www.rtems.org/license/LICENSE.
12 */
13
14#ifndef _RTEMS_SCORE_THREADDISPATCH_H
15#define _RTEMS_SCORE_THREADDISPATCH_H
16
17#include <rtems/score/percpu.h>
18#include <rtems/score/smplock.h>
19#include <rtems/score/profiling.h>
20
21#ifdef __cplusplus
22extern "C" {
23#endif /* __cplusplus */
24
25#if defined(RTEMS_HEAVY_STACK_DEBUG) || \
26    defined(RTEMS_HEAVY_MALLOC_DEBUG)
27  #define __THREAD_DO_NOT_INLINE_DISABLE_DISPATCH__
28#endif
29
30#if defined(RTEMS_SMP) || \
31   (CPU_INLINE_ENABLE_DISPATCH == FALSE) || \
32   (__RTEMS_DO_NOT_INLINE_THREAD_ENABLE_DISPATCH__ == 1)
33  #define __THREAD_DO_NOT_INLINE_ENABLE_DISPATCH__
34#endif
35
36/**
37 * @addtogroup ScoreThread
38 *
39 * @{
40 */
41
42/**
43 * @brief Indicates if the executing thread is inside a thread dispatch
44 * critical section.
45 *
46 * @retval true Thread dispatching is enabled.
47 * @retval false The executing thread is inside a thread dispatch critical
48 * section and dispatching is not allowed.
49 */
50RTEMS_INLINE_ROUTINE bool _Thread_Dispatch_is_enabled(void)
51{
52  bool enabled;
53
54#if defined(RTEMS_SMP)
55  ISR_Level level;
56
57  _ISR_Disable_without_giant( level );
58#endif
59
60  enabled = _Thread_Dispatch_disable_level == 0;
61
62#if defined(RTEMS_SMP)
63  _ISR_Enable_without_giant( level );
64#endif
65
66  return enabled;
67}
68
69/**
70 * @briefs Gets thread dispatch disable level.
71 *
72 * @return The value of the thread dispatch level.
73 */
74RTEMS_INLINE_ROUTINE uint32_t _Thread_Dispatch_get_disable_level(void)
75{
76  return _Thread_Dispatch_disable_level;
77}
78
79/**
80 * @brief Thread dispatch initialization.
81 *
82 * This routine initializes the thread dispatching subsystem.
83 */
84RTEMS_INLINE_ROUTINE void _Thread_Dispatch_initialization( void )
85{
86  _Thread_Dispatch_disable_level = 1;
87}
88
89#if defined(RTEMS_SMP)
90  /**
91   * @brief Acquires the giant lock.
92   *
93   * The giant lock is a recursive SMP lock protecting nearly all operating
94   * system services.
95   *
96   * This lock is implicitly acquired in
97   * _Thread_Dispatch_increment_disable_level().
98   *
99   * Thread dispatching must be disabled before the Giant lock can be acquired
100   * and must no be enabled while owning the Giant lock.  The thread dispatch
101   * disable level is not altered by this function.
102   *
103   * @param[in] cpu_self The current processor.
104   */
105  void _Giant_Acquire( Per_CPU_Control *cpu_self );
106
107  /**
108   * @brief Releases the giant lock.
109   *
110   * This lock is implicitly released in
111   * _Thread_Dispatch_decrement_disable_level().
112   *
113   * The thread dispatch disable level is not altered by this function.
114   *
115   * @param[in] cpu_self The current processor.
116   */
117  void _Giant_Release( Per_CPU_Control *cpu_self );
118
119  /**
120   * @brief Releases the giant lock completely if held by the executing processor.
121   *
122   * The thread dispatch disable level is not altered by this function.
123   *
124   * The only use case for this operation is in _SMP_Request_shutdown().
125   *
126   * @param[in] cpu_self The current processor.
127   */
128  void _Giant_Drop( Per_CPU_Control *cpu_self );
129
130  /**
131   *  @brief Increments the thread dispatch level.
132   *
133   * This rountine increments the thread dispatch level
134   */
135  uint32_t _Thread_Dispatch_increment_disable_level(void);
136
137  /**
138   *  @brief Decrements the thread dispatch level.
139   *
140   * This routine decrements the thread dispatch level.
141   */
142  uint32_t _Thread_Dispatch_decrement_disable_level(void);
143#else /* RTEMS_SMP */
144  /**
145   * @brief Increase thread dispatch disable level.
146   *
147   * This rountine increments the thread dispatch level
148   */
149  RTEMS_INLINE_ROUTINE uint32_t _Thread_Dispatch_increment_disable_level(void)
150  {
151    uint32_t disable_level = _Thread_Dispatch_disable_level;
152#if defined( RTEMS_PROFILING )
153    ISR_Level level;
154
155    _ISR_Disable( level );
156    _Profiling_Thread_dispatch_disable( _Per_CPU_Get(), disable_level );
157#endif
158
159    ++disable_level;
160    _Thread_Dispatch_disable_level = disable_level;
161
162#if defined( RTEMS_PROFILING )
163    _ISR_Enable( level );
164#endif
165
166    return disable_level;
167  }
168
169  /**
170   * @brief Decrease thread dispatch disable level.
171   *
172   * This routine decrements the thread dispatch level.
173   */
174  RTEMS_INLINE_ROUTINE uint32_t _Thread_Dispatch_decrement_disable_level(void)
175  {
176    uint32_t disable_level = _Thread_Dispatch_disable_level;
177#if defined( RTEMS_PROFILING )
178    ISR_Level level;
179
180    _ISR_Disable( level );
181#endif
182
183    --disable_level;
184    _Thread_Dispatch_disable_level = disable_level;
185
186#if defined( RTEMS_PROFILING )
187    _Profiling_Thread_dispatch_enable( _Per_CPU_Get(), disable_level );
188    _ISR_Enable( level );
189#endif
190
191    return disable_level;
192  }
193#endif /* RTEMS_SMP */
194
195/**
196 *  @brief Dispatch thread.
197 *
198 *  This routine is responsible for transferring control of the
199 *  processor from the executing thread to the heir thread. Once the
200 *  heir is running an attempt is made to dispatch any ASRs.
201 *  As part of this process, it is responsible for the following actions:
202 *     + saving the context of the executing thread
203 *     + restoring the context of the heir thread
204 *     + dispatching any signals for the resulting executing thread
205
206 *  ALTERNATE ENTRY POINTS:
207 *    void _Thread_Enable_dispatch();
208 *
209 *  - INTERRUPT LATENCY:
210 *    + dispatch thread
211 *    + no dispatch thread
212 */
213void _Thread_Dispatch( void );
214
215/**
216 * This routine prevents dispatching.
217 */
218
219#if defined ( __THREAD_DO_NOT_INLINE_DISABLE_DISPATCH__ )
220void _Thread_Disable_dispatch( void );
221#else
222RTEMS_INLINE_ROUTINE void _Thread_Disable_dispatch( void )
223{
224  _Thread_Dispatch_increment_disable_level();
225  RTEMS_COMPILER_MEMORY_BARRIER();
226}
227#endif
228
229/**
230 * This routine allows dispatching to occur again.  If this is
231 * the outer most dispatching critical section, then a dispatching
232 * operation will be performed and, if necessary, control of the
233 * processor will be transferred to the heir thread.
234 */
235
236#if defined ( __THREAD_DO_NOT_INLINE_ENABLE_DISPATCH__ )
237  void _Thread_Enable_dispatch( void );
238#else
239  /* inlining of enable dispatching must be true */
240  RTEMS_INLINE_ROUTINE void _Thread_Enable_dispatch( void )
241  {
242    RTEMS_COMPILER_MEMORY_BARRIER();
243    if ( _Thread_Dispatch_decrement_disable_level() == 0 )
244      _Thread_Dispatch();
245  }
246#endif
247
248/**
249 * This routine allows dispatching to occur again.  However,
250 * no dispatching operation is performed even if this is the outer
251 * most dispatching critical section.
252 */
253
254RTEMS_INLINE_ROUTINE void _Thread_Unnest_dispatch( void )
255{
256  RTEMS_COMPILER_MEMORY_BARRIER();
257  _Thread_Dispatch_decrement_disable_level();
258}
259
260/** @} */
261
262#ifdef __cplusplus
263}
264#endif /* __cplusplus */
265
266#endif /* _RTEMS_SCORE_THREADDISPATCH_H */
Note: See TracBrowser for help on using the repository browser.