source: rtems/cpukit/score/src/threadhandler.c @ 0a97ba5b

5
Last change on this file since 0a97ba5b was ccd5434, checked in by Sebastian Huber <sebastian.huber@…>, on 01/07/16 at 08:55:45

score: Introduce Thread_Entry_information

This avoids potential dead code in _Thread_Handler(). It gets rid of
the dangerous function pointer casts.

Update #2514.

  • Property mode set to 100644
File size: 3.1 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.org/license/LICENSE.
15 */
16
17#if HAVE_CONFIG_H
18#include "config.h"
19#endif
20
21#include <rtems/score/threadimpl.h>
22#include <rtems/score/assert.h>
23#include <rtems/score/interr.h>
24#include <rtems/score/isrlevel.h>
25#include <rtems/score/userextimpl.h>
26
27void _Thread_Handler( void )
28{
29  Thread_Control  *executing = _Thread_Executing;
30  ISR_Level        level;
31  Per_CPU_Control *cpu_self;
32
33  /*
34   * Some CPUs need to tinker with the call frame or registers when the
35   * thread actually begins to execute for the first time.  This is a
36   * hook point where the port gets a shot at doing whatever it requires.
37   */
38  _Context_Initialization_at_thread_begin();
39
40  #if defined(RTEMS_SMP)
41    /* On SMP we enter _Thread_Handler() with interrupts disabled */
42    _Assert( _ISR_Get_level() != 0 );
43
44    _Thread_Debug_set_real_processor( executing, _Per_CPU_Get() );
45  #endif
46
47  /*
48   * have to put level into a register for those cpu's that use
49   * inline asm here
50   */
51  level = executing->Start.isr_level;
52  _ISR_Set_level( level );
53
54  /*
55   * Initialize the floating point context because we do not come
56   * through _Thread_Dispatch on our first invocation. So the normal
57   * code path for performing the FP context switch is not hit.
58   */
59  _Thread_Restore_fp( executing );
60
61  /*
62   * Take care that 'begin' extensions get to complete before
63   * 'switch' extensions can run.  This means must keep dispatch
64   * disabled until all 'begin' extensions complete.
65   */
66  _User_extensions_Thread_begin( executing );
67
68  /*
69   * Do not use the level of the thread control block, since it has a
70   * different format.
71   */
72  _ISR_Disable_without_giant( level );
73
74  /*
75   *  At this point, the dispatch disable level BETTER be 1.
76   */
77  cpu_self = _Per_CPU_Get();
78  _Assert( cpu_self->thread_dispatch_disable_level == 1 );
79
80  /*
81   * Make sure we lose no thread dispatch necessary update and execute the
82   * post-switch actions.  As a side-effect change the thread dispatch level
83   * from one to zero.  Do not use _Thread_Enable_dispatch() since there is no
84   * valid thread dispatch necessary indicator in this context.
85   */
86  _Thread_Do_dispatch( cpu_self, level );
87
88  /*
89   *  RTEMS supports multiple APIs and each API can define a different
90   *  thread/task prototype. The following code supports invoking the
91   *  user thread entry point using the prototype expected.
92   */
93  ( *executing->Start.Entry.adaptor )( executing );
94
95  /*
96   *  In the call above, the return code from the user thread body which return
97   *  something was placed in return_argument.  This assumed that if it
98   *  returned anything (which is not supporting in all APIs), then it would be
99   *  able to fit in a (void *).
100   */
101
102  _User_extensions_Thread_exitted( executing );
103
104  _Terminate(
105    INTERNAL_ERROR_CORE,
106    true,
107    INTERNAL_ERROR_THREAD_EXITTED
108  );
109}
Note: See TracBrowser for help on using the repository browser.