Deleted Added
full compact
kern_tc.c (57182) kern_tc.c (58377)
1/*-
2 * Copyright (c) 1997, 1998 Poul-Henning Kamp <phk@FreeBSD.org>
3 * Copyright (c) 1982, 1986, 1991, 1993
4 * The Regents of the University of California. All rights reserved.
5 * (c) UNIX System Laboratories, Inc.
6 * All or some portions of this file are derived from material licensed
7 * to the University of California by American Telephone and Telegraph
8 * Co. or Unix System Laboratories, Inc. and are reproduced herein with
9 * the permission of UNIX System Laboratories, Inc.
1/*
2 * ----------------------------------------------------------------------------
3 * "THE BEER-WARE LICENSE" (Revision 42):
4 * <phk@FreeBSD.ORG> wrote this file. As long as you retain this notice you
5 * can do whatever you want with this stuff. If we meet some day, and you think
6 * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
7 * ----------------------------------------------------------------------------
10 *
8 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. All advertising materials mentioning features or use of this software
20 * must display the following acknowledgement:
21 * This product includes software developed by the University of
22 * California, Berkeley and its contributors.
23 * 4. Neither the name of the University nor the names of its contributors
24 * may be used to endorse or promote products derived from this software
25 * without specific prior written permission.
26 *
27 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
28 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
31 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37 * SUCH DAMAGE.
38 *
39 * @(#)kern_clock.c 8.5 (Berkeley) 1/21/94
40 * $FreeBSD: head/sys/kern/kern_tc.c 57182 2000-02-13 10:56:32Z phk $
9 * $FreeBSD: head/sys/kern/kern_tc.c 58377 2000-03-20 14:09:06Z phk $
41 */
42
43#include "opt_ntp.h"
44
45#include <sys/param.h>
10 */
11
12#include "opt_ntp.h"
13
14#include <sys/param.h>
46#include <sys/systm.h>
47#include <sys/dkstat.h>
48#include <sys/callout.h>
49#include <sys/kernel.h>
50#include <sys/proc.h>
15#include <sys/timetc.h>
51#include <sys/malloc.h>
16#include <sys/malloc.h>
52#include <sys/resourcevar.h>
53#include <sys/signalvar.h>
17#include <sys/kernel.h>
18#include <sys/sysctl.h>
19#include <sys/systm.h>
54#include <sys/timex.h>
55#include <sys/timepps.h>
20#include <sys/timex.h>
21#include <sys/timepps.h>
56#include <vm/vm.h>
57#include <sys/lock.h>
58#include <vm/pmap.h>
59#include <vm/vm_map.h>
60#include <sys/sysctl.h>
61
22
62#include <machine/cpu.h>
63#include <machine/limits.h>
64
65#ifdef GPROF
66#include <sys/gmon.h>
67#endif
68
69#if defined(SMP) && defined(BETTER_CLOCK)
70#include <machine/smp.h>
71#endif
72
73/*
74 * Number of timecounters used to implement stable storage
75 */
76#ifndef NTIMECOUNTER
77#define NTIMECOUNTER 5
78#endif
79
80static MALLOC_DEFINE(M_TIMECOUNTER, "timecounter",
81 "Timecounter stable storage");
82
23/*
24 * Number of timecounters used to implement stable storage
25 */
26#ifndef NTIMECOUNTER
27#define NTIMECOUNTER 5
28#endif
29
30static MALLOC_DEFINE(M_TIMECOUNTER, "timecounter",
31 "Timecounter stable storage");
32
83static void initclocks __P((void *dummy));
84SYSINIT(clocks, SI_SUB_CLOCKS, SI_ORDER_FIRST, initclocks, NULL)
85
86static void tco_forward __P((int force));
87static void tco_setscales __P((struct timecounter *tc));
88static __inline unsigned tco_delta __P((struct timecounter *tc));
89
33static void tco_setscales __P((struct timecounter *tc));
34static __inline unsigned tco_delta __P((struct timecounter *tc));
35
90/* Some of these don't belong here, but it's easiest to concentrate them. */
91#if defined(SMP) && defined(BETTER_CLOCK)
92long cp_time[CPUSTATES];
93#else
94static long cp_time[CPUSTATES];
95#endif
96
97long tk_cancc;
98long tk_nin;
99long tk_nout;
100long tk_rawcc;
101
102time_t time_second;
103
104struct timeval boottime;
105SYSCTL_STRUCT(_kern, KERN_BOOTTIME, boottime, CTLFLAG_RD,
106 &boottime, timeval, "System boottime");
107
36time_t time_second;
37
38struct timeval boottime;
39SYSCTL_STRUCT(_kern, KERN_BOOTTIME, boottime, CTLFLAG_RD,
40 &boottime, timeval, "System boottime");
41
108/*
109 * Which update policy to use.
110 * 0 - every tick, bad hardware may fail with "calcru negative..."
111 * 1 - more resistent to the above hardware, but less efficient.
112 */
113static int tco_method;
42SYSCTL_NODE(_kern, OID_AUTO, timecounter, CTLFLAG_RW, 0, "");
114
43
44static unsigned nmicrotime;
45static unsigned nnanotime;
46static unsigned ngetmicrotime;
47static unsigned ngetnanotime;
48static unsigned nmicrouptime;
49static unsigned nnanouptime;
50static unsigned ngetmicrouptime;
51static unsigned ngetnanouptime;
52SYSCTL_INT(_kern_timecounter, OID_AUTO, nmicrotime, CTLFLAG_RD, &nmicrotime, 0, "");
53SYSCTL_INT(_kern_timecounter, OID_AUTO, nnanotime, CTLFLAG_RD, &nnanotime, 0, "");
54SYSCTL_INT(_kern_timecounter, OID_AUTO, nmicrouptime, CTLFLAG_RD, &nmicrouptime, 0, "");
55SYSCTL_INT(_kern_timecounter, OID_AUTO, nnanouptime, CTLFLAG_RD, &nnanouptime, 0, "");
56SYSCTL_INT(_kern_timecounter, OID_AUTO, ngetmicrotime, CTLFLAG_RD, &ngetmicrotime, 0, "");
57SYSCTL_INT(_kern_timecounter, OID_AUTO, ngetnanotime, CTLFLAG_RD, &ngetnanotime, 0, "");
58SYSCTL_INT(_kern_timecounter, OID_AUTO, ngetmicrouptime, CTLFLAG_RD, &ngetmicrouptime, 0, "");
59SYSCTL_INT(_kern_timecounter, OID_AUTO, ngetnanouptime, CTLFLAG_RD, &ngetnanouptime, 0, "");
60
115/*
116 * Implement a dummy timecounter which we can use until we get a real one
117 * in the air. This allows the console and other early stuff to use
118 * timeservices.
119 */
120
121static unsigned
122dummy_get_timecount(struct timecounter *tc)
123{
124 static unsigned now;
61/*
62 * Implement a dummy timecounter which we can use until we get a real one
63 * in the air. This allows the console and other early stuff to use
64 * timeservices.
65 */
66
67static unsigned
68dummy_get_timecount(struct timecounter *tc)
69{
70 static unsigned now;
71
125 return (++now);
126}
127
128static struct timecounter dummy_timecounter = {
129 dummy_get_timecount,
130 0,
131 ~0u,
132 1000000,
133 "dummy"
134};
135
136struct timecounter *timecounter = &dummy_timecounter;
137
72 return (++now);
73}
74
75static struct timecounter dummy_timecounter = {
76 dummy_get_timecount,
77 0,
78 ~0u,
79 1000000,
80 "dummy"
81};
82
83struct timecounter *timecounter = &dummy_timecounter;
84
138/*
139 * Clock handling routines.
140 *
141 * This code is written to operate with two timers that run independently of
142 * each other.
143 *
144 * The main timer, running hz times per second, is used to trigger interval
145 * timers, timeouts and rescheduling as needed.
146 *
147 * The second timer handles kernel and user profiling,
148 * and does resource use estimation. If the second timer is programmable,
149 * it is randomized to avoid aliasing between the two clocks. For example,
150 * the randomization prevents an adversary from always giving up the cpu
151 * just before its quantum expires. Otherwise, it would never accumulate
152 * cpu ticks. The mean frequency of the second timer is stathz.
153 *
154 * If no second timer exists, stathz will be zero; in this case we drive
155 * profiling and statistics off the main clock. This WILL NOT be accurate;
156 * do not do it unless absolutely necessary.
157 *
158 * The statistics clock may (or may not) be run at a higher rate while
159 * profiling. This profile clock runs at profhz. We require that profhz
160 * be an integral multiple of stathz.
161 *
162 * If the statistics clock is running fast, it must be divided by the ratio
163 * profhz/stathz for statistics. (For profiling, every tick counts.)
164 *
165 * Time-of-day is maintained using a "timecounter", which may or may
166 * not be related to the hardware generating the above mentioned
167 * interrupts.
168 */
169
170int stathz;
171int profhz;
172static int profprocs;
173int ticks;
174static int psdiv, pscnt; /* prof => stat divider */
175int psratio; /* ratio: prof / stat */
176
177/*
178 * Initialize clock frequencies and start both clocks running.
179 */
180/* ARGSUSED*/
181static void
182initclocks(dummy)
183 void *dummy;
184{
185 register int i;
186
187 /*
188 * Set divisors to 1 (normal case) and let the machine-specific
189 * code do its bit.
190 */
191 psdiv = pscnt = 1;
192 cpu_initclocks();
193
194 /*
195 * Compute profhz/stathz, and fix profhz if needed.
196 */
197 i = stathz ? stathz : hz;
198 if (profhz == 0)
199 profhz = i;
200 psratio = profhz / i;
201}
202
203/*
204 * The real-time timer, interrupting hz times per second.
205 */
206void
207hardclock(frame)
208 register struct clockframe *frame;
209{
210 register struct proc *p;
211
212 p = curproc;
213 if (p) {
214 register struct pstats *pstats;
215
216 /*
217 * Run current process's virtual and profile time, as needed.
218 */
219 pstats = p->p_stats;
220 if (CLKF_USERMODE(frame) &&
221 timevalisset(&pstats->p_timer[ITIMER_VIRTUAL].it_value) &&
222 itimerdecr(&pstats->p_timer[ITIMER_VIRTUAL], tick) == 0)
223 psignal(p, SIGVTALRM);
224 if (timevalisset(&pstats->p_timer[ITIMER_PROF].it_value) &&
225 itimerdecr(&pstats->p_timer[ITIMER_PROF], tick) == 0)
226 psignal(p, SIGPROF);
227 }
228
229#if defined(SMP) && defined(BETTER_CLOCK)
230 forward_hardclock(pscnt);
231#endif
232
233 /*
234 * If no separate statistics clock is available, run it from here.
235 */
236 if (stathz == 0)
237 statclock(frame);
238
239 tco_forward(0);
240 ticks++;
241
242 /*
243 * Process callouts at a very low cpu priority, so we don't keep the
244 * relatively high clock interrupt priority any longer than necessary.
245 */
246 if (TAILQ_FIRST(&callwheel[ticks & callwheelmask]) != NULL) {
247 if (CLKF_BASEPRI(frame)) {
248 /*
249 * Save the overhead of a software interrupt;
250 * it will happen as soon as we return, so do it now.
251 */
252 (void)splsoftclock();
253 softclock();
254 } else
255 setsoftclock();
256 } else if (softticks + 1 == ticks)
257 ++softticks;
258}
259
260/*
261 * Compute number of ticks in the specified amount of time.
262 */
263int
264tvtohz(tv)
265 struct timeval *tv;
266{
267 register unsigned long ticks;
268 register long sec, usec;
269
270 /*
271 * If the number of usecs in the whole seconds part of the time
272 * difference fits in a long, then the total number of usecs will
273 * fit in an unsigned long. Compute the total and convert it to
274 * ticks, rounding up and adding 1 to allow for the current tick
275 * to expire. Rounding also depends on unsigned long arithmetic
276 * to avoid overflow.
277 *
278 * Otherwise, if the number of ticks in the whole seconds part of
279 * the time difference fits in a long, then convert the parts to
280 * ticks separately and add, using similar rounding methods and
281 * overflow avoidance. This method would work in the previous
282 * case but it is slightly slower and assumes that hz is integral.
283 *
284 * Otherwise, round the time difference down to the maximum
285 * representable value.
286 *
287 * If ints have 32 bits, then the maximum value for any timeout in
288 * 10ms ticks is 248 days.
289 */
290 sec = tv->tv_sec;
291 usec = tv->tv_usec;
292 if (usec < 0) {
293 sec--;
294 usec += 1000000;
295 }
296 if (sec < 0) {
297#ifdef DIAGNOSTIC
298 if (usec > 0) {
299 sec++;
300 usec -= 1000000;
301 }
302 printf("tvotohz: negative time difference %ld sec %ld usec\n",
303 sec, usec);
304#endif
305 ticks = 1;
306 } else if (sec <= LONG_MAX / 1000000)
307 ticks = (sec * 1000000 + (unsigned long)usec + (tick - 1))
308 / tick + 1;
309 else if (sec <= LONG_MAX / hz)
310 ticks = sec * hz
311 + ((unsigned long)usec + (tick - 1)) / tick + 1;
312 else
313 ticks = LONG_MAX;
314 if (ticks > INT_MAX)
315 ticks = INT_MAX;
316 return ((int)ticks);
317}
318
319/*
320 * Start profiling on a process.
321 *
322 * Kernel profiling passes proc0 which never exits and hence
323 * keeps the profile clock running constantly.
324 */
325void
326startprofclock(p)
327 register struct proc *p;
328{
329 int s;
330
331 if ((p->p_flag & P_PROFIL) == 0) {
332 p->p_flag |= P_PROFIL;
333 if (++profprocs == 1 && stathz != 0) {
334 s = splstatclock();
335 psdiv = pscnt = psratio;
336 setstatclockrate(profhz);
337 splx(s);
338 }
339 }
340}
341
342/*
343 * Stop profiling on a process.
344 */
345void
346stopprofclock(p)
347 register struct proc *p;
348{
349 int s;
350
351 if (p->p_flag & P_PROFIL) {
352 p->p_flag &= ~P_PROFIL;
353 if (--profprocs == 0 && stathz != 0) {
354 s = splstatclock();
355 psdiv = pscnt = 1;
356 setstatclockrate(stathz);
357 splx(s);
358 }
359 }
360}
361
362/*
363 * Statistics clock. Grab profile sample, and if divider reaches 0,
364 * do process and kernel statistics. Most of the statistics are only
365 * used by user-level statistics programs. The main exceptions are
366 * p->p_uticks, p->p_sticks, p->p_iticks, and p->p_estcpu.
367 */
368void
369statclock(frame)
370 register struct clockframe *frame;
371{
372#ifdef GPROF
373 register struct gmonparam *g;
374 int i;
375#endif
376 register struct proc *p;
377 struct pstats *pstats;
378 long rss;
379 struct rusage *ru;
380 struct vmspace *vm;
381
382 if (curproc != NULL && CLKF_USERMODE(frame)) {
383 /*
384 * Came from user mode; CPU was in user state.
385 * If this process is being profiled, record the tick.
386 */
387 p = curproc;
388 if (p->p_flag & P_PROFIL)
389 addupc_intr(p, CLKF_PC(frame), 1);
390#if defined(SMP) && defined(BETTER_CLOCK)
391 if (stathz != 0)
392 forward_statclock(pscnt);
393#endif
394 if (--pscnt > 0)
395 return;
396 /*
397 * Charge the time as appropriate.
398 */
399 p->p_uticks++;
400 if (p->p_nice > NZERO)
401 cp_time[CP_NICE]++;
402 else
403 cp_time[CP_USER]++;
404 } else {
405#ifdef GPROF
406 /*
407 * Kernel statistics are just like addupc_intr, only easier.
408 */
409 g = &_gmonparam;
410 if (g->state == GMON_PROF_ON) {
411 i = CLKF_PC(frame) - g->lowpc;
412 if (i < g->textsize) {
413 i /= HISTFRACTION * sizeof(*g->kcount);
414 g->kcount[i]++;
415 }
416 }
417#endif
418#if defined(SMP) && defined(BETTER_CLOCK)
419 if (stathz != 0)
420 forward_statclock(pscnt);
421#endif
422 if (--pscnt > 0)
423 return;
424 /*
425 * Came from kernel mode, so we were:
426 * - handling an interrupt,
427 * - doing syscall or trap work on behalf of the current
428 * user process, or
429 * - spinning in the idle loop.
430 * Whichever it is, charge the time as appropriate.
431 * Note that we charge interrupts to the current process,
432 * regardless of whether they are ``for'' that process,
433 * so that we know how much of its real time was spent
434 * in ``non-process'' (i.e., interrupt) work.
435 */
436 p = curproc;
437 if (CLKF_INTR(frame)) {
438 if (p != NULL)
439 p->p_iticks++;
440 cp_time[CP_INTR]++;
441 } else if (p != NULL) {
442 p->p_sticks++;
443 cp_time[CP_SYS]++;
444 } else
445 cp_time[CP_IDLE]++;
446 }
447 pscnt = psdiv;
448
449 if (p != NULL) {
450 schedclock(p);
451
452 /* Update resource usage integrals and maximums. */
453 if ((pstats = p->p_stats) != NULL &&
454 (ru = &pstats->p_ru) != NULL &&
455 (vm = p->p_vmspace) != NULL) {
456 ru->ru_ixrss += pgtok(vm->vm_tsize);
457 ru->ru_idrss += pgtok(vm->vm_dsize);
458 ru->ru_isrss += pgtok(vm->vm_ssize);
459 rss = pgtok(vmspace_resident_count(vm));
460 if (ru->ru_maxrss < rss)
461 ru->ru_maxrss = rss;
462 }
463 }
464}
465
466/*
467 * Return information about system clocks.
468 */
469static int
470sysctl_kern_clockrate SYSCTL_HANDLER_ARGS
471{
472 struct clockinfo clkinfo;
473 /*
474 * Construct clockinfo structure.
475 */
476 clkinfo.hz = hz;
477 clkinfo.tick = tick;
478 clkinfo.tickadj = tickadj;
479 clkinfo.profhz = profhz;
480 clkinfo.stathz = stathz ? stathz : hz;
481 return (sysctl_handle_opaque(oidp, &clkinfo, sizeof clkinfo, req));
482}
483
484SYSCTL_PROC(_kern, KERN_CLOCKRATE, clockrate, CTLTYPE_STRUCT|CTLFLAG_RD,
485 0, 0, sysctl_kern_clockrate, "S,clockinfo","");
486
487static __inline unsigned
488tco_delta(struct timecounter *tc)
489{
490
491 return ((tc->tc_get_timecount(tc) - tc->tc_offset_count) &
492 tc->tc_counter_mask);
493}
494

--- 8 unchanged lines hidden (view full) ---

503 * interval measurements.
504 */
505
506void
507getmicrotime(struct timeval *tvp)
508{
509 struct timecounter *tc;
510
85static __inline unsigned
86tco_delta(struct timecounter *tc)
87{
88
89 return ((tc->tc_get_timecount(tc) - tc->tc_offset_count) &
90 tc->tc_counter_mask);
91}
92

--- 8 unchanged lines hidden (view full) ---

101 * interval measurements.
102 */
103
104void
105getmicrotime(struct timeval *tvp)
106{
107 struct timecounter *tc;
108
511 if (!tco_method) {
512 tc = timecounter;
513 *tvp = tc->tc_microtime;
514 } else {
515 microtime(tvp);
516 }
109 ngetmicrotime++;
110 tc = timecounter;
111 *tvp = tc->tc_microtime;
517}
518
519void
520getnanotime(struct timespec *tsp)
521{
522 struct timecounter *tc;
523
112}
113
114void
115getnanotime(struct timespec *tsp)
116{
117 struct timecounter *tc;
118
524 if (!tco_method) {
525 tc = timecounter;
526 *tsp = tc->tc_nanotime;
527 } else {
528 nanotime(tsp);
529 }
119 ngetnanotime++;
120 tc = timecounter;
121 *tsp = tc->tc_nanotime;
530}
531
532void
533microtime(struct timeval *tv)
534{
535 struct timecounter *tc;
536
122}
123
124void
125microtime(struct timeval *tv)
126{
127 struct timecounter *tc;
128
129 nmicrotime++;
537 tc = timecounter;
538 tv->tv_sec = tc->tc_offset_sec;
539 tv->tv_usec = tc->tc_offset_micro;
540 tv->tv_usec += ((u_int64_t)tco_delta(tc) * tc->tc_scale_micro) >> 32;
541 tv->tv_usec += boottime.tv_usec;
542 tv->tv_sec += boottime.tv_sec;
543 while (tv->tv_usec >= 1000000) {
544 tv->tv_usec -= 1000000;
545 tv->tv_sec++;
546 }
547}
548
549void
550nanotime(struct timespec *ts)
551{
552 unsigned count;
553 u_int64_t delta;
554 struct timecounter *tc;
555
130 tc = timecounter;
131 tv->tv_sec = tc->tc_offset_sec;
132 tv->tv_usec = tc->tc_offset_micro;
133 tv->tv_usec += ((u_int64_t)tco_delta(tc) * tc->tc_scale_micro) >> 32;
134 tv->tv_usec += boottime.tv_usec;
135 tv->tv_sec += boottime.tv_sec;
136 while (tv->tv_usec >= 1000000) {
137 tv->tv_usec -= 1000000;
138 tv->tv_sec++;
139 }
140}
141
142void
143nanotime(struct timespec *ts)
144{
145 unsigned count;
146 u_int64_t delta;
147 struct timecounter *tc;
148
149 nnanotime++;
556 tc = timecounter;
557 ts->tv_sec = tc->tc_offset_sec;
558 count = tco_delta(tc);
559 delta = tc->tc_offset_nano;
560 delta += ((u_int64_t)count * tc->tc_scale_nano_f);
561 delta >>= 32;
562 delta += ((u_int64_t)count * tc->tc_scale_nano_i);
563 delta += boottime.tv_usec * 1000;

--- 5 unchanged lines hidden (view full) ---

569 ts->tv_nsec = delta;
570}
571
572void
573getmicrouptime(struct timeval *tvp)
574{
575 struct timecounter *tc;
576
150 tc = timecounter;
151 ts->tv_sec = tc->tc_offset_sec;
152 count = tco_delta(tc);
153 delta = tc->tc_offset_nano;
154 delta += ((u_int64_t)count * tc->tc_scale_nano_f);
155 delta >>= 32;
156 delta += ((u_int64_t)count * tc->tc_scale_nano_i);
157 delta += boottime.tv_usec * 1000;

--- 5 unchanged lines hidden (view full) ---

163 ts->tv_nsec = delta;
164}
165
166void
167getmicrouptime(struct timeval *tvp)
168{
169 struct timecounter *tc;
170
577 if (!tco_method) {
578 tc = timecounter;
579 tvp->tv_sec = tc->tc_offset_sec;
580 tvp->tv_usec = tc->tc_offset_micro;
581 } else {
582 microuptime(tvp);
583 }
171 ngetmicrouptime++;
172 tc = timecounter;
173 tvp->tv_sec = tc->tc_offset_sec;
174 tvp->tv_usec = tc->tc_offset_micro;
584}
585
586void
587getnanouptime(struct timespec *tsp)
588{
589 struct timecounter *tc;
590
175}
176
177void
178getnanouptime(struct timespec *tsp)
179{
180 struct timecounter *tc;
181
591 if (!tco_method) {
592 tc = timecounter;
593 tsp->tv_sec = tc->tc_offset_sec;
594 tsp->tv_nsec = tc->tc_offset_nano >> 32;
595 } else {
596 nanouptime(tsp);
597 }
182 ngetnanouptime++;
183 tc = timecounter;
184 tsp->tv_sec = tc->tc_offset_sec;
185 tsp->tv_nsec = tc->tc_offset_nano >> 32;
598}
599
600void
601microuptime(struct timeval *tv)
602{
603 struct timecounter *tc;
604
186}
187
188void
189microuptime(struct timeval *tv)
190{
191 struct timecounter *tc;
192
193 nmicrouptime++;
605 tc = timecounter;
606 tv->tv_sec = tc->tc_offset_sec;
607 tv->tv_usec = tc->tc_offset_micro;
608 tv->tv_usec += ((u_int64_t)tco_delta(tc) * tc->tc_scale_micro) >> 32;
609 if (tv->tv_usec >= 1000000) {
610 tv->tv_usec -= 1000000;
611 tv->tv_sec++;
612 }
613}
614
615void
616nanouptime(struct timespec *ts)
617{
618 unsigned count;
619 u_int64_t delta;
620 struct timecounter *tc;
621
194 tc = timecounter;
195 tv->tv_sec = tc->tc_offset_sec;
196 tv->tv_usec = tc->tc_offset_micro;
197 tv->tv_usec += ((u_int64_t)tco_delta(tc) * tc->tc_scale_micro) >> 32;
198 if (tv->tv_usec >= 1000000) {
199 tv->tv_usec -= 1000000;
200 tv->tv_sec++;
201 }
202}
203
204void
205nanouptime(struct timespec *ts)
206{
207 unsigned count;
208 u_int64_t delta;
209 struct timecounter *tc;
210
211 nnanouptime++;
622 tc = timecounter;
623 ts->tv_sec = tc->tc_offset_sec;
624 count = tco_delta(tc);
625 delta = tc->tc_offset_nano;
626 delta += ((u_int64_t)count * tc->tc_scale_nano_f);
627 delta >>= 32;
628 delta += ((u_int64_t)count * tc->tc_scale_nano_i);
629 if (delta >= 1000000000) {

--- 12 unchanged lines hidden (view full) ---

642 scale += tc->tc_adjustment;
643 scale /= tc->tc_tweak->tc_frequency;
644 tc->tc_scale_micro = scale / 1000;
645 tc->tc_scale_nano_f = scale & 0xffffffff;
646 tc->tc_scale_nano_i = scale >> 32;
647}
648
649void
212 tc = timecounter;
213 ts->tv_sec = tc->tc_offset_sec;
214 count = tco_delta(tc);
215 delta = tc->tc_offset_nano;
216 delta += ((u_int64_t)count * tc->tc_scale_nano_f);
217 delta >>= 32;
218 delta += ((u_int64_t)count * tc->tc_scale_nano_i);
219 if (delta >= 1000000000) {

--- 12 unchanged lines hidden (view full) ---

232 scale += tc->tc_adjustment;
233 scale /= tc->tc_tweak->tc_frequency;
234 tc->tc_scale_micro = scale / 1000;
235 tc->tc_scale_nano_f = scale & 0xffffffff;
236 tc->tc_scale_nano_i = scale >> 32;
237}
238
239void
650update_timecounter(struct timecounter *tc)
240tc_update(struct timecounter *tc)
651{
652 tco_setscales(tc);
653}
654
655void
241{
242 tco_setscales(tc);
243}
244
245void
656init_timecounter(struct timecounter *tc)
246tc_init(struct timecounter *tc)
657{
658 struct timespec ts1;
659 struct timecounter *t1, *t2, *t3;
660 int i;
661
662 tc->tc_adjustment = 0;
663 tc->tc_tweak = tc;
664 tco_setscales(tc);

--- 26 unchanged lines hidden (view full) ---

691 nanouptime(&ts1);
692 tc->tc_offset_nano = (u_int64_t)ts1.tv_nsec << 32;
693 tc->tc_offset_micro = ts1.tv_nsec / 1000;
694 tc->tc_offset_sec = ts1.tv_sec;
695 timecounter = tc;
696}
697
698void
247{
248 struct timespec ts1;
249 struct timecounter *t1, *t2, *t3;
250 int i;
251
252 tc->tc_adjustment = 0;
253 tc->tc_tweak = tc;
254 tco_setscales(tc);

--- 26 unchanged lines hidden (view full) ---

281 nanouptime(&ts1);
282 tc->tc_offset_nano = (u_int64_t)ts1.tv_nsec << 32;
283 tc->tc_offset_micro = ts1.tv_nsec / 1000;
284 tc->tc_offset_sec = ts1.tv_sec;
285 timecounter = tc;
286}
287
288void
699set_timecounter(struct timespec *ts)
289tc_setclock(struct timespec *ts)
700{
701 struct timespec ts2;
702
703 nanouptime(&ts2);
704 boottime.tv_sec = ts->tv_sec - ts2.tv_sec;
705 boottime.tv_usec = (ts->tv_nsec - ts2.tv_nsec) / 1000;
706 if (boottime.tv_usec < 0) {
707 boottime.tv_usec += 1000000;
708 boottime.tv_sec--;
709 }
710 /* fiddle all the little crinkly bits around the fiords... */
290{
291 struct timespec ts2;
292
293 nanouptime(&ts2);
294 boottime.tv_sec = ts->tv_sec - ts2.tv_sec;
295 boottime.tv_usec = (ts->tv_nsec - ts2.tv_nsec) / 1000;
296 if (boottime.tv_usec < 0) {
297 boottime.tv_usec += 1000000;
298 boottime.tv_sec--;
299 }
300 /* fiddle all the little crinkly bits around the fiords... */
711 tco_forward(1);
301 tc_windup();
712}
713
714static void
715switch_timecounter(struct timecounter *newtc)
716{
717 int s;
718 struct timecounter *tc;
719 struct timespec ts;

--- 29 unchanged lines hidden (view full) ---

749 delta = tco_delta(tc);
750 tc->tc_offset_count += delta;
751 tc->tc_offset_count &= tc->tc_counter_mask;
752 tc->tc_offset_nano += (u_int64_t)delta * tc->tc_scale_nano_f;
753 tc->tc_offset_nano += (u_int64_t)delta * tc->tc_scale_nano_i << 32;
754 return (tc);
755}
756
302}
303
304static void
305switch_timecounter(struct timecounter *newtc)
306{
307 int s;
308 struct timecounter *tc;
309 struct timespec ts;

--- 29 unchanged lines hidden (view full) ---

339 delta = tco_delta(tc);
340 tc->tc_offset_count += delta;
341 tc->tc_offset_count &= tc->tc_counter_mask;
342 tc->tc_offset_nano += (u_int64_t)delta * tc->tc_scale_nano_f;
343 tc->tc_offset_nano += (u_int64_t)delta * tc->tc_scale_nano_i << 32;
344 return (tc);
345}
346
757static void
758tco_forward(int force)
347void
348tc_windup(void)
759{
760 struct timecounter *tc, *tco;
761 struct timeval tvt;
762
763 tco = timecounter;
764 tc = sync_other_counter();
765 /*
766 * We may be inducing a tiny error here, the tc_poll_pps() may

--- 20 unchanged lines hidden (view full) ---

787 timedelta -= tickdelta;
788 }
789
790 while (tc->tc_offset_nano >= 1000000000ULL << 32) {
791 tc->tc_offset_nano -= 1000000000ULL << 32;
792 tc->tc_offset_sec++;
793 ntp_update_second(tc); /* XXX only needed if xntpd runs */
794 tco_setscales(tc);
349{
350 struct timecounter *tc, *tco;
351 struct timeval tvt;
352
353 tco = timecounter;
354 tc = sync_other_counter();
355 /*
356 * We may be inducing a tiny error here, the tc_poll_pps() may

--- 20 unchanged lines hidden (view full) ---

377 timedelta -= tickdelta;
378 }
379
380 while (tc->tc_offset_nano >= 1000000000ULL << 32) {
381 tc->tc_offset_nano -= 1000000000ULL << 32;
382 tc->tc_offset_sec++;
383 ntp_update_second(tc); /* XXX only needed if xntpd runs */
384 tco_setscales(tc);
795 force++;
796 }
797
385 }
386
798 if (tco_method && !force)
799 return;
800
801 tc->tc_offset_micro = (tc->tc_offset_nano / 1000) >> 32;
802
803 /* Figure out the wall-clock time */
804 tc->tc_nanotime.tv_sec = tc->tc_offset_sec + boottime.tv_sec;
805 tc->tc_nanotime.tv_nsec =
806 (tc->tc_offset_nano >> 32) + boottime.tv_usec * 1000;
807 tc->tc_microtime.tv_usec = tc->tc_offset_micro + boottime.tv_usec;
808 if (tc->tc_nanotime.tv_nsec >= 1000000000) {
809 tc->tc_nanotime.tv_nsec -= 1000000000;
810 tc->tc_microtime.tv_usec -= 1000000;
811 tc->tc_nanotime.tv_sec++;
812 }
813 time_second = tc->tc_microtime.tv_sec = tc->tc_nanotime.tv_sec;
814
815 timecounter = tc;
816}
817
387 tc->tc_offset_micro = (tc->tc_offset_nano / 1000) >> 32;
388
389 /* Figure out the wall-clock time */
390 tc->tc_nanotime.tv_sec = tc->tc_offset_sec + boottime.tv_sec;
391 tc->tc_nanotime.tv_nsec =
392 (tc->tc_offset_nano >> 32) + boottime.tv_usec * 1000;
393 tc->tc_microtime.tv_usec = tc->tc_offset_micro + boottime.tv_usec;
394 if (tc->tc_nanotime.tv_nsec >= 1000000000) {
395 tc->tc_nanotime.tv_nsec -= 1000000000;
396 tc->tc_microtime.tv_usec -= 1000000;
397 tc->tc_nanotime.tv_sec++;
398 }
399 time_second = tc->tc_microtime.tv_sec = tc->tc_nanotime.tv_sec;
400
401 timecounter = tc;
402}
403
818SYSCTL_NODE(_kern, OID_AUTO, timecounter, CTLFLAG_RW, 0, "");
819
820SYSCTL_INT(_kern_timecounter, OID_AUTO, method, CTLFLAG_RW, &tco_method, 0,
821 "This variable determines the method used for updating timecounters. "
822 "If the default algorithm (0) fails with \"calcru negative...\" messages "
823 "try the alternate algorithm (1) which handles bad hardware better."
824
825);
826
827static int
828sysctl_kern_timecounter_hardware SYSCTL_HANDLER_ARGS
829{
830 char newname[32];
831 struct timecounter *newtc, *tc;
832 int error;
833
834 tc = timecounter->tc_tweak;

--- 170 unchanged lines hidden ---
404static int
405sysctl_kern_timecounter_hardware SYSCTL_HANDLER_ARGS
406{
407 char newname[32];
408 struct timecounter *newtc, *tc;
409 int error;
410
411 tc = timecounter->tc_tweak;

--- 170 unchanged lines hidden ---