source: rtems/cpukit/score/inline/rtems/score/thread.inl @ 3a8a999

4.115
Last change on this file since 3a8a999 was 3a8a999, checked in by Jennifer Averett <Jennifer.Averett@…>, on 05/23/11 at 13:30:15

2011-05-23 Jennifer Averett <Jennifer.Averett@…>

  • score/Makefile.am, score/include/rtems/score/thread.h, score/inline/rtems/score/thread.inl: Add smp support to dispable dispatch level accesses.
  • score/src/threaddispatchdisablelevel.c: New file.
  • Property mode set to 100644
File size: 9.0 KB
Line 
1/**
2 *  @file  rtems/score/thread.inl
3 *
4 *  This file contains the macro implementation of the inlined
5 *  routines from the Thread handler.
6 */
7
8/*
9 *  COPYRIGHT (c) 1989-2008.
10 *  On-Line Applications Research Corporation (OAR).
11 *
12 *  The license and distribution terms for this file may be
13 *  found in the file LICENSE in this distribution or at
14 *  http://www.rtems.com/license/LICENSE.
15 *
16 *  $Id$
17 */
18
19#ifndef _RTEMS_SCORE_THREAD_H
20# error "Never use <rtems/score/thread.inl> directly; include <rtems/score/thread.h> instead."
21#endif
22
23#ifndef _RTEMS_SCORE_THREAD_INL
24#define _RTEMS_SCORE_THREAD_INL
25
26#include <rtems/score/sysstate.h>
27#include <rtems/score/context.h>
28
29/**
30 *  @addtogroup ScoreThread
31 *  @{
32 */
33
34#if defined(RTEMS_SMP)
35
36  /*
37   * The _Thread_Dispatch_... functions are prototyped in thread.h.
38   */
39
40#else
41
42  /** @brief _Thread_Dispatch_in_critical_section
43   *
44   * This routine returns true if thread dispatch indicates
45   * that we are in a critical section.
46   */
47  RTEMS_INLINE_ROUTINE bool _Thread_Dispatch_in_critical_section(void)
48  {
49     if (  _Thread_Dispatch_disable_level == 0 )
50      return false;
51
52     return true;
53  }
54
55  /** @brief _Thread_Dispatch_get_disable_level
56   *
57   * This routine returns value of the the thread dispatch level.
58   */
59  RTEMS_INLINE_ROUTINE uint32_t _Thread_Dispatch_get_disable_level(void)
60  {
61    return _Thread_Dispatch_disable_level;
62  }
63
64  /** @brief _Thread_Dispatch_set_disable_level
65   *
66   * This routine sets thread dispatch level to the
67   * value passed in.
68   */
69  RTEMS_INLINE_ROUTINE uint32_t _Thread_Dispatch_set_disable_level(uint32_t value)
70  {
71    _Thread_Dispatch_disable_level = value;
72    return value;
73  }
74
75  /** @brief _Thread_Dispatch_increment_disable_level
76   *
77   * This rountine increments the thread dispatch level
78   */
79  RTEMS_INLINE_ROUTINE uint32_t _Thread_Dispatch_increment_disable_level(void)
80  {
81    _Thread_Dispatch_disable_level++;
82    return _Thread_Dispatch_disable_level;
83  }
84
85  /** @brief _Thread_Dispatch_decrement_disable_level
86   *
87   * This routine decrements the thread dispatch level.
88   */
89  RTEMS_INLINE_ROUTINE uint32_t _Thread_Dispatch_decrement_disable_level(void)
90  {
91    _Thread_Dispatch_disable_level--;
92    return _Thread_Dispatch_disable_level;
93  }
94
95  /** @brief _Thread_Dispatch_initialization
96   *
97   *  This routine initializes the thread dispatching subsystem.
98   */
99  RTEMS_INLINE_ROUTINE void _Thread_Dispatch_initialization( void )
100  {
101    _Thread_Dispatch_set_disable_level( 1 );
102  }
103
104#endif
105
106/**
107 *  This routine halts multitasking and returns control to
108 *  the "thread" (i.e. the BSP) which initially invoked the
109 *  routine which initialized the system.
110 */
111
112RTEMS_INLINE_ROUTINE void _Thread_Stop_multitasking( void )
113{
114  /*
115   *  This may look a bit of an odd but _Context_Restart_self is just
116   *  a very careful restore of a specific context which ensures that
117   *  if we were running within the same context, it would work.
118   *
119   *  And we will not return to this thread, so there is no point of
120   *  saving the context.
121   */
122  _Context_Restart_self( &_Thread_BSP_context );
123
124  /***************************************************************
125   ***************************************************************
126   *   SYSTEM SHUTS DOWN!!!  WE DO NOT RETURN TO THIS POINT!!!   *
127   ***************************************************************
128   ***************************************************************
129   */
130}
131
132/**
133 *  This function returns true if the_thread is the currently executing
134 *  thread, and false otherwise.
135 */
136
137RTEMS_INLINE_ROUTINE bool _Thread_Is_executing (
138  const Thread_Control *the_thread
139)
140{
141  return ( the_thread == _Thread_Executing );
142}
143
144/**
145 *  This function returns true if the_thread is the heir
146 *  thread, and false otherwise.
147 */
148
149RTEMS_INLINE_ROUTINE bool _Thread_Is_heir (
150  const Thread_Control *the_thread
151)
152{
153  return ( the_thread == _Thread_Heir );
154}
155
156/**
157 *  This function returns true if the currently executing thread
158 *  is also the heir thread, and false otherwise.
159 */
160
161RTEMS_INLINE_ROUTINE bool _Thread_Is_executing_also_the_heir( void )
162{
163  return ( _Thread_Executing == _Thread_Heir );
164}
165
166/**
167 *  This routine clears any blocking state for the_thread.  It performs
168 *  any necessary scheduling operations including the selection of
169 *  a new heir thread.
170 */
171
172RTEMS_INLINE_ROUTINE void _Thread_Unblock (
173  Thread_Control *the_thread
174)
175{
176  _Thread_Clear_state( the_thread, STATES_BLOCKED );
177}
178
179/**
180 *  This routine resets the current context of the calling thread
181 *  to that of its initial state.
182 */
183
184RTEMS_INLINE_ROUTINE void _Thread_Restart_self( void )
185{
186#if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
187  if ( _Thread_Executing->fp_context != NULL )
188    _Context_Restore_fp( &_Thread_Executing->fp_context );
189#endif
190
191  _CPU_Context_Restart_self( &_Thread_Executing->Registers );
192}
193
194/**
195 *  This function returns true if the floating point context of
196 *  the_thread is currently loaded in the floating point unit, and
197 *  false otherwise.
198 */
199
200#if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
201RTEMS_INLINE_ROUTINE bool _Thread_Is_allocated_fp (
202  const Thread_Control *the_thread
203)
204{
205  return ( the_thread == _Thread_Allocated_fp );
206}
207#endif
208
209/**
210 *  This routine is invoked when the currently loaded floating
211 *  point context is now longer associated with an active thread.
212 */
213
214#if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
215RTEMS_INLINE_ROUTINE void _Thread_Deallocate_fp( void )
216{
217  _Thread_Allocated_fp = NULL;
218}
219#endif
220
221/**
222 *  This routine prevents dispatching.
223 */
224
225#if defined ( __THREAD_DO_NOT_INLINE_DISABLE_DISPATCH__ )
226void _Thread_Disable_dispatch( void );
227#else
228RTEMS_INLINE_ROUTINE void _Thread_Disable_dispatch( void )
229{
230  _Thread_Dispatch_increment_disable_level();
231  RTEMS_COMPILER_MEMORY_BARRIER();
232}
233#endif
234
235/**
236 *  This routine allows dispatching to occur again.  If this is
237 *  the outer most dispatching critical section, then a dispatching
238 *  operation will be performed and, if necessary, control of the
239 *  processor will be transferred to the heir thread.
240 */
241
242#if defined ( __THREAD_DO_NOT_INLINE_ENABLE_DISPATCH__ )
243  void _Thread_Enable_dispatch( void );
244#else
245  /* inlining of enable dispatching must be true */
246  RTEMS_INLINE_ROUTINE void _Thread_Enable_dispatch( void )
247  {
248    RTEMS_COMPILER_MEMORY_BARRIER();
249    if ( _Thread_Dispatch_decrement_disable_level() == 0 )
250      _Thread_Dispatch();
251  }
252#endif
253
254/**
255 *  This routine allows dispatching to occur again.  However,
256 *  no dispatching operation is performed even if this is the outer
257 *  most dispatching critical section.
258 */
259
260RTEMS_INLINE_ROUTINE void _Thread_Unnest_dispatch( void )
261{
262  RTEMS_COMPILER_MEMORY_BARRIER();
263  _Thread_Dispatch_decrement_disable_level();
264}
265
266/**
267 *  This function returns true if dispatching is disabled, and false
268 *  otherwise.
269 */
270
271RTEMS_INLINE_ROUTINE bool _Thread_Is_dispatching_enabled( void )
272{
273  return  ( _Thread_Dispatch_in_critical_section() == false );
274}
275
276/**
277 *  This function returns true if dispatching is disabled, and false
278 *  otherwise.
279 */
280
281RTEMS_INLINE_ROUTINE bool _Thread_Is_context_switch_necessary( void )
282{
283  return ( _Thread_Dispatch_necessary );
284}
285
286/**
287 *  This function returns true if the_thread is NULL and false otherwise.
288 */
289
290RTEMS_INLINE_ROUTINE bool _Thread_Is_null (
291  const Thread_Control *the_thread
292)
293{
294  return ( the_thread == NULL );
295}
296
297/** @brief _Thread_Is_proxy_blocking
298 *
299 *  status which indicates that a proxy is blocking, and false otherwise.
300 */
301RTEMS_INLINE_ROUTINE bool _Thread_Is_proxy_blocking (
302  uint32_t   code
303)
304{
305  return (code == THREAD_STATUS_PROXY_BLOCKING);
306}
307
308/**
309 *  This routine allocates an internal thread.
310 */
311 
312RTEMS_INLINE_ROUTINE Thread_Control *_Thread_Internal_allocate( void )
313{
314  return (Thread_Control *) _Objects_Allocate( &_Thread_Internal_information );
315}
316 
317/**
318 *  This routine frees an internal thread.
319 */
320 
321RTEMS_INLINE_ROUTINE void _Thread_Internal_free (
322  Thread_Control *the_task
323)
324{
325  _Objects_Free( &_Thread_Internal_information, &the_task->Object );
326}
327
328/**
329 *  This routine returns the C library re-enterant pointer.
330 */
331 
332RTEMS_INLINE_ROUTINE struct _reent **_Thread_Get_libc_reent( void )
333{
334  return _Thread_libc_reent;
335}
336
337/**
338 *  This routine set the C library re-enterant pointer.
339 */
340 
341RTEMS_INLINE_ROUTINE void _Thread_Set_libc_reent (
342  struct _reent **libc_reent
343)
344{
345  _Thread_libc_reent = libc_reent;
346}
347
348/**
349 *  This routine evaluates the current scheduling information for the
350 *  system and determines if a context switch is required.  This
351 *  is usually called after changing an execution mode such as preemptability
352 *  for a thread.
353 *
354 *  @param[in] are_signals_pending specifies whether or not the API
355 *             level signals are pending and a dispatch is needed.
356 */
357RTEMS_INLINE_ROUTINE bool _Thread_Evaluate_is_dispatch_needed(
358  bool are_signals_pending
359)
360{
361  Thread_Control     *executing;
362
363  executing = _Thread_Executing;
364
365  if ( are_signals_pending ||
366       (!_Thread_Is_heir( executing ) && executing->is_preemptible) ) {
367    _Thread_Dispatch_necessary = true;
368    return true;
369  }
370
371  return false;
372}
373
374/**@}*/
375
376#endif
377/* end of include file */
Note: See TracBrowser for help on using the repository browser.