Index: sys/kern/kern_clock.c =================================================================== --- sys/kern/kern_clock.c +++ sys/kern/kern_clock.c @@ -377,10 +377,10 @@ int stathz; int profhz; int profprocs; -volatile int ticks; +volatile long ticks; int psratio; -static DPCPU_DEFINE(int, pcputicks); /* Per-CPU version of ticks. */ +static DPCPU_DEFINE(long, pcputicks); /* Per-CPU version of ticks. */ static int global_hardclock_run = 0; /* @@ -411,10 +411,10 @@ EVENTHANDLER_REGISTER(watchdog_list, watchdog_config, NULL, 0); #endif /* - * Arrange for ticks to wrap 10 minutes after boot to help catch + * Arrange for ticks to wrap 5 minutes after boot to help catch * sign problems sooner. */ - ticks = INT_MAX - (hz * 10 * 60); + ticks = LONG_MAX - (((uint64_t)hz) * 5 * 60); } /* @@ -469,7 +469,7 @@ hardclock(int usermode, uintfptr_t pc) { - atomic_add_int(&ticks, 1); + atomic_add_long(&ticks, 1); hardclock_cpu(usermode); tc_ticktock(1); cpu_tick_calibration(); @@ -497,8 +497,10 @@ struct pstats *pstats; struct thread *td = curthread; struct proc *p = td->td_proc; - int *t = DPCPU_PTR(pcputicks); - int flags, global, newticks; + long *t = DPCPU_PTR(pcputicks); + long global, newticks; + int flags; + #ifdef SW_WATCHDOG int i; #endif /* SW_WATCHDOG */ @@ -516,7 +518,7 @@ newticks = 0; break; } - } while (!atomic_cmpset_int(&ticks, global, *t)); + } while (!atomic_cmpset_long(&ticks, global, *t)); /* * Run current process's virtual and profile time, as needed. @@ -575,7 +577,7 @@ void hardclock_sync(int cpu) { - int *t = DPCPU_ID_PTR(cpu, pcputicks); + long *t = DPCPU_ID_PTR(cpu, pcputicks); *t = ticks; } @@ -640,6 +642,62 @@ } /* + * Compute number of ticks in the specified amount of time. + */ +uint64_t +tvtohz64(struct timeval *tv) +{ + uint64_t ticks; + int64_t sec, usec; + + /* + * If the number of usecs in the whole seconds part of the time + * difference fits in a long, then the total number of usecs will + * fit in an unsigned long. Compute the total and convert it to + * ticks, rounding up and adding 1 to allow for the current tick + * to expire. Rounding also depends on unsigned long arithmetic + * to avoid overflow. + * + * Otherwise, if the number of ticks in the whole seconds part of + * the time difference fits in a long, then convert the parts to + * ticks separately and add, using similar rounding methods and + * overflow avoidance. This method would work in the previous + * case but it is slightly slower and assumes that hz is integral. + * + * Otherwise, round the time difference down to the maximum + * representable value. + * + */ + sec = tv->tv_sec; + usec = tv->tv_usec; + if (usec < 0) { + sec--; + usec += 1000000; + } + if (sec < 0) { +#ifdef DIAGNOSTIC + if (usec > 0) { + sec++; + usec -= 1000000; + } + printf("tvotohz: negative time difference %ld sec %ld usec\n", + sec, usec); +#endif + ticks = 1; + } else if (sec <= LONG_MAX / 1000000) + ticks = (sec * 1000000 + (uint64_t)usec + (tick - 1)) + / tick + 1; + else if (sec <= LONG_MAX / hz) + ticks = sec * hz + + ((uint64_t)usec + (tick - 1)) / tick + 1; + else + ticks = LONG_MAX; + if (ticks > LONG_MAX) + ticks = LONG_MAX; + return (ticks); +} + +/* * Start profiling on a process. * * Kernel profiling passes proc0 which never exits and hence Index: sys/kern/kern_clocksource.c =================================================================== --- sys/kern/kern_clocksource.c +++ sys/kern/kern_clocksource.c @@ -160,6 +160,7 @@ int usermode; int done, runs; + MPASS(tick_sbt <= htick_sbt); CTR3(KTR_SPARE2, "handle at %d: now %d.%08x", curcpu, (int)(now >> 32), (u_int)(now & 0xffffffff)); done = 0; @@ -181,6 +182,10 @@ if (runs) { hct = DPCPU_PTR(hardclocktime); *hct = state->nexthard - tick_sbt; + /* advance nexthard to next possible hardclock tick + * if hardclock_hz < hz + */ + state->nexthard += (htick_sbt - tick_sbt); if (fake < 2) { hardclock_cnt(runs, usermode); done = 1; Index: sys/kern/kern_sig.c =================================================================== --- sys/kern/kern_sig.c +++ sys/kern/kern_sig.c @@ -1229,7 +1229,8 @@ struct sigacts *ps; sigset_t saved_mask, new_block; struct proc *p; - int error, sig, timo, timevalid = 0; + int error, sig, timevalid = 0; + uint64_t timo; struct timespec rts, ets, ts; struct timeval tv; @@ -1285,7 +1286,7 @@ ts = ets; timespecsub(&ts, &rts); TIMESPEC_TO_TIMEVAL(&tv, &ts); - timo = tvtohz(&tv); + timo = tvtohz64(&tv); } else { timo = 0; } Index: sys/kern/kern_synch.c =================================================================== --- sys/kern/kern_synch.c +++ sys/kern/kern_synch.c @@ -342,7 +342,7 @@ /* silently convert invalid timeouts */ if (sbt == 0) - sbt = tick_sbt; + sbt = htick_sbt; if (cold || kdb_active) { /* @@ -556,8 +556,8 @@ * run at regular intervals. */ callout_reset_sbt(&loadav_callout, - SBT_1US * (4000000 + (int)(random() % 2000001)), SBT_1US, - loadav, NULL, C_DIRECT_EXEC | C_PREL(32)); + SBT_1US * (4000000 + (int)(random() % 2000001)), SBT_1MS, + loadav, NULL, C_DIRECT_EXEC | C_PREL(C_PMS)); } /* ARGSUSED */ Index: sys/kern/kern_tc.c =================================================================== --- sys/kern/kern_tc.c +++ sys/kern/kern_tc.c @@ -35,6 +35,13 @@ #include #include +#include +#include + +DPCPU_DECLARE(uint64_t, tsc); + + + /* * A large step happens on boot. This constant detects such steps. * It is relatively small so that ntp_update_second gets called enough @@ -1273,7 +1280,9 @@ u_int delta, ncount, ogen; int i; time_t t; + uint64_t tscval; + tscval = rdtscp(); /* * Make the next timehands a copy of the current one, but do * not overwrite the generation or next pointer. While we @@ -1512,7 +1521,8 @@ static int pps_fetch(struct pps_fetch_args *fapi, struct pps_state *pps) { - int err, timo; + int err; + uint64_t timo; pps_seq_t aseq, cseq; struct timeval tv; @@ -1532,7 +1542,7 @@ else { tv.tv_sec = fapi->timeout.tv_sec; tv.tv_usec = fapi->timeout.tv_nsec / 1000; - timo = tvtohz(&tv); + timo = tvtohz64(&tv); } aseq = pps->ppsinfo.assert_sequence; cseq = pps->ppsinfo.clear_sequence; @@ -1933,6 +1943,8 @@ static DPCPU_DEFINE(uint64_t, tc_cpu_ticks_base); static DPCPU_DEFINE(unsigned, tc_cpu_ticks_last); +static DPCPU_DEFINE(uint64_t, tc_tsc); + static uint64_t tc_cpu_ticks(void) Index: sys/kern/kern_thr.c =================================================================== --- sys/kern/kern_thr.c +++ sys/kern/kern_thr.c @@ -503,7 +503,7 @@ struct proc *p = td->td_proc; struct timeval tv; int error = 0; - int timo = 0; + uint64_t timo = 0; if (td->td_pflags & TDP_WAKEUP) { td->td_pflags &= ~TDP_WAKEUP; @@ -515,7 +515,7 @@ error = EWOULDBLOCK; else { TIMESPEC_TO_TIMEVAL(&tv, tsp); - timo = tvtohz(&tv); + timo = tvtohz64(&tv); } } Index: sys/kern/kern_thrworkq.c =================================================================== --- sys/kern/kern_thrworkq.c +++ sys/kern/kern_thrworkq.c @@ -307,15 +307,15 @@ return ((u_int64_t)t.tv_sec * 1000000 + (u_int64_t)t.tv_usec); } -static uint32_t +static uint64_t twq_usecstoticks(uint32_t usec) { struct timeval tv; - uint32_t tticks; + uint64_t tticks; tv.tv_sec = usec / 1000000; tv.tv_usec = usec - (tv.tv_sec * 1000000); - tticks = tvtohz(&tv); + tticks = tvtohz64(&tv); return (tticks); } @@ -323,7 +323,7 @@ static void twq_interval_timer_start(struct thrworkq *wq) { - uint32_t deadline; + uint64_t deadline; if (wq->wq_timer_interval == 0) wq->wq_timer_interval = wq_stalled_window_usecs; Index: sys/kern/kern_time.c =================================================================== --- sys/kern/kern_time.c +++ sys/kern/kern_time.c @@ -1467,7 +1467,7 @@ */ } TIMESPEC_TO_TIMEVAL(&tv, &ts); - callout_reset(&it->it_callout, tvtohz(&tv), + callout_reset(&it->it_callout, tvtohz64(&tv), realtimer_expire, it); } else { callout_stop(&it->it_callout); @@ -1545,7 +1545,7 @@ ts = it->it_time.it_value; timespecsub(&ts, &cts); TIMESPEC_TO_TIMEVAL(&tv, &ts); - callout_reset(&it->it_callout, tvtohz(&tv), + callout_reset(&it->it_callout, tvtohz64(&tv), realtimer_expire, it); } itimer_enter(it); @@ -1557,7 +1557,7 @@ ts = it->it_time.it_value; timespecsub(&ts, &cts); TIMESPEC_TO_TIMEVAL(&tv, &ts); - callout_reset(&it->it_callout, tvtohz(&tv), realtimer_expire, + callout_reset(&it->it_callout, tvtohz64(&tv), realtimer_expire, it); } } Index: sys/kern/kern_timeout.c =================================================================== --- sys/kern/kern_timeout.c +++ sys/kern/kern_timeout.c @@ -594,7 +594,7 @@ if (flags & C_DIRECT_EXEC) c->c_iflags |= CALLOUT_DIRECT; c->c_func = func; - c->c_time = sbt; + c->c_time = roundup(sbt, precision); c->c_precision = precision; bucket = callout_get_bucket(c->c_time); CTR3(KTR_CALLOUT, "precision set for %p: %d.%08x", @@ -946,7 +946,7 @@ * callout_deactivate() - marks the callout as having been serviced */ int -callout_reset_sbt_on(struct callout *c, sbintime_t sbt, sbintime_t precision, +callout_reset_sbt_on_(struct callout *c, sbintime_t sbt, sbintime_t precision, void (*ftn)(void *), void *arg, int cpu, int flags) { sbintime_t to_sbt, pr; @@ -954,6 +954,8 @@ int cancelled, direct; int ignore_cpu=0; + MPASS(precision >= SBT_1US); + cancelled = 0; if (cpu == -1) { ignore_cpu = 1; @@ -991,7 +993,7 @@ #endif #endif if ((flags & C_HARDCLOCK) == 0) - to_sbt += tick_sbt; + to_sbt += max(tick_sbt, precision); } else to_sbt = sbinuptime(); if (SBT_MAX - to_sbt < sbt) @@ -1133,13 +1135,13 @@ * Common idioms that can be optimized in the future. */ int -callout_schedule_on(struct callout *c, int to_ticks, int cpu) +callout_schedule_on(struct callout *c, int64_t to_ticks, int cpu) { return callout_reset_on(c, to_ticks, c->c_func, c->c_arg, cpu); } int -callout_schedule(struct callout *c, int to_ticks) +callout_schedule(struct callout *c, int64_t to_ticks) { return callout_reset_on(c, to_ticks, c->c_func, c->c_arg, c->c_cpu); } Index: sys/kern/kern_umtx.c =================================================================== --- sys/kern/kern_umtx.c +++ sys/kern/kern_umtx.c @@ -704,13 +704,13 @@ wakeup(uq); } -static inline int +static inline int64_t tstohz(const struct timespec *tsp) { struct timeval tv; TIMESPEC_TO_TIMEVAL(&tv, tsp); - return tvtohz(&tv); + return tvtohz64(&tv); } static void @@ -744,7 +744,7 @@ kern_clock_gettime(curthread, timo->clockid, &timo->cur); } -static int +static int64_t abs_timeout_gethz(struct abs_timeout *timo) { struct timespec tts; @@ -764,7 +764,8 @@ umtxq_sleep(struct umtx_q *uq, const char *wmesg, struct abs_timeout *abstime) { struct umtxq_chain *uc; - int error, timo; + int error; + int64_t timo; uc = umtxq_getchain(&uq->uq_key); UMTXQ_LOCKED_ASSERT(uc); Index: sys/kern/subr_param.c =================================================================== --- sys/kern/subr_param.c +++ sys/kern/subr_param.c @@ -81,10 +81,13 @@ static int sysctl_kern_vm_guest(SYSCTL_HANDLER_ARGS); -int hz; /* system clock's frequency */ +int hz; /* systems maximum timer frequency */ +int hardclock_hz; /* system maximum hardclock frequency */ int tick; /* usec per tick (1000000 / hz) */ struct bintime tick_bt; /* bintime per tick (1s / hz) */ + sbintime_t tick_sbt; +sbintime_t htick_sbt; int maxusers; /* base tunable */ int maxproc; /* maximum # of processes */ int maxprocperuid; /* max # of procs per user */ @@ -107,8 +110,10 @@ u_long maxssiz; /* max stack size */ u_long sgrowsiz; /* amount to grow stack */ +SYSCTL_INT(_kern, OID_AUTO, hardclock_hz, CTLFLAG_RDTUN | CTLFLAG_NOFETCH, &hardclock_hz, 0, + "Max clock ticks per second"); SYSCTL_INT(_kern, OID_AUTO, hz, CTLFLAG_RDTUN | CTLFLAG_NOFETCH, &hz, 0, - "Number of clock ticks per second"); + "max schedulable ticks per second"); SYSCTL_INT(_kern, OID_AUTO, nbuf, CTLFLAG_RDTUN | CTLFLAG_NOFETCH, &nbuf, 0, "Number of buffers in the buffer cache"); SYSCTL_INT(_kern, OID_AUTO, nswbuf, CTLFLAG_RDTUN | CTLFLAG_NOFETCH, &nswbuf, 0, @@ -162,12 +167,16 @@ #if !defined(__mips__) && !defined(__arm64__) && !defined(__sparc64__) TUNABLE_INT_FETCH("kern.kstack_pages", &kstack_pages); #endif - hz = -1; + hardclock_hz = hz = -1; TUNABLE_INT_FETCH("kern.hz", &hz); if (hz == -1) hz = vm_guest > VM_GUEST_NO ? HZ_VM : HZ; - tick = 1000000 / hz; + TUNABLE_INT_FETCH("kern.hardclock_hz", &hardclock_hz); + if (hardclock_hz == -1) + hardclock_hz = min(hz, HZ); + tick = max(1000000 / hz, 1); tick_sbt = SBT_1S / hz; + htick_sbt = SBT_1S / hardclock_hz; tick_bt = sbttobt(tick_sbt); #ifdef VM_SWZONE_SIZE_MAX Index: sys/kern/tty_ttydisc.c =================================================================== --- sys/kern/tty_ttydisc.c +++ sys/kern/tty_ttydisc.c @@ -226,7 +226,8 @@ size_t vmin = MAX(tp->t_termios.c_cc[VMIN], 1); unsigned int vtime = tp->t_termios.c_cc[VTIME]; struct timeval end, now, left; - int error, hz; + int error; + uint64_t hz; MPASS(tp->t_termios.c_cc[VTIME] != 0); @@ -254,7 +255,7 @@ return (0); left = end; timevalsub(&left, &now); - hz = tvtohz(&left); + hz = tvtohz64(&left); /* * We have to wait for more. If the timer expires, we Index: sys/kern/uipc_mqueue.c =================================================================== --- sys/kern/uipc_mqueue.c +++ sys/kern/uipc_mqueue.c @@ -249,9 +249,9 @@ size_t msg_len, unsigned *msg_prio, int waitok, const struct timespec *abs_timeout); static int _mqueue_send(struct mqueue *mq, struct mqueue_msg *msg, - int timo); + int64_t timo); static int _mqueue_recv(struct mqueue *mq, struct mqueue_msg **msg, - int timo); + int64_t timo); static void mqueue_send_notification(struct mqueue *mq); static void mqueue_fdclose(struct thread *td, int fd, struct file *fp); static void mq_proc_exit(void *arg, struct proc *p); @@ -1679,7 +1679,7 @@ break; } TIMESPEC_TO_TIMEVAL(&tv, &ts2); - error = _mqueue_send(mq, msg, tvtohz(&tv)); + error = _mqueue_send(mq, msg, tvtohz64(&tv)); if (error != ETIMEDOUT) break; } @@ -1694,7 +1694,7 @@ * Common routine to send a message */ static int -_mqueue_send(struct mqueue *mq, struct mqueue_msg *msg, int timo) +_mqueue_send(struct mqueue *mq, struct mqueue_msg *msg, int64_t timo) { struct mqueue_msg *msg2; int error = 0; @@ -1831,7 +1831,7 @@ return (error); } TIMESPEC_TO_TIMEVAL(&tv, &ts2); - error = _mqueue_recv(mq, &msg, tvtohz(&tv)); + error = _mqueue_recv(mq, &msg, tvtohz64(&tv)); if (error == 0) break; if (error != ETIMEDOUT) @@ -1852,7 +1852,7 @@ * Common routine to receive a message */ static int -_mqueue_recv(struct mqueue *mq, struct mqueue_msg **msg, int timo) +_mqueue_recv(struct mqueue *mq, struct mqueue_msg **msg, int64_t timo) { int error = 0; Index: sys/kern/uipc_sem.c =================================================================== --- sys/kern/uipc_sem.c +++ sys/kern/uipc_sem.c @@ -808,7 +808,7 @@ break; } error = cv_timedwait_sig(&ks->ks_cv, - &sem_lock, tvtohz(&tv)); + &sem_lock, tvtohz64(&tv)); if (error != EWOULDBLOCK) break; } Index: sys/kern/vfs_aio.c =================================================================== --- sys/kern/vfs_aio.c +++ sys/kern/vfs_aio.c @@ -1969,7 +1969,8 @@ struct timeval atv; struct kaioinfo *ki; struct aiocblist *cb, *cbfirst; - int error, i, timo; + int error, i; + int64_t timo; timo = 0; if (ts) { @@ -1979,7 +1980,7 @@ TIMESPEC_TO_TIMEVAL(&atv, ts); if (itimerfix(&atv)) return (EINVAL); - timo = tvtohz(&atv); + timo = tvtohz64(&atv); } ki = p->p_aioinfo; @@ -2490,7 +2491,8 @@ struct kaioinfo *ki; struct aiocblist *cb; struct aiocb *uuaiocb; - int error, status, timo; + int error, status; + int64_t timo; ops->store_aiocb(aiocbp, NULL); @@ -2505,7 +2507,7 @@ TIMESPEC_TO_TIMEVAL(&atv, ts); if (itimerfix(&atv)) return (EINVAL); - timo = tvtohz(&atv); + timo = tvtohz64(&atv); } if (p->p_aioinfo == NULL) Index: sys/sys/callout.h =================================================================== --- sys/sys/callout.h +++ sys/sys/callout.h @@ -51,12 +51,16 @@ #define CALLOUT_DIRECT 0x0100 /* allow exec from hw int context */ #define C_DIRECT_EXEC 0x0001 /* direct execution of callout */ -#define C_PRELBITS 7 + + +#define C_PMS 7 +#define C_PRELBITS 11 #define C_PRELRANGE ((1 << C_PRELBITS) - 1) #define C_PREL(x) (((x) + 1) << 1) #define C_PRELGET(x) (int)((((x) >> 1) & C_PRELRANGE) - 1) -#define C_HARDCLOCK 0x0100 /* align to hardclock() calls */ -#define C_ABSOLUTE 0x0200 /* event time is absolute. */ +#define C_DEFAULT C_PREL(C_PMS) +#define C_HARDCLOCK 0x1000 /* align to hardclock() calls */ +#define C_ABSOLUTE 0x2000 /* event time is absolute. */ struct callout_handle { struct callout *callout; @@ -79,6 +83,12 @@ * flags via callout_active(), callout_deactivate(), callout_reset*(), or * callout_stop() to avoid races. */ + +/* if the passed precision is less than 1 microsecond set it to the resolution + * of hardclock + */ +#define prthresh(pr) ((pr) < SBT_1US ? htick_sbt : (pr)) + #define callout_active(c) ((c)->c_flags & CALLOUT_ACTIVE) #define callout_deactivate(c) ((c)->c_flags &= ~CALLOUT_ACTIVE) #define callout_drain(c) _callout_stop_safe(c, 1) @@ -94,29 +104,31 @@ _callout_init_lock((c), ((rw) != NULL) ? &(rw)->lock_object : \ NULL, (flags)) #define callout_pending(c) ((c)->c_iflags & CALLOUT_PENDING) -int callout_reset_sbt_on(struct callout *, sbintime_t, sbintime_t, - void (*)(void *), void *, int, int); +int callout_reset_sbt_on_(struct callout *, sbintime_t, sbintime_t, + void (*)(void *), void *, int, int); +#define callout_reset_sbt_on(c, sbt, pr, fn, arg, cpu, flags) \ + callout_reset_sbt_on_((c), (sbt), prthresh(pr), (fn), (arg), (cpu), (flags)); #define callout_reset_sbt(c, sbt, pr, fn, arg, flags) \ - callout_reset_sbt_on((c), (sbt), (pr), (fn), (arg), -1, (flags)) + callout_reset_sbt_on_((c), (sbt), prthresh(pr) , (fn), (arg), -1, (flags)) #define callout_reset_sbt_curcpu(c, sbt, pr, fn, arg, flags) \ - callout_reset_sbt_on((c), (sbt), (pr), (fn), (arg), PCPU_GET(cpuid),\ + callout_reset_sbt_on_((c), (sbt), prthresh(pr), (fn), (arg), PCPU_GET(cpuid),\ (flags)) #define callout_reset_on(c, to_ticks, fn, arg, cpu) \ - callout_reset_sbt_on((c), tick_sbt * (to_ticks), 0, (fn), (arg), \ + callout_reset_sbt_on_((c), tick_sbt * (to_ticks), SBT_1MS, (fn), (arg), \ (cpu), C_HARDCLOCK) #define callout_reset(c, on_tick, fn, arg) \ callout_reset_on((c), (on_tick), (fn), (arg), -1) #define callout_reset_curcpu(c, on_tick, fn, arg) \ callout_reset_on((c), (on_tick), (fn), (arg), PCPU_GET(cpuid)) #define callout_schedule_sbt_on(c, sbt, pr, cpu, flags) \ - callout_reset_sbt_on((c), (sbt), (pr), (c)->c_func, (c)->c_arg, \ + callout_reset_sbt_on_((c), (sbt), prthresh(pr), (c)->c_func, (c)->c_arg, \ (cpu), (flags)) #define callout_schedule_sbt(c, sbt, pr, flags) \ - callout_schedule_sbt_on((c), (sbt), (pr), -1, (flags)) + callout_schedule_sbt_on((c), (sbt), prthresh(pr), -1, (flags)) #define callout_schedule_sbt_curcpu(c, sbt, pr, flags) \ - callout_schedule_sbt_on((c), (sbt), (pr), PCPU_GET(cpuid), (flags)) -int callout_schedule(struct callout *, int); -int callout_schedule_on(struct callout *, int, int); + callout_schedule_sbt_on((c), (sbt), prthresh(pr), PCPU_GET(cpuid), (flags)) +int callout_schedule(struct callout *, int64_t); +int callout_schedule_on(struct callout *, int64_t, int); #define callout_schedule_curcpu(c, on_tick) \ callout_schedule_on((c), (on_tick), PCPU_GET(cpuid)) #define callout_stop(c) _callout_stop_safe(c, 0) Index: sys/sys/kernel.h =================================================================== --- sys/sys/kernel.h +++ sys/sys/kernel.h @@ -58,12 +58,13 @@ extern char kernelname[MAXPATHLEN]; extern int tick; /* usec per tick (1000000 / hz) */ -extern int hz; /* system clock's frequency */ +extern int hz; /* system scheduling granularity */ +extern int hardclock_hz; /* system clock's max frequency */ extern int psratio; /* ratio: prof / stat */ extern int stathz; /* statistics clock's frequency */ extern int profhz; /* profiling clock's frequency */ extern int profprocs; /* number of process's profiling */ -extern volatile int ticks; +extern volatile long ticks; #endif /* _KERNEL */ Index: sys/sys/time.h =================================================================== --- sys/sys/time.h +++ sys/sys/time.h @@ -378,6 +378,8 @@ extern sbintime_t tc_tick_sbt; extern struct bintime tick_bt; extern sbintime_t tick_sbt; +extern sbintime_t htick_sbt; +extern uint64_t tsc_sbt; extern int tc_precexp; extern int tc_timepercentage; extern struct bintime bt_timethreshold; @@ -448,6 +450,7 @@ void timevaladd(struct timeval *t1, const struct timeval *t2); void timevalsub(struct timeval *t1, const struct timeval *t2); int tvtohz(struct timeval *tv); +uint64_t tvtohz64(struct timeval *tv); #define TC_DEFAULTPERC 5