source:
rtems/cpukit/score/src/threaddispatch.c
@
a6eef8b
Last change on this file since a6eef8b was a6eef8b, checked in by Joel Sherrill <joel.sherrill@…>, on 09/04/03 at 18:52:48 | |
---|---|
|
|
File size: 3.9 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.rtems.com/license/LICENSE. |
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 ) |
50 | void _Thread_Enable_dispatch( void ) |
51 | { |
52 | if ( --_Thread_Dispatch_disable_level ) |
53 | return; |
54 | _Thread_Dispatch(); |
55 | } |
56 | #endif |
57 | |
58 | void _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 | /* |
78 | * Switch libc's task specific data. |
79 | */ |
80 | if ( _Thread_libc_reent ) { |
81 | executing->libc_reent = *_Thread_libc_reent; |
82 | *_Thread_libc_reent = heir->libc_reent; |
83 | } |
84 | |
85 | _User_extensions_Thread_switch( executing, heir ); |
86 | |
87 | if ( heir->budget_algorithm == THREAD_CPU_BUDGET_ALGORITHM_RESET_TIMESLICE ) |
88 | heir->cpu_time_budget = _Thread_Ticks_per_timeslice; |
89 | |
90 | /* |
91 | * If the CPU has hardware floating point, then we must address saving |
92 | * and restoring it as part of the context switch. |
93 | * |
94 | * The second conditional compilation section selects the algorithm used |
95 | * to context switch between floating point tasks. The deferred algorithm |
96 | * can be significantly better in a system with few floating point tasks |
97 | * because it reduces the total number of save and restore FP context |
98 | * operations. However, this algorithm can not be used on all CPUs due |
99 | * to unpredictable use of FP registers by some compilers for integer |
100 | * operations. |
101 | */ |
102 | |
103 | #if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE ) |
104 | #if ( CPU_USE_DEFERRED_FP_SWITCH != TRUE ) |
105 | if ( executing->fp_context != NULL ) |
106 | _Context_Save_fp( &executing->fp_context ); |
107 | #endif |
108 | #endif |
109 | |
110 | _Context_Switch( &executing->Registers, &heir->Registers ); |
111 | |
112 | #if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE ) |
113 | #if ( CPU_USE_DEFERRED_FP_SWITCH == TRUE ) |
114 | if ( (executing->fp_context != NULL) && !_Thread_Is_allocated_fp( executing ) ) { |
115 | if ( _Thread_Allocated_fp != NULL ) |
116 | _Context_Save_fp( &_Thread_Allocated_fp->fp_context ); |
117 | _Context_Restore_fp( &executing->fp_context ); |
118 | _Thread_Allocated_fp = executing; |
119 | } |
120 | #else |
121 | if ( executing->fp_context != NULL ) |
122 | _Context_Restore_fp( &executing->fp_context ); |
123 | #endif |
124 | #endif |
125 | |
126 | executing = _Thread_Executing; |
127 | |
128 | _ISR_Disable( level ); |
129 | } |
130 | |
131 | _Thread_Dispatch_disable_level = 0; |
132 | |
133 | _ISR_Enable( level ); |
134 | |
135 | if ( _Thread_Do_post_task_switch_extension || |
136 | executing->do_post_task_switch_extension ) { |
137 | executing->do_post_task_switch_extension = FALSE; |
138 | _API_extensions_Run_postswitch(); |
139 | } |
140 | |
141 | } |
Note: See TracBrowser
for help on using the repository browser.