source: rtems/cpukit/score/src/threaddispatch.c @ d7c3883

4.11
Last change on this file since d7c3883 was d7c3883, checked in by Jennifer Averett <Jennifer.Averett@…>, on Apr 21, 2011 at 7:05:15 PM

2011-04-21 Jennifer Averett <Jennifer.Averett@…

PR 1777/cpukit

  • libcsupport/src/malloc_deferred.c, libcsupport/src/realloc.c, score/Makefile.am, score/cpu/lm32/irq.c, score/cpu/nios2/irq.c, score/include/rtems/score/coremutex.h, score/include/rtems/score/thread.h, score/inline/rtems/score/thread.inl, score/src/heapfree.c, score/src/pheapwalk.c, score/src/smp.c, score/src/threaddispatch.c: Consolidated access to _Thread_Dispatch_disable_level.
  • score/src/threaddisabledispatch.c, score/src/threadenabledispatch.c: New files.
  • Property mode set to 100644
File size: 4.4 KB
Line 
1/*
2 *  Thread Handler
3 *
4 *  COPYRIGHT (c) 1989-2009.
5 *  On-Line Applications Research Corporation (OAR).
6 *
7 *  The license and distribution terms for this file may be
8 *  found in the file LICENSE in this distribution or at
9 *  http://www.rtems.com/license/LICENSE.
10 *
11 *  $Id$
12 */
13
14#if HAVE_CONFIG_H
15#include "config.h"
16#endif
17
18#include <rtems/system.h>
19#include <rtems/score/apiext.h>
20#include <rtems/score/context.h>
21#include <rtems/score/interr.h>
22#include <rtems/score/isr.h>
23#include <rtems/score/object.h>
24#include <rtems/score/priority.h>
25#include <rtems/score/states.h>
26#include <rtems/score/sysstate.h>
27#include <rtems/score/thread.h>
28#include <rtems/score/threadq.h>
29#include <rtems/score/userext.h>
30#include <rtems/score/wkspace.h>
31
32#ifndef __RTEMS_USE_TICKS_FOR_STATISTICS__
33  #include <rtems/score/timestamp.h>
34#endif
35
36/**
37 *  _Thread_Dispatch
38 *
39 *  This kernel routine determines if a dispatch is needed, and if so
40 *  dispatches to the heir thread.  Once the heir is running an attempt
41 *  is made to dispatch any ASRs.
42 *
43 *  ALTERNATE ENTRY POINTS:
44 *    void _Thread_Enable_dispatch();
45 *
46 *  INTERRUPT LATENCY:
47 *    dispatch thread
48 *    no dispatch thread
49 */
50
51void _Thread_Dispatch( void )
52{
53  Thread_Control   *executing;
54  Thread_Control   *heir;
55  ISR_Level         level;
56
57  executing   = _Thread_Executing;
58  _ISR_Disable( level );
59  while ( _Thread_Dispatch_necessary == true ) {
60    heir = _Thread_Heir;
61   _Thread_Dispatch_set_disable_level( 1 );
62    _Thread_Dispatch_necessary = false;
63    _Thread_Executing = heir;
64
65    /*
66     *  When the heir and executing are the same, then we are being
67     *  requested to do the post switch dispatching.  This is normally
68     *  done to dispatch signals.
69     */
70    if ( heir == executing )
71      goto post_switch;
72
73    /*
74     *  Since heir and executing are not the same, we need to do a real
75     *  context switch.
76     */
77#if __RTEMS_ADA__
78    executing->rtems_ada_self = rtems_ada_self;
79    rtems_ada_self = heir->rtems_ada_self;
80#endif
81    if ( heir->budget_algorithm == THREAD_CPU_BUDGET_ALGORITHM_RESET_TIMESLICE )
82      heir->cpu_time_budget = _Thread_Ticks_per_timeslice;
83
84    _ISR_Enable( level );
85
86    #ifndef __RTEMS_USE_TICKS_FOR_STATISTICS__
87      {
88        Timestamp_Control uptime, ran;
89        _TOD_Get_uptime( &uptime );
90        _Timestamp_Subtract(
91          &_Thread_Time_of_last_context_switch,
92          &uptime,
93          &ran
94        );
95        _Timestamp_Add_to( &executing->cpu_time_used, &ran );
96        _Thread_Time_of_last_context_switch = uptime;
97      }
98    #else
99      heir->cpu_time_used++;
100    #endif
101
102    /*
103     * Switch libc's task specific data.
104     */
105    if ( _Thread_libc_reent ) {
106      executing->libc_reent = *_Thread_libc_reent;
107      *_Thread_libc_reent = heir->libc_reent;
108    }
109
110    _User_extensions_Thread_switch( executing, heir );
111
112    /*
113     *  If the CPU has hardware floating point, then we must address saving
114     *  and restoring it as part of the context switch.
115     *
116     *  The second conditional compilation section selects the algorithm used
117     *  to context switch between floating point tasks.  The deferred algorithm
118     *  can be significantly better in a system with few floating point tasks
119     *  because it reduces the total number of save and restore FP context
120     *  operations.  However, this algorithm can not be used on all CPUs due
121     *  to unpredictable use of FP registers by some compilers for integer
122     *  operations.
123     */
124
125#if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
126#if ( CPU_USE_DEFERRED_FP_SWITCH != TRUE )
127    if ( executing->fp_context != NULL )
128      _Context_Save_fp( &executing->fp_context );
129#endif
130#endif
131
132    _Context_Switch( &executing->Registers, &heir->Registers );
133
134#if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
135#if ( CPU_USE_DEFERRED_FP_SWITCH == TRUE )
136    if ( (executing->fp_context != NULL) &&
137         !_Thread_Is_allocated_fp( executing ) ) {
138      if ( _Thread_Allocated_fp != NULL )
139        _Context_Save_fp( &_Thread_Allocated_fp->fp_context );
140      _Context_Restore_fp( &executing->fp_context );
141      _Thread_Allocated_fp = executing;
142    }
143#else
144    if ( executing->fp_context != NULL )
145      _Context_Restore_fp( &executing->fp_context );
146#endif
147#endif
148
149    executing = _Thread_Executing;
150
151    _ISR_Disable( level );
152  }
153
154post_switch:
155  _Thread_Dispatch_set_disable_level( 0 );
156
157  _ISR_Enable( level );
158
159  _API_extensions_Run_postswitch();
160}
Note: See TracBrowser for help on using the repository browser.