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

4.11
Last change on this file since d4dc7c8 was d4dc7c8, checked in by Jennifer Averett <Jennifer.Averett@…>, on May 26, 2011 at 6:07:07 PM

2011-05-26 Jennifer Averett <Jennifer.Averett@…>

PR 1796/cpukit

  • sapi/src/exshutdown.c, score/include/rtems/score/percpu.h, score/include/rtems/score/smp.h, score/src/smp.c, score/src/threaddispatch.c, score/src/threadhandler.c: Added SMP interprocess communications.
  • Property mode set to 100644
File size: 4.7 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#if defined(RTEMS_SMP)
37  #include <rtems/score/smp.h>
38#endif
39
40/**
41 *  _Thread_Dispatch
42 *
43 *  This kernel routine determines if a dispatch is needed, and if so
44 *  dispatches to the heir thread.  Once the heir is running an attempt
45 *  is made to dispatch any ASRs.
46 *
47 *  ALTERNATE ENTRY POINTS:
48 *    void _Thread_Enable_dispatch();
49 *
50 *  INTERRUPT LATENCY:
51 *    dispatch thread
52 *    no dispatch thread
53 */
54void _Thread_Dispatch( void )
55{
56  Thread_Control   *executing;
57  Thread_Control   *heir;
58  ISR_Level         level;
59
60  _Thread_Disable_dispatch();
61  #if defined(RTEMS_SMP)
62    /*
63     *  If necessary, send dispatch request to other cores.
64     */
65    _SMP_Request_other_cores_to_dispatch();
66  #endif
67
68  /*
69   *  Now determine if we need to perform a dispatch on the current CPU.
70   */
71  executing   = _Thread_Executing;
72  _ISR_Disable( level );
73  while ( _Thread_Dispatch_necessary == true ) {
74
75    heir = _Thread_Heir;
76    _Thread_Dispatch_necessary = false;
77    _Thread_Executing = heir;
78
79    /*
80     *  When the heir and executing are the same, then we are being
81     *  requested to do the post switch dispatching.  This is normally
82     *  done to dispatch signals.
83     */
84    if ( heir == executing )
85      goto post_switch;
86
87    /*
88     *  Since heir and executing are not the same, we need to do a real
89     *  context switch.
90     */
91#if __RTEMS_ADA__
92    executing->rtems_ada_self = rtems_ada_self;
93    rtems_ada_self = heir->rtems_ada_self;
94#endif
95    if ( heir->budget_algorithm == THREAD_CPU_BUDGET_ALGORITHM_RESET_TIMESLICE )
96      heir->cpu_time_budget = _Thread_Ticks_per_timeslice;
97
98    _ISR_Enable( level );
99
100    #ifndef __RTEMS_USE_TICKS_FOR_STATISTICS__
101      {
102        Timestamp_Control uptime, ran;
103        _TOD_Get_uptime( &uptime );
104        _Timestamp_Subtract(
105          &_Thread_Time_of_last_context_switch,
106          &uptime,
107          &ran
108        );
109        _Timestamp_Add_to( &executing->cpu_time_used, &ran );
110        _Thread_Time_of_last_context_switch = uptime;
111      }
112    #else
113      {
114        TOD_Get_uptime( &_Thread_Time_of_last_context_switch );
115        heir->cpu_time_used++;
116      }
117    #endif
118
119    /*
120     * Switch libc's task specific data.
121     */
122    if ( _Thread_libc_reent ) {
123      executing->libc_reent = *_Thread_libc_reent;
124      *_Thread_libc_reent = heir->libc_reent;
125    }
126
127    _User_extensions_Thread_switch( executing, heir );
128
129    /*
130     *  If the CPU has hardware floating point, then we must address saving
131     *  and restoring it as part of the context switch.
132     *
133     *  The second conditional compilation section selects the algorithm used
134     *  to context switch between floating point tasks.  The deferred algorithm
135     *  can be significantly better in a system with few floating point tasks
136     *  because it reduces the total number of save and restore FP context
137     *  operations.  However, this algorithm can not be used on all CPUs due
138     *  to unpredictable use of FP registers by some compilers for integer
139     *  operations.
140     */
141
142#if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
143#if ( CPU_USE_DEFERRED_FP_SWITCH != TRUE )
144    if ( executing->fp_context != NULL )
145      _Context_Save_fp( &executing->fp_context );
146#endif
147#endif
148
149    _Context_Switch( &executing->Registers, &heir->Registers );
150
151#if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
152#if ( CPU_USE_DEFERRED_FP_SWITCH == TRUE )
153    if ( (executing->fp_context != NULL) &&
154         !_Thread_Is_allocated_fp( executing ) ) {
155      if ( _Thread_Allocated_fp != NULL )
156        _Context_Save_fp( &_Thread_Allocated_fp->fp_context );
157      _Context_Restore_fp( &executing->fp_context );
158      _Thread_Allocated_fp = executing;
159    }
160#else
161    if ( executing->fp_context != NULL )
162      _Context_Restore_fp( &executing->fp_context );
163#endif
164#endif
165
166    executing = _Thread_Executing;
167
168    _ISR_Disable( level );
169  }
170
171post_switch:
172  _Thread_Dispatch_set_disable_level( 0 );
173
174  _ISR_Enable( level );
175
176  _API_extensions_Run_postswitch();
177}
Note: See TracBrowser for help on using the repository browser.