source: rtems/cpukit/score/inline/rtems/score/thread.inl @ c5ed148

4.115
Last change on this file since c5ed148 was 86c847c1, checked in by Sebastian Huber <sebastian.huber@…>, on 09/24/11 at 12:45:55

2011-09-24 Sebastian Huber <sebastian.huber@…>

PR 1921/cpukit

  • score/inline/rtems/score/thread.inl, score/src/threadstartmultitasking.c: Allow CPU port to provide optional multitasking start and stop.
  • Property mode set to 100644
File size: 9.1 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#if defined(_CPU_Stop_multitasking)
115  _CPU_Stop_multitasking( &_Thread_BSP_context );
116#else
117  /*
118   *  This may look a bit of an odd but _Context_Restart_self is just
119   *  a very careful restore of a specific context which ensures that
120   *  if we were running within the same context, it would work.
121   *
122   *  And we will not return to this thread, so there is no point of
123   *  saving the context.
124   */
125  _Context_Restart_self( &_Thread_BSP_context );
126#endif
127
128  /***************************************************************
129   ***************************************************************
130   *   SYSTEM SHUTS DOWN!!!  WE DO NOT RETURN TO THIS POINT!!!   *
131   ***************************************************************
132   ***************************************************************
133   */
134}
135
136/**
137 *  This function returns true if the_thread is the currently executing
138 *  thread, and false otherwise.
139 */
140
141RTEMS_INLINE_ROUTINE bool _Thread_Is_executing (
142  const Thread_Control *the_thread
143)
144{
145  return ( the_thread == _Thread_Executing );
146}
147
148/**
149 *  This function returns true if the_thread is the heir
150 *  thread, and false otherwise.
151 */
152
153RTEMS_INLINE_ROUTINE bool _Thread_Is_heir (
154  const Thread_Control *the_thread
155)
156{
157  return ( the_thread == _Thread_Heir );
158}
159
160/**
161 *  This function returns true if the currently executing thread
162 *  is also the heir thread, and false otherwise.
163 */
164
165RTEMS_INLINE_ROUTINE bool _Thread_Is_executing_also_the_heir( void )
166{
167  return ( _Thread_Executing == _Thread_Heir );
168}
169
170/**
171 *  This routine clears any blocking state for the_thread.  It performs
172 *  any necessary scheduling operations including the selection of
173 *  a new heir thread.
174 */
175
176RTEMS_INLINE_ROUTINE void _Thread_Unblock (
177  Thread_Control *the_thread
178)
179{
180  _Thread_Clear_state( the_thread, STATES_BLOCKED );
181}
182
183/**
184 *  This routine resets the current context of the calling thread
185 *  to that of its initial state.
186 */
187
188RTEMS_INLINE_ROUTINE void _Thread_Restart_self( void )
189{
190#if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
191  if ( _Thread_Executing->fp_context != NULL )
192    _Context_Restore_fp( &_Thread_Executing->fp_context );
193#endif
194
195  _CPU_Context_Restart_self( &_Thread_Executing->Registers );
196}
197
198/**
199 *  This function returns true if the floating point context of
200 *  the_thread is currently loaded in the floating point unit, and
201 *  false otherwise.
202 */
203
204#if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
205RTEMS_INLINE_ROUTINE bool _Thread_Is_allocated_fp (
206  const Thread_Control *the_thread
207)
208{
209  return ( the_thread == _Thread_Allocated_fp );
210}
211#endif
212
213/**
214 *  This routine is invoked when the currently loaded floating
215 *  point context is now longer associated with an active thread.
216 */
217
218#if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
219RTEMS_INLINE_ROUTINE void _Thread_Deallocate_fp( void )
220{
221  _Thread_Allocated_fp = NULL;
222}
223#endif
224
225/**
226 *  This routine prevents dispatching.
227 */
228
229#if defined ( __THREAD_DO_NOT_INLINE_DISABLE_DISPATCH__ )
230void _Thread_Disable_dispatch( void );
231#else
232RTEMS_INLINE_ROUTINE void _Thread_Disable_dispatch( void )
233{
234  _Thread_Dispatch_increment_disable_level();
235  RTEMS_COMPILER_MEMORY_BARRIER();
236}
237#endif
238
239/**
240 *  This routine allows dispatching to occur again.  If this is
241 *  the outer most dispatching critical section, then a dispatching
242 *  operation will be performed and, if necessary, control of the
243 *  processor will be transferred to the heir thread.
244 */
245
246#if defined ( __THREAD_DO_NOT_INLINE_ENABLE_DISPATCH__ )
247  void _Thread_Enable_dispatch( void );
248#else
249  /* inlining of enable dispatching must be true */
250  RTEMS_INLINE_ROUTINE void _Thread_Enable_dispatch( void )
251  {
252    RTEMS_COMPILER_MEMORY_BARRIER();
253    if ( _Thread_Dispatch_decrement_disable_level() == 0 )
254      _Thread_Dispatch();
255  }
256#endif
257
258/**
259 *  This routine allows dispatching to occur again.  However,
260 *  no dispatching operation is performed even if this is the outer
261 *  most dispatching critical section.
262 */
263
264RTEMS_INLINE_ROUTINE void _Thread_Unnest_dispatch( void )
265{
266  RTEMS_COMPILER_MEMORY_BARRIER();
267  _Thread_Dispatch_decrement_disable_level();
268}
269
270/**
271 *  This function returns true if dispatching is disabled, and false
272 *  otherwise.
273 */
274
275RTEMS_INLINE_ROUTINE bool _Thread_Is_dispatching_enabled( void )
276{
277  return  ( _Thread_Dispatch_in_critical_section() == false );
278}
279
280/**
281 *  This function returns true if dispatching is disabled, and false
282 *  otherwise.
283 */
284
285RTEMS_INLINE_ROUTINE bool _Thread_Is_context_switch_necessary( void )
286{
287  return ( _Thread_Dispatch_necessary );
288}
289
290/**
291 *  This function returns true if the_thread is NULL and false otherwise.
292 */
293
294RTEMS_INLINE_ROUTINE bool _Thread_Is_null (
295  const Thread_Control *the_thread
296)
297{
298  return ( the_thread == NULL );
299}
300
301/** @brief _Thread_Is_proxy_blocking
302 *
303 *  status which indicates that a proxy is blocking, and false otherwise.
304 */
305RTEMS_INLINE_ROUTINE bool _Thread_Is_proxy_blocking (
306  uint32_t   code
307)
308{
309  return (code == THREAD_STATUS_PROXY_BLOCKING);
310}
311
312/**
313 *  This routine allocates an internal thread.
314 */
315 
316RTEMS_INLINE_ROUTINE Thread_Control *_Thread_Internal_allocate( void )
317{
318  return (Thread_Control *) _Objects_Allocate( &_Thread_Internal_information );
319}
320 
321/**
322 *  This routine frees an internal thread.
323 */
324 
325RTEMS_INLINE_ROUTINE void _Thread_Internal_free (
326  Thread_Control *the_task
327)
328{
329  _Objects_Free( &_Thread_Internal_information, &the_task->Object );
330}
331
332/**
333 *  This routine returns the C library re-enterant pointer.
334 */
335 
336RTEMS_INLINE_ROUTINE struct _reent **_Thread_Get_libc_reent( void )
337{
338  return _Thread_libc_reent;
339}
340
341/**
342 *  This routine set the C library re-enterant pointer.
343 */
344 
345RTEMS_INLINE_ROUTINE void _Thread_Set_libc_reent (
346  struct _reent **libc_reent
347)
348{
349  _Thread_libc_reent = libc_reent;
350}
351
352/**
353 *  This routine evaluates the current scheduling information for the
354 *  system and determines if a context switch is required.  This
355 *  is usually called after changing an execution mode such as preemptability
356 *  for a thread.
357 *
358 *  @param[in] are_signals_pending specifies whether or not the API
359 *             level signals are pending and a dispatch is needed.
360 */
361RTEMS_INLINE_ROUTINE bool _Thread_Evaluate_is_dispatch_needed(
362  bool are_signals_pending
363)
364{
365  Thread_Control     *executing;
366
367  executing = _Thread_Executing;
368
369  if ( are_signals_pending ||
370       (!_Thread_Is_heir( executing ) && executing->is_preemptible) ) {
371    _Thread_Dispatch_necessary = true;
372    return true;
373  }
374
375  return false;
376}
377
378/**@}*/
379
380#endif
381/* end of include file */
Note: See TracBrowser for help on using the repository browser.