source: rtems/cpukit/score/src/threaddispatch.c @ 19131e97

4.104.114.84.95
Last change on this file since 19131e97 was 48f89683, checked in by Joel Sherrill <joel.sherrill@…>, on 05/14/02 at 17:45:36

2001-05-14 Till Straumann <strauman@…>

  • src/threaddispatch.c, src/threadhandler.c: Per PR211 fix saving/restoring floating point context. The fpsave and fprestore routines are only used in a executing context which _is_ fp and hence has the FPU enabled. The current behavior required the FPU always to be on which is very dangerous if lazy context switching is used. [Joel Note: Some ports explicitly enabled the FPU in the FP save and restore routines to avoid this.]

The patch also makes sure (on powerpc only) that the FPU is disabled
for integer tasks. Note that this is crucial if deferred fp context
switching is used. Otherwise, fp context corruption may go undetected!
Also note that even tasks which merely push/pop FP registers to/from
the stack without modifying them still MUST be FP tasks - otherwise
(if lazy FP context switching is used), FP register corruption (of
other, FP, tasks may occur)!

Furthermore, (on PPC) by default, lazy FP context save/restore
is _disabled_.

  • Property mode set to 100644
File size: 3.7 KB
Line 
1/*
2 *  Thread Handler
3 *
4 *
5 *  COPYRIGHT (c) 1989-1999.
6 *  On-Line Applications Research Corporation (OAR).
7 *
8 *  The license and distribution terms for this file may be
9 *  found in found in the file LICENSE in this distribution or at
10 *  http://www.OARcorp.com/rtems/license.html.
11 *
12 *  $Id$
13 */
14
15#include <rtems/system.h>
16#include <rtems/score/apiext.h>
17#include <rtems/score/context.h>
18#include <rtems/score/interr.h>
19#include <rtems/score/isr.h>
20#include <rtems/score/object.h>
21#include <rtems/score/priority.h>
22#include <rtems/score/states.h>
23#include <rtems/score/sysstate.h>
24#include <rtems/score/thread.h>
25#include <rtems/score/threadq.h>
26#include <rtems/score/userext.h>
27#include <rtems/score/wkspace.h>
28
29/*PAGE
30 *
31 *  _Thread_Dispatch
32 *
33 *  This kernel routine determines if a dispatch is needed, and if so
34 *  dispatches to the heir thread.  Once the heir is running an attempt
35 *  is made to dispatch any ASRs.
36 *
37 *  ALTERNATE ENTRY POINTS:
38 *    void _Thread_Enable_dispatch();
39 *
40 *  Input parameters:  NONE
41 *
42 *  Output parameters:  NONE
43 *
44 *  INTERRUPT LATENCY:
45 *    dispatch thread
46 *    no dispatch thread
47 */
48
49#if ( CPU_INLINE_ENABLE_DISPATCH == FALSE )
50void _Thread_Enable_dispatch( void )
51{
52  if ( --_Thread_Dispatch_disable_level )
53    return;
54  _Thread_Dispatch();
55}
56#endif
57
58void _Thread_Dispatch( void )
59{
60  Thread_Control   *executing;
61  Thread_Control   *heir;
62  ISR_Level         level;
63
64  executing   = _Thread_Executing;
65  _ISR_Disable( level );
66  while ( _Context_Switch_necessary == TRUE ) {
67    heir = _Thread_Heir;
68    _Thread_Dispatch_disable_level = 1;
69    _Context_Switch_necessary = FALSE;
70    _Thread_Executing = heir;
71    executing->rtems_ada_self = rtems_ada_self;
72    rtems_ada_self = heir->rtems_ada_self;
73    _ISR_Enable( level );
74
75    heir->ticks_executed++;
76
77    _User_extensions_Thread_switch( executing, heir );
78
79    if ( heir->budget_algorithm == THREAD_CPU_BUDGET_ALGORITHM_RESET_TIMESLICE )
80      heir->cpu_time_budget = _Thread_Ticks_per_timeslice;
81
82    /*
83     *  If the CPU has hardware floating point, then we must address saving
84     *  and restoring it as part of the context switch.
85     *
86     *  The second conditional compilation section selects the algorithm used
87     *  to context switch between floating point tasks.  The deferred algorithm
88     *  can be significantly better in a system with few floating point tasks
89     *  because it reduces the total number of save and restore FP context
90     *  operations.  However, this algorithm can not be used on all CPUs due
91     *  to unpredictable use of FP registers by some compilers for integer
92     *  operations.
93     */
94
95#if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
96#if ( CPU_USE_DEFERRED_FP_SWITCH != TRUE )
97    if ( executing->fp_context != NULL )
98      _Context_Save_fp( &executing->fp_context );
99#endif
100#endif
101
102    _Context_Switch( &executing->Registers, &heir->Registers );
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) && !_Thread_Is_allocated_fp( executing ) ) {
107      if ( _Thread_Allocated_fp != NULL )
108        _Context_Save_fp( &_Thread_Allocated_fp->fp_context );
109      _Context_Restore_fp( &executing->fp_context );
110      _Thread_Allocated_fp = executing;
111    }
112#else
113    if ( executing->fp_context != NULL )
114      _Context_Restore_fp( &executing->fp_context );
115#endif
116#endif
117
118    executing = _Thread_Executing;
119
120    _ISR_Disable( level );
121  }
122
123  _Thread_Dispatch_disable_level = 0;
124
125  _ISR_Enable( level );
126
127  if ( _Thread_Do_post_task_switch_extension ||
128       executing->do_post_task_switch_extension ) {
129    executing->do_post_task_switch_extension = FALSE;
130    _API_extensions_Run_postswitch();
131  }
132 
133}
Note: See TracBrowser for help on using the repository browser.