|
|
1.1 root 1: /*
2: * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3: *
4: * @APPLE_LICENSE_HEADER_START@
5: *
6: * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7: * Reserved. This file contains Original Code and/or Modifications of
8: * Original Code as defined in and that are subject to the Apple Public
9: * Source License Version 1.1 (the "License"). You may not use this file
10: * except in compliance with the License. Please obtain a copy of the
11: * License at http://www.apple.com/publicsource and read it before using
12: * this file.
13: *
14: * The Original Code and all software distributed under the License are
15: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
19: * License for the specific language governing rights and limitations
20: * under the License.
21: *
22: * @APPLE_LICENSE_HEADER_END@
23: */
24:
25: /*
26: * Mach Operating System
27: * Copyright (c) 1993,1991,1990,1989,1988,1987 Carnegie Mellon University
28: * All Rights Reserved.
29: *
30: * Permission to use, copy, modify and distribute this software and its
31: * documentation is hereby granted, provided that both the copyright
32: * notice and this permission notice appear in all copies of the
33: * software, derivative works or modified versions, and any portions
34: * thereof, and that both notices appear in supporting documentation.
35: *
36: * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
37: * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
38: * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
39: *
40: * Carnegie Mellon requests users of this software to return to
41: *
42: * Software Distribution Coordinator or [email protected]
43: * School of Computer Science
44: * Carnegie Mellon University
45: * Pittsburgh PA 15213-3890
46: *
47: * any improvements or extensions that they make and grant Carnegie Mellon
48: * the rights to redistribute these changes.
49: */
50: /*
51: * File: clock_prim.c
52: * Author: Avadis Tevanian, Jr.
53: * Date: 1986
54: *
55: * Clock primitives.
56: */
57:
58: #include <cpus.h>
59:
60: #include <mach/boolean.h>
61: #include <mach/kern_return.h>
62: #include <mach/machine.h>
63: #include <kern/host.h>
64: #include <kern/mach_param.h>
65: #include <kern/sched.h>
66: #include <kern/thread.h>
67: #include <kern/time_out.h>
68: #include <kern/time_stamp.h>
69: #include <machine/machspl.h>
70:
71:
72:
73: /*
74: * USAGE_THRESHOLD is the amount by which usage must change to
75: * cause a priority shift that moves a thread between run queues.
76: */
77:
78: #ifdef PRI_SHIFT_2
79: #if PRI_SHIFT_2 > 0
80: #define USAGE_THRESHOLD (((1 << PRI_SHIFT) + (1 << PRI_SHIFT_2)) << (2 + SCHED_SHIFT))
81: #else /* PRI_SHIFT_2 > 0 */
82: #define USAGE_THRESHOLD (((1 << PRI_SHIFT) - (1 << -(PRI_SHIFT_2))) << (2 + SCHED_SHIFT))
83: #endif /* PRI_SHIFT_2 > 0 */
84: #else /* PRI_SHIFT_2 */
85: #define USAGE_THRESHOLD (1 << (PRI_SHIFT + 2 + SCHED_SHIFT))
86: #endif /* PRI_SHIFT_2 */
87:
88: /*
89: * thread_quantum_update:
90: *
91: * Recalculate the quantum and priority for a thread.
92: * The number of ticks that has elapsed since we were last called
93: * is passed as "nticks."
94: */
95:
96: void thread_quantum_update(mycpu, thread, nticks, state)
97: register int mycpu;
98: register thread_t thread;
99: int nticks;
100: int state;
101: {
102: register int quantum;
103: register processor_t myprocessor;
104: #if NCPUS > 1
105: register processor_set_t pset;
106: #endif
107: spl_t s;
108:
109: myprocessor = cpu_to_processor(mycpu);
110: #if NCPUS > 1
111: pset = myprocessor->processor_set;
112: if (pset == 0) {
113: /*
114: * Processor is being reassigned.
115: * Should rewrite processor assignment code to
116: * block clock interrupts.
117: */
118: return;
119: }
120: #endif /* NCPUS > 1 */
121:
122: /*
123: * Account for thread's utilization of these ticks.
124: * This assumes that there is *always* a current thread.
125: * When the processor is idle, it should be the idle thread.
126: */
127:
128: /*
129: * Update set_quantum and calculate the current quantum.
130: */
131: #if NCPUS > 1
132: pset->set_quantum = pset->machine_quantum[
133: ((pset->runq.count > pset->processor_count) ?
134: pset->processor_count : pset->runq.count)];
135:
136: if (myprocessor->runq.count != 0)
137: quantum = min_quantum;
138: else
139: quantum = pset->set_quantum;
140: #else /* NCPUS > 1 */
141: quantum = min_quantum;
142: default_pset.set_quantum = quantum;
143: #endif /* NCPUS > 1 */
144:
145: /*
146: * Now recompute the priority of the thread if appropriate.
147: */
148:
149: if (state != CPU_STATE_IDLE) {
150: myprocessor->quantum -= nticks;
151: #if NCPUS > 1
152: /*
153: * Runtime quantum adjustment. Use quantum_adj_index
154: * to avoid synchronizing quantum expirations.
155: */
156: if ((quantum != myprocessor->last_quantum) &&
157: (pset->processor_count > 1)) {
158: myprocessor->last_quantum = quantum;
159: simple_lock(&pset->quantum_adj_lock);
160: quantum = min_quantum + (pset->quantum_adj_index *
161: (quantum - min_quantum)) /
162: (pset->processor_count - 1);
163: if (++(pset->quantum_adj_index) >=
164: pset->processor_count)
165: pset->quantum_adj_index = 0;
166: simple_unlock(&pset->quantum_adj_lock);
167: }
168: #endif /* NCPUS > 1 */
169: if (myprocessor->quantum <= 0) {
170: s = splsched();
171: thread_lock(thread);
172: if (thread->sched_stamp != sched_tick) {
173: #if NCPUS > 1
174: update_priority(thread);
175: #endif /* NCPUS > 1 */
176: }
177: else {
178: if (
179: #if MACH_FIXPRI
180: (thread->policy != POLICY_FIXEDPRI) &&
181: #endif /* MACH_FIXPRI */
182: (thread->depress_priority < 0)) {
183: thread_timer_delta(thread);
184: thread->sched_usage +=
185: thread->sched_delta;
186: thread->sched_delta = 0;
187: compute_my_priority(thread);
188: }
189: }
190: thread_unlock(thread);
191: (void) splx(s);
192: /*
193: * This quantum is up, give this thread another.
194: */
195: myprocessor->first_quantum = FALSE;
196: #if MACH_FIXPRI
197: if (thread->policy != POLICY_FIXEDPRI) {
198: #endif /* MACH_FIXPRI */
199: myprocessor->quantum += quantum;
200: #if MACH_FIXPRI
201: }
202: else {
203: /*
204: * Fixed priority has per-thread quantum.
205: *
206: */
207: myprocessor->quantum += thread->sched_data;
208: }
209: #endif /* MACH_FIXPRI */
210: }
211: /*
212: * Recompute priority if appropriate.
213: */
214: else {
215: s = splsched();
216: thread_lock(thread);
217: if (thread->sched_stamp != sched_tick) {
218: #if NCPUS > 1
219: update_priority(thread);
220: #endif /* NCPUS > 1 */
221: }
222: else {
223: if (
224: #if MACH_FIXPRI
225: (thread->policy != POLICY_FIXEDPRI) &&
226: #endif /* MACH_FIXPRI */
227: (thread->depress_priority < 0)) {
228: thread_timer_delta(thread);
229: if (thread->sched_delta >= USAGE_THRESHOLD) {
230: thread->sched_usage +=
231: thread->sched_delta;
232: thread->sched_delta = 0;
233: compute_my_priority(thread);
234: }
235: }
236: }
237: thread_unlock(thread);
238: (void) splx(s);
239: }
240: /*
241: * Check for and schedule ast if needed.
242: */
243: ast_check();
244: }
245: }
246:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.