source: rtems/cpukit/score/src/threadhandler.c @ 155ea78

4.115
Last change on this file since 155ea78 was 155ea78, checked in by Joel Sherrill <joel.sherrill@…>, on 07/09/13 at 16:15:34

threadhandler.c: Add comments

  • Property mode set to 100644
File size: 5.4 KB
Line 
1/**
2 *  @file
3 *
4 *  @brief Thread Handler
5 *  @ingroup ScoreThread
6 */
7
8/*
9 *  COPYRIGHT (c) 1989-2012.
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
17#if HAVE_CONFIG_H
18#include "config.h"
19#endif
20
21#include <rtems/system.h>
22#include <rtems/score/apiext.h>
23#include <rtems/score/context.h>
24#include <rtems/score/interr.h>
25#include <rtems/score/isr.h>
26#include <rtems/score/object.h>
27#include <rtems/score/priority.h>
28#include <rtems/score/states.h>
29#include <rtems/score/sysstate.h>
30#include <rtems/score/thread.h>
31#include <rtems/score/threaddispatch.h>
32#include <rtems/score/threadq.h>
33#include <rtems/score/userextimpl.h>
34#include <rtems/score/wkspace.h>
35#if defined(RTEMS_SMP)
36  #include <rtems/score/smp.h>
37#endif
38
39/*
40 *  Conditional magic to determine what style of C++ constructor
41 *  initialization this target and compiler version uses.
42 */
43#if defined(__USE_INIT_FINI__)
44  #if defined(__M32R__)
45    #define INIT_NAME __init
46  #elif defined(__ARM_EABI__)
47    #define INIT_NAME __libc_init_array
48  #else
49    #define INIT_NAME _init
50  #endif
51
52  extern void INIT_NAME(void);
53  #define EXECUTE_GLOBAL_CONSTRUCTORS
54#endif
55
56#if defined(__USE__MAIN__)
57  extern void __main(void);
58  #define INIT_NAME __main
59  #define EXECUTE_GLOBAL_CONSTRUCTORS
60#endif
61
62void _Thread_Handler( void )
63{
64  ISR_Level  level;
65  Thread_Control *executing;
66  #if defined(EXECUTE_GLOBAL_CONSTRUCTORS)
67    static bool doneConstructors;
68    bool doCons;
69  #endif
70
71  executing = _Thread_Executing;
72
73  /*
74   * Some CPUs need to tinker with the call frame or registers when the
75   * thread actually begins to execute for the first time.  This is a
76   * hook point where the port gets a shot at doing whatever it requires.
77   */
78  _Context_Initialization_at_thread_begin();
79
80  /*
81   * have to put level into a register for those cpu's that use
82   * inline asm here
83   */
84  level = executing->Start.isr_level;
85  _ISR_Set_level(level);
86
87  #if defined(EXECUTE_GLOBAL_CONSTRUCTORS)
88    #if defined(RTEMS_MULTIPROCESSING)
89      doCons = !doneConstructors
90        && _Objects_Get_API( executing->Object.id ) != OBJECTS_INTERNAL_API;
91      if (doCons)
92        doneConstructors = true;
93    #else
94      doCons = !doneConstructors;
95      doneConstructors = true;
96    #endif
97  #endif
98
99  /*
100   * Initialize the floating point context because we do not come
101   * through _Thread_Dispatch on our first invocation. So the normal
102   * code path for performing the FP context switch is not hit.
103   */
104  #if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
105    #if ( CPU_USE_DEFERRED_FP_SWITCH == TRUE )
106      if ( (executing->fp_context != NULL) &&
107            !_Thread_Is_allocated_fp( executing ) ) {
108        if ( _Thread_Allocated_fp != NULL )
109          _Context_Save_fp( &_Thread_Allocated_fp->fp_context );
110        _Thread_Allocated_fp = executing;
111      }
112    #endif
113  #endif
114
115  /*
116   * Take care that 'begin' extensions get to complete before
117   * 'switch' extensions can run.  This means must keep dispatch
118   * disabled until all 'begin' extensions complete.
119   */
120  _User_extensions_Thread_begin( executing );
121
122  /*
123   *  At this point, the dispatch disable level BETTER be 1.
124   */
125  _Thread_Enable_dispatch();
126
127  #if defined(EXECUTE_GLOBAL_CONSTRUCTORS)
128    /*
129     *  _init could be a weak symbol and we SHOULD test it but it isn't
130     *  in any configuration I know of and it generates a warning on every
131     *  RTEMS target configuration.  --joel (12 May 2007)
132     */
133    if (doCons) /* && (volatile void *)_init) */ {
134      INIT_NAME ();
135    }
136 #endif
137
138  /*
139   *  RTEMS supports multiple APIs and each API can define a different
140   *  thread/task prototype. The following code supports invoking the
141   *  user thread entry point using the prototype expected.
142   */
143  if ( executing->Start.prototype == THREAD_START_NUMERIC ) {
144    executing->Wait.return_argument =
145      (*(Thread_Entry_numeric) executing->Start.entry_point)(
146        executing->Start.numeric_argument
147      );
148  }
149  #if defined(RTEMS_POSIX_API)
150    else if ( executing->Start.prototype == THREAD_START_POINTER ) {
151      executing->Wait.return_argument =
152        (*(Thread_Entry_pointer) executing->Start.entry_point)(
153          executing->Start.pointer_argument
154        );
155    }
156  #endif
157  #if defined(FUNCTIONALITY_NOT_CURRENTLY_USED_BY_ANY_API)
158    else if ( executing->Start.prototype == THREAD_START_BOTH_POINTER_FIRST ) {
159      executing->Wait.return_argument =
160         (*(Thread_Entry_both_pointer_first) executing->Start.entry_point)(
161           executing->Start.pointer_argument,
162           executing->Start.numeric_argument
163         );
164    }
165    else if ( executing->Start.prototype == THREAD_START_BOTH_NUMERIC_FIRST ) {
166      executing->Wait.return_argument =
167       (*(Thread_Entry_both_numeric_first) executing->Start.entry_point)(
168         executing->Start.numeric_argument,
169         executing->Start.pointer_argument
170       );
171    }
172  #endif
173
174  /*
175   *  In the switch above, the return code from the user thread body
176   *  was placed in return_argument.  This assumed that if it returned
177   *  anything (which is not supporting in all APIs), then it would be
178   *  able to fit in a (void *).
179   */
180
181  _User_extensions_Thread_exitted( executing );
182
183  _Internal_error_Occurred(
184    INTERNAL_ERROR_CORE,
185    true,
186    INTERNAL_ERROR_THREAD_EXITTED
187  );
188}
Note: See TracBrowser for help on using the repository browser.