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

4.115
Last change on this file since bf30999 was bf30999, checked in by Sebastian Huber <sebastian.huber@…>, on 08/23/13 at 14:15:50

smp: Add and use _Assert_Owner_of_giant()

Add and use _ISR_Disable_without_giant() and
_ISR_Enable_without_giant() if RTEMS_SMP is defined.

On single processor systems the ISR disable/enable was the big hammer
which ensured system-wide mutual exclusion. On SMP configurations this
no longer works since other processors do not care about disabled
interrupts on this processor and continue to execute freely.

On SMP in addition to ISR disable/enable an SMP lock must be used.
Currently we have only the Giant lock so we can check easily that ISR
disable/enable is used only in the right context.

  • Property mode set to 100644
File size: 6.0 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.com/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
20#ifdef __cplusplus
21extern "C" {
22#endif /* __cplusplus */
23
24#if defined(RTEMS_SMP) || \
25    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 this lock can be acquired.
100   */
101  void _Giant_Acquire( void );
102
103  /**
104   * @brief Releases the giant lock.
105   *
106   * This lock is implicitly released in
107   * _Thread_Dispatch_decrement_disable_level().
108   */
109  void _Giant_Release( void );
110
111  /**
112   *  @brief Sets thread dispatch level to the value passed in.
113   *
114   * This routine sets thread dispatch level to the
115   * value passed in.
116   */
117  uint32_t _Thread_Dispatch_set_disable_level(uint32_t value);
118
119  /**
120   *  @brief Increments the thread dispatch level.
121   *
122   * This rountine increments the thread dispatch level
123   */
124  uint32_t _Thread_Dispatch_increment_disable_level(void);
125
126  /**
127   *  @brief Decrements the thread dispatch level.
128   *
129   * This routine decrements the thread dispatch level.
130   */
131  uint32_t _Thread_Dispatch_decrement_disable_level(void);
132#else /* RTEMS_SMP */
133  /**
134   * @brief Set thread dispatch disable level.
135   *
136   * This routine sets thread dispatch level to the
137   * value passed in.
138   */
139  RTEMS_INLINE_ROUTINE uint32_t _Thread_Dispatch_set_disable_level(uint32_t value)
140  {
141    _Thread_Dispatch_disable_level = value;
142    return value;
143  }
144
145  /**
146   * @brief Increase thread dispatch disable level.
147   *
148   * This rountine increments the thread dispatch level
149   */
150  RTEMS_INLINE_ROUTINE uint32_t _Thread_Dispatch_increment_disable_level(void)
151  {
152    uint32_t level = _Thread_Dispatch_disable_level;
153
154    ++level;
155    _Thread_Dispatch_disable_level = level;
156
157    return level;
158  }
159
160  /**
161   * @brief Decrease thread dispatch disable level.
162   *
163   * This routine decrements the thread dispatch level.
164   */
165  RTEMS_INLINE_ROUTINE uint32_t _Thread_Dispatch_decrement_disable_level(void)
166  {
167    uint32_t level = _Thread_Dispatch_disable_level;
168
169    --level;
170    _Thread_Dispatch_disable_level = level;
171
172    return level;
173  }
174#endif /* RTEMS_SMP */
175
176/**
177 *  @brief Dispatch thread.
178 *
179 *  This routine is responsible for transferring control of the
180 *  processor from the executing thread to the heir thread. Once the
181 *  heir is running an attempt is made to dispatch any ASRs.
182 *  As part of this process, it is responsible for the following actions:
183 *     + saving the context of the executing thread
184 *     + restoring the context of the heir thread
185 *     + dispatching any signals for the resulting executing thread
186
187 *  ALTERNATE ENTRY POINTS:
188 *    void _Thread_Enable_dispatch();
189 *
190 *  - INTERRUPT LATENCY:
191 *    + dispatch thread
192 *    + no dispatch thread
193 */
194void _Thread_Dispatch( void );
195
196/**
197 * This routine prevents dispatching.
198 */
199
200#if defined ( __THREAD_DO_NOT_INLINE_DISABLE_DISPATCH__ )
201void _Thread_Disable_dispatch( void );
202#else
203RTEMS_INLINE_ROUTINE void _Thread_Disable_dispatch( void )
204{
205  _Thread_Dispatch_increment_disable_level();
206  RTEMS_COMPILER_MEMORY_BARRIER();
207}
208#endif
209
210/**
211 * This routine allows dispatching to occur again.  If this is
212 * the outer most dispatching critical section, then a dispatching
213 * operation will be performed and, if necessary, control of the
214 * processor will be transferred to the heir thread.
215 */
216
217#if defined ( __THREAD_DO_NOT_INLINE_ENABLE_DISPATCH__ )
218  void _Thread_Enable_dispatch( void );
219#else
220  /* inlining of enable dispatching must be true */
221  RTEMS_INLINE_ROUTINE void _Thread_Enable_dispatch( void )
222  {
223    RTEMS_COMPILER_MEMORY_BARRIER();
224    if ( _Thread_Dispatch_decrement_disable_level() == 0 )
225      _Thread_Dispatch();
226  }
227#endif
228
229/**
230 * This routine allows dispatching to occur again.  However,
231 * no dispatching operation is performed even if this is the outer
232 * most dispatching critical section.
233 */
234
235RTEMS_INLINE_ROUTINE void _Thread_Unnest_dispatch( void )
236{
237  RTEMS_COMPILER_MEMORY_BARRIER();
238  _Thread_Dispatch_decrement_disable_level();
239}
240
241/** @} */
242
243#ifdef __cplusplus
244}
245#endif /* __cplusplus */
246
247#endif /* _RTEMS_SCORE_THREADDISPATCH_H */
Note: See TracBrowser for help on using the repository browser.