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

4.115
Last change on this file since e3be691 was e3be691, checked in by Sebastian Huber <sebastian.huber@…>, on May 27, 2013 at 3:31:46 PM

score: Remove idle field of Per_CPU_Control

This field is unused except for special case simulator clock drivers.
In these places use an alternative. Add and use
_Thread_Set_global_exit_status() and _Thread_Get_global_exit_status().

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