FreeBSD/Linux Kernel Cross Reference
sys/kern/priority.c
1 /*
2 * Mach Operating System
3 * Copyright (c) 1993,1991,1990,1989,1988,1987 Carnegie Mellon University
4 * All Rights Reserved.
5 *
6 * Permission to use, copy, modify and distribute this software and its
7 * documentation is hereby granted, provided that both the copyright
8 * notice and this permission notice appear in all copies of the
9 * software, derivative works or modified versions, and any portions
10 * thereof, and that both notices appear in supporting documentation.
11 *
12 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
13 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
14 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
15 *
16 * Carnegie Mellon requests users of this software to return to
17 *
18 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
19 * School of Computer Science
20 * Carnegie Mellon University
21 * Pittsburgh PA 15213-3890
22 *
23 * any improvements or extensions that they make and grant Carnegie Mellon
24 * the rights to redistribute these changes.
25 */
26 /*
27 * HISTORY
28 * $Log: priority.c,v $
29 * Revision 2.8 93/05/15 18:56:43 mrt
30 * machparam.h -> machspl.h
31 *
32 * Revision 2.7 93/01/14 17:35:42 danner
33 * Added check to thread_quantum_update for processor not in a
34 * processor set (when being reassigned). This should be fixed in
35 * processor assignment code instead.
36 * [92/10/23 dbg]
37 * Removed unnecessary include of machine/mach_param.h
38 * [92/12/16 af]
39 * Proper spl typing.
40 * [92/12/01 af]
41 *
42 * Added check thread_quantum_update for processor not in a
43 * processor set (when being reassigned). This should be fixed in
44 * processor assignment code instead.
45 * [92/10/23 dbg]
46 * Proper spl typing.
47 * [92/12/01 af]
48 *
49 * Added check thread_quantum_update for processor not in a
50 * processor set (when being reassigned). This should be fixed in
51 * processor assignment code instead.
52 * [92/10/23 dbg]
53 *
54 * Revision 2.6 92/08/03 17:38:38 jfriedl
55 * removed silly prototypes
56 * [92/08/02 jfriedl]
57 *
58 * Revision 2.5 92/05/21 17:15:03 jfriedl
59 * tried prototypes.
60 * [92/05/20 jfriedl]
61 *
62 * Revision 2.4 91/05/14 16:45:17 mrt
63 * Correcting copyright
64 *
65 * Revision 2.3 91/02/05 17:28:22 mrt
66 * Changed to new Mach copyright
67 * [91/02/01 16:15:50 mrt]
68 *
69 * Revision 2.2 90/06/02 14:55:24 rpd
70 * Updated to new scheduling technology.
71 * [90/03/26 22:13:58 rpd]
72 *
73 * Revision 2.1 89/08/03 15:45:28 rwd
74 * Created.
75 *
76 * 24-Mar-89 David Golub (dbg) at Carnegie-Mellon University
77 * Added thread_set_priority.
78 *
79 * 14-Jan-89 David Golub (dbg) at Carnegie-Mellon University
80 * Split into two new files: mach_clock (for timing) and priority
81 * (for priority calculation).
82 *
83 * 9-Aug-88 David Black (dlb) at Carnegie-Mellon University
84 * thread->first_quantum replaces runrun.
85 *
86 * 4-May-88 David Black (dlb) at Carnegie-Mellon University
87 * MACH_TIME_NEW is now standard.
88 * Do ageing here on clock interrupts instead of in
89 * recompute_priorities. Do accurate usage calculations.
90 *
91 * 18-Nov-87 Avadis Tevanian (avie) at Carnegie-Mellon University
92 * Delete previous history.
93 */
94 /*
95 * File: clock_prim.c
96 * Author: Avadis Tevanian, Jr.
97 * Date: 1986
98 *
99 * Clock primitives.
100 */
101
102 #include <cpus.h>
103
104 #include <mach/boolean.h>
105 #include <mach/kern_return.h>
106 #include <mach/machine.h>
107 #include <kern/host.h>
108 #include <kern/mach_param.h>
109 #include <kern/sched.h>
110 #include <kern/thread.h>
111 #include <kern/time_out.h>
112 #include <kern/time_stamp.h>
113 #include <machine/machspl.h>
114
115
116
117 /*
118 * USAGE_THRESHOLD is the amount by which usage must change to
119 * cause a priority shift that moves a thread between run queues.
120 */
121
122 #ifdef PRI_SHIFT_2
123 #if PRI_SHIFT_2 > 0
124 #define USAGE_THRESHOLD (((1 << PRI_SHIFT) + (1 << PRI_SHIFT_2)) << (2 + SCHED_SHIFT))
125 #else /* PRI_SHIFT_2 > 0 */
126 #define USAGE_THRESHOLD (((1 << PRI_SHIFT) - (1 << -(PRI_SHIFT_2))) << (2 + SCHED_SHIFT))
127 #endif /* PRI_SHIFT_2 > 0 */
128 #else /* PRI_SHIFT_2 */
129 #define USAGE_THRESHOLD (1 << (PRI_SHIFT + 2 + SCHED_SHIFT))
130 #endif /* PRI_SHIFT_2 */
131
132 /*
133 * thread_quantum_update:
134 *
135 * Recalculate the quantum and priority for a thread.
136 * The number of ticks that has elapsed since we were last called
137 * is passed as "nticks."
138 */
139
140 void thread_quantum_update(mycpu, thread, nticks, state)
141 register int mycpu;
142 register thread_t thread;
143 int nticks;
144 int state;
145 {
146 register int quantum;
147 register processor_t myprocessor;
148 #if NCPUS > 1
149 register processor_set_t pset;
150 #endif
151 spl_t s;
152
153 myprocessor = cpu_to_processor(mycpu);
154 #if NCPUS > 1
155 pset = myprocessor->processor_set;
156 if (pset == 0) {
157 /*
158 * Processor is being reassigned.
159 * Should rewrite processor assignment code to
160 * block clock interrupts.
161 */
162 return;
163 }
164 #endif /* NCPUS > 1 */
165
166 /*
167 * Account for thread's utilization of these ticks.
168 * This assumes that there is *always* a current thread.
169 * When the processor is idle, it should be the idle thread.
170 */
171
172 /*
173 * Update set_quantum and calculate the current quantum.
174 */
175 #if NCPUS > 1
176 pset->set_quantum = pset->machine_quantum[
177 ((pset->runq.count > pset->processor_count) ?
178 pset->processor_count : pset->runq.count)];
179
180 if (myprocessor->runq.count != 0)
181 quantum = min_quantum;
182 else
183 quantum = pset->set_quantum;
184 #else /* NCPUS > 1 */
185 quantum = min_quantum;
186 default_pset.set_quantum = quantum;
187 #endif /* NCPUS > 1 */
188
189 /*
190 * Now recompute the priority of the thread if appropriate.
191 */
192
193 if (state != CPU_STATE_IDLE) {
194 myprocessor->quantum -= nticks;
195 #if NCPUS > 1
196 /*
197 * Runtime quantum adjustment. Use quantum_adj_index
198 * to avoid synchronizing quantum expirations.
199 */
200 if ((quantum != myprocessor->last_quantum) &&
201 (pset->processor_count > 1)) {
202 myprocessor->last_quantum = quantum;
203 simple_lock(&pset->quantum_adj_lock);
204 quantum = min_quantum + (pset->quantum_adj_index *
205 (quantum - min_quantum)) /
206 (pset->processor_count - 1);
207 if (++(pset->quantum_adj_index) >=
208 pset->processor_count)
209 pset->quantum_adj_index = 0;
210 simple_unlock(&pset->quantum_adj_lock);
211 }
212 #endif /* NCPUS > 1 */
213 if (myprocessor->quantum <= 0) {
214 s = splsched();
215 thread_lock(thread);
216 if (thread->sched_stamp != sched_tick) {
217 update_priority(thread);
218 }
219 else {
220 if (
221 #if MACH_FIXPRI
222 (thread->policy == POLICY_TIMESHARE) &&
223 #endif /* MACH_FIXPRI */
224 (thread->depress_priority < 0)) {
225 thread_timer_delta(thread);
226 thread->sched_usage +=
227 thread->sched_delta;
228 thread->sched_delta = 0;
229 compute_my_priority(thread);
230 }
231 }
232 thread_unlock(thread);
233 (void) splx(s);
234 /*
235 * This quantum is up, give this thread another.
236 */
237 myprocessor->first_quantum = FALSE;
238 #if MACH_FIXPRI
239 if (thread->policy == POLICY_TIMESHARE) {
240 #endif /* MACH_FIXPRI */
241 myprocessor->quantum += quantum;
242 #if MACH_FIXPRI
243 }
244 else {
245 /*
246 * Fixed priority has per-thread quantum.
247 *
248 */
249 myprocessor->quantum += thread->sched_data;
250 }
251 #endif /* MACH_FIXPRI */
252 }
253 /*
254 * Recompute priority if appropriate.
255 */
256 else {
257 s = splsched();
258 thread_lock(thread);
259 if (thread->sched_stamp != sched_tick) {
260 update_priority(thread);
261 }
262 else {
263 if (
264 #if MACH_FIXPRI
265 (thread->policy == POLICY_TIMESHARE) &&
266 #endif /* MACH_FIXPRI */
267 (thread->depress_priority < 0)) {
268 thread_timer_delta(thread);
269 if (thread->sched_delta >= USAGE_THRESHOLD) {
270 thread->sched_usage +=
271 thread->sched_delta;
272 thread->sched_delta = 0;
273 compute_my_priority(thread);
274 }
275 }
276 }
277 thread_unlock(thread);
278 (void) splx(s);
279 }
280 /*
281 * Check for and schedule ast if needed.
282 */
283 ast_check();
284 }
285 }
286
Cache object: 1418e6a41557bb2a2f499982cad7cf32
|