source: rtems/cpukit/score/src/threadhandler.c @ 4fc370e

4.115
Last change on this file since 4fc370e was 4fc370e, checked in by Sebastian Huber <sebastian.huber@…>, on Jun 5, 2013 at 10:08:23 AM

score: Move thread dispatch content to new file

Move thread dispatch declarations and inline functions to new header
<rtems/score/threaddispatch.h> to make it independent of the
Thread_Control structure. This avoids a cyclic dependency in case
thread dispatch functions are used for the object implementation.

  • Property mode set to 100644
File size: 5.0 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  #if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
100    #if ( CPU_USE_DEFERRED_FP_SWITCH == TRUE )
101      if ( (executing->fp_context != NULL) &&
102            !_Thread_Is_allocated_fp( executing ) ) {
103        if ( _Thread_Allocated_fp != NULL )
104          _Context_Save_fp( &_Thread_Allocated_fp->fp_context );
105        _Thread_Allocated_fp = executing;
106      }
107    #endif
108  #endif
109
110  /*
111   * Take care that 'begin' extensions get to complete before
112   * 'switch' extensions can run.  This means must keep dispatch
113   * disabled until all 'begin' extensions complete.
114   */
115  _User_extensions_Thread_begin( executing );
116
117  /*
118   *  At this point, the dispatch disable level BETTER be 1.
119   */
120  _Thread_Enable_dispatch();
121
122  #if defined(EXECUTE_GLOBAL_CONSTRUCTORS)
123    /*
124     *  _init could be a weak symbol and we SHOULD test it but it isn't
125     *  in any configuration I know of and it generates a warning on every
126     *  RTEMS target configuration.  --joel (12 May 2007)
127     */
128    if (doCons) /* && (volatile void *)_init) */ {
129      INIT_NAME ();
130    }
131 #endif
132
133  if ( executing->Start.prototype == THREAD_START_NUMERIC ) {
134    executing->Wait.return_argument =
135      (*(Thread_Entry_numeric) executing->Start.entry_point)(
136        executing->Start.numeric_argument
137      );
138  }
139  #if defined(RTEMS_POSIX_API)
140    else if ( executing->Start.prototype == THREAD_START_POINTER ) {
141      executing->Wait.return_argument =
142        (*(Thread_Entry_pointer) executing->Start.entry_point)(
143          executing->Start.pointer_argument
144        );
145    }
146  #endif
147  #if defined(FUNCTIONALITY_NOT_CURRENTLY_USED_BY_ANY_API)
148    else if ( executing->Start.prototype == THREAD_START_BOTH_POINTER_FIRST ) {
149      executing->Wait.return_argument =
150         (*(Thread_Entry_both_pointer_first) executing->Start.entry_point)(
151           executing->Start.pointer_argument,
152           executing->Start.numeric_argument
153         );
154    }
155    else if ( executing->Start.prototype == THREAD_START_BOTH_NUMERIC_FIRST ) {
156      executing->Wait.return_argument =
157       (*(Thread_Entry_both_numeric_first) executing->Start.entry_point)(
158         executing->Start.numeric_argument,
159         executing->Start.pointer_argument
160       );
161    }
162  #endif
163
164  /*
165   *  In the switch above, the return code from the user thread body
166   *  was placed in return_argument.  This assumed that if it returned
167   *  anything (which is not supporting in all APIs), then it would be
168   *  able to fit in a (void *).
169   */
170
171  _User_extensions_Thread_exitted( executing );
172
173  _Internal_error_Occurred(
174    INTERNAL_ERROR_CORE,
175    true,
176    INTERNAL_ERROR_THREAD_EXITTED
177  );
178}
Note: See TracBrowser for help on using the repository browser.