|
|
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) 1991,1990,1989,1988 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: #import <mach/features.h>
58:
59: #include <mach/boolean.h>
60: #include <mach/machine.h>
61: #include <mach/time_value.h>
62: #include <mach/vm_param.h>
63: #include <mach/vm_prot.h>
64: #include <kern/counters.h>
65: #include <kern/cpu_number.h>
66: #include <kern/clock.h>
67: #include <kern/host.h>
68: #include <kern/lock.h>
69: #include <kern/mach_param.h>
70: #include <kern/processor.h>
71: #include <kern/sched.h>
72: #include <kern/sched_prim.h>
73: #include <kern/thread.h>
74: #include <kern/time_out.h>
75: #include <kern/time_stamp.h>
76: #include <vm/vm_kern.h>
77: #include <machine/mach_param.h> /* HZ */
78: #include <machine/machspl.h>
79:
80:
81:
82: extern void thread_quantum_update();
83:
84: int hz = HZ; /* number of ticks per second */
85: int tick = (1000000 / HZ); /* number of usec per tick */
86:
87: tvalspec_t tick_stamp; /* timestamp of the last 'tick' */
88:
89: /*
90: * Handle clock interrupts.
91: *
92: * The clock interrupt is assumed to be called at a (more or less)
93: * constant rate. The rate must be identical on all CPUS (XXX - fix).
94: *
95: * Usec is the number of microseconds that have elapsed since the
96: * last clock tick. It may be constant or computed, depending on
97: * the accuracy of the hardware clock.
98: *
99: */
100: void clock_interrupt(usec, usermode, basepri)
101: register int usec; /* microseconds per tick */
102: boolean_t usermode; /* executing user code */
103: boolean_t basepri; /* at base priority */
104: {
105: register int my_cpu = cpu_number();
106: register thread_t thread = current_thread();
107:
108: counter(c_clock_ticks++);
109: counter(c_threads_total += c_threads_current);
110: counter(c_stacks_total += c_stacks_current);
111:
112: #if STAT_TIME
113: /*
114: * Increment the thread time, if using
115: * statistical timing.
116: */
117: if (usermode) {
118: timer_bump(&thread->user_timer, usec);
119: }
120: else {
121: timer_bump(&thread->system_timer, usec);
122: }
123: #endif STAT_TIME
124:
125: /*
126: * Increment the CPU time statistics.
127: */
128: {
129: register int state;
130:
131: if (usermode)
132: state = CPU_STATE_USER;
133: else if (!cpu_idle(my_cpu))
134: state = CPU_STATE_SYSTEM;
135: else
136: state = CPU_STATE_IDLE;
137:
138: machine_slot[my_cpu].cpu_ticks[state]++;
139:
140: /*
141: * Adjust the thread's priority and check for
142: * quantum expiration.
143: */
144:
145: if (!(thread->state & TH_IDLE))
146: thread_quantum_update(my_cpu, thread, 1, state);
147: }
148:
149: if (my_cpu == master_cpu) {
150:
151: /*
152: * Perform scheduler housekeeping activities.
153: */
154: recompute_priorities();
155:
156: /*
157: * Save a timestamp for this clock tick. This
158: * is used by set_timeout(), et al. to apply
159: * appropriate rounding to timeout intervals.
160: * This is really a hack which assumes that
161: * 'timer interrupts' have the same period and
162: * phase as a clock tick.
163: */
164: tick_stamp = clock_get_counter(System);
165:
166: #if TS_FORMAT == 1
167: /*
168: * Increment the tick count for the timestamping routine.
169: */
170: ts_tick_count++;
171: #endif TS_FORMAT == 1
172:
173: }
174: }
175:
176: #if SIMPLE_CLOCK
177:
178: int
179: sched_usec_elapsed(void)
180: {
181: static tvalspec_t sched_stamp;
182: tvalspec_t delta_stamp,
183: new_stamp = clock_get_counter(System);
184: int new_usec;
185:
186: delta_stamp = new_stamp;
187: SUB_TVALSPEC(&delta_stamp, &sched_stamp);
188: new_usec = (delta_stamp.tv_sec * USEC_PER_SEC) +
189: (delta_stamp.tv_nsec / NSEC_PER_USEC);
190: sched_stamp = new_stamp;
191:
192: return (new_usec);
193: }
194: #endif /* SIMPLE_CLOCK */
195:
196: tvalspec_t
197: ticks_to_tvalspec(
198: unsigned int ticks)
199: {
200: tvalspec_t result;
201:
202: result.tv_sec = ticks / TICKS_PER_SEC;
203: result.tv_nsec = (ticks % TICKS_PER_SEC) * NSEC_PER_TICK;
204:
205: return (result);
206: }
207:
208: decl_simple_lock_data(static, timer_lock) /* lock for ... */
209:
210: static void
211: service_timer(
212: timer_elt_t telt)
213: {
214: spl_t s;
215: int (*fcn)();
216: char *param;
217:
218: s = splsched();
219: simple_lock(&timer_lock);
220:
221: fcn = telt->fcn;
222: param = telt->param;
223:
224: telt->set = TELT_UNSET;
225:
226: simple_unlock(&timer_lock);
227: splx(s);
228:
229: (*fcn)(param);
230: }
231:
232: static __inline__ void
233: init_timeout_element(
234: timer_elt_t telt)
235: {
236: telt->call.func = (thread_call_func_t)service_timer;
237: telt->call.spec_proto = telt;
238: telt->call.status = IDLE;
239: }
240:
241: /*
242: * Set timeout.
243: *
244: * Parameters:
245: * telt timer element. Function and param are already set.
246: * interval time-out interval, in hz.
247: */
248: void set_timeout(telt, interval)
249: register timer_elt_t telt; /* already loaded */
250: register unsigned int interval;
251: {
252: spl_t s;
253: tvalspec_t deadline;
254:
255: s = splsched();
256: simple_lock(&timer_lock);
257:
258: if (telt->call.spec_proto != telt)
259: init_timeout_element(telt);
260:
261: deadline = ticks_to_tvalspec(interval);
262: ADD_TVALSPEC(&deadline, &tick_stamp);
263:
264: thread_call_enter_delayed(&telt->call, deadline);
265:
266: telt->set = TELT_SET;
267:
268: simple_unlock(&timer_lock);
269: splx(s);
270: }
271:
272: boolean_t reset_timeout(telt)
273: register timer_elt_t telt;
274: {
275: spl_t s;
276:
277: s = splsched();
278: simple_lock(&timer_lock);
279:
280: if (telt->set) {
281: thread_call_cancel(&telt->call);
282:
283: telt->set = TELT_UNSET;
284:
285: simple_unlock(&timer_lock);
286: splx(s);
287: return TRUE;
288: }
289: else {
290: simple_unlock(&timer_lock);
291: splx(s);
292: return FALSE;
293: }
294: }
295:
296: void init_timeout()
297: {
298: simple_lock_init(&timer_lock);
299: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.