diff options
author | cheloha <cheloha@cvs.openbsd.org> | 2019-06-03 01:27:31 +0000 |
---|---|---|
committer | cheloha <cheloha@cvs.openbsd.org> | 2019-06-03 01:27:31 +0000 |
commit | 8462915bcbbfceaacadcb124aea7494de9067b67 (patch) | |
tree | cc2797608205d270b64d672b420ef800760197b9 | |
parent | 1a6db7afbda625bea54b11bd578b5ee38ec96b99 (diff) |
Switch from bintime_add() et al. to bintimeadd(9).
Basically just make all the bintime routines look and behave more like
the timeradd(3) macros.
Switch to three-argument forms for structure math, introduce and use
bintimecmp(9), and rename the structure conversion routines to resemble
e.g. TIMEVAL_TO_TIMESPEC(3).
Document all of this in a new bintimeadd.9 page.
Code input from mpi@, manpage input from schwarze@.
code ok mpi@, docs ok schwarze@, docs probably still ok jmc@
-rw-r--r-- | share/man/man9/Makefile | 6 | ||||
-rw-r--r-- | share/man/man9/bintimeadd.9 | 185 | ||||
-rw-r--r-- | sys/kern/kern_tc.c | 52 | ||||
-rw-r--r-- | sys/kern/kern_time.c | 6 | ||||
-rw-r--r-- | sys/sys/time.h | 59 |
5 files changed, 243 insertions, 65 deletions
diff --git a/share/man/man9/Makefile b/share/man/man9/Makefile index b55b7baee3c..8829966881c 100644 --- a/share/man/man9/Makefile +++ b/share/man/man9/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.293 2019/02/26 14:28:20 visa Exp $ +# $OpenBSD: Makefile,v 1.294 2019/06/03 01:27:30 cheloha Exp $ # $NetBSD: Makefile,v 1.4 1996/01/09 03:23:01 thorpej Exp $ # Makefile for section 9 (kernel function and variable) manual pages. @@ -7,8 +7,8 @@ MAN= aml_evalnode.9 atomic_add_int.9 atomic_cas_uint.9 \ atomic_dec_int.9 atomic_inc_int.9 atomic_setbits_int.9 \ atomic_sub_int.9 atomic_swap_uint.9 \ audio.9 autoconf.9 \ - bemtoh32.9 bio_register.9 boot.9 bpf_mtap.9 buffercache.9 bufq_init.9 \ - bus_dma.9 bus_space.9 \ + bemtoh32.9 bio_register.9 bintimeadd.9 boot.9 bpf_mtap.9 buffercache.9 \ + bufq_init.9 bus_dma.9 bus_space.9 \ copy.9 cond_init.9 config_attach.9 config_defer.9 counters_alloc.9 \ cpumem_get.9 crypto.9 \ delay.9 disk.9 disklabel.9 dma_alloc.9 dohooks.9 \ diff --git a/share/man/man9/bintimeadd.9 b/share/man/man9/bintimeadd.9 new file mode 100644 index 00000000000..ce6f6c9419b --- /dev/null +++ b/share/man/man9/bintimeadd.9 @@ -0,0 +1,185 @@ +.\" $OpenBSD: bintimeadd.9,v 1.1 2019/06/03 01:27:30 cheloha Exp $ +.\" $NetBSD: getitimer.2,v 1.6 1995/10/12 15:40:54 jtc Exp $ +.\" +.\" Copyright (c) 1983, 1991, 1993 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. Neither the name of the University nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" @(#)getitimer.2 8.2 (Berkeley) 12/11/93 +.\" +.Dd $Mdocdate: June 3 2019 $ +.Dt BINTIMEADD 9 +.Os +.Sh NAME +.Nm bintimecmp , +.Nm bintimesub , +.Nm bintimeadd , +.Nm bintimeaddfrac , +.Nm BINTIME_TO_TIMEVAL , +.Nm BINTIME_TO_TIMESPEC , +.Nm TIMEVAL_TO_BINTIME , +.Nm TIMESPEC_TO_BINTIME +.Nd manipulate kernel time structures +.Sh SYNOPSIS +.In sys/time.h +.Ft int +.Fo bintimecmp +.Fa "struct bintime *a" +.Fa "struct bintime *b" +.Fa operator +.Fc +.Ft void +.Fo bintimesub +.Fa "const struct bintime *a" +.Fa "const struct bintime *b" +.Fa "struct bintime *c" +.Fc +.Ft void +.Fo bintimeadd +.Fa "const struct bintime *a" +.Fa "const struct bintime *b" +.Fa "struct bintime *c" +.Fc +.Ft void +.Fo bintimeaddfrac +.Fa "const struct bintime *a" +.Fa "uint64_t fraction" +.Fa "struct bintime *b" +.Fc +.Ft void +.Fo BINTIME_TO_TIMEVAL +.Fa "const struct bintime *bt" +.Fa "struct timeval *tv" +.Fc +.Ft void +.Fo BINTIME_TO_TIMESPEC +.Fa "const struct bintime *bt" +.Fa "struct timespec *ts" +.Fc +.Ft void +.Fo TIMEVAL_TO_BINTIME +.Fa "const struct timeval *tv" +.Fa "struct bintime *bt" +.Fc +.Ft void +.Fo TIMESPEC_TO_BINTIME +.Fa "const struct timespec *ts" +.Fa "struct bintime *bt" +.Fc +.Sh DESCRIPTION +These functions simplify the use of +.Vt bintime +structures and the conversion to and from other time representations. +.Pp +The following functions are available: +.Bl -tag -width Ds +.It Fn bintimecmp a b operator +Test if the expression +.Fa a operator b +is true, +where +.Fa operator +is one of +.Cm < , +.Cm <= , +.Cm == , +.Cm != , +.Cm >= , +or +.Cm > . +.It Fn bintimesub a b c +Subtract +.Fa b +from +.Fa a +and store the result in +.Fa c . +.It Fn bintimeadd a b c +Add +.Fa b +to +.Fa a +and store the result in +.Fa c . +.It Fn bintimeaddfrac a fraction b +Add +.Fa fraction +fractional seconds to +.Fa a +and store the result in +.Fa b . +A fractional second is equal to 1 / (2^64) seconds. +.It Fn BINTIME_TO_TIMEVAL bt tv +Convert +.Fa bt +to a +.Vt struct timeval +and store the result in +.Fa tv . +.It Fn BINTIME_TO_TIMESPEC bt ts +Convert +.Fa bt +to a +.Vt struct timespec +and store the result in +.Fa ts . +.It Fn TIMEVAL_TO_BINTIME tv bt +Convert +.Fa tv +to a +.Vt struct bintime +and store the result in +.Fa bt . +.It Fn TIMESPEC_TO_BINTIME ts bt +Convert +.Fa ts +to a +.Vt struct bintime +and store the result in +.Fa bt . +.El +.Sh RETURN VALUES +.Fn bintimecmp +returns 1 if the tested condition holds or 0 otherwise. +.Sh CODE REFERENCES +These functions are implemented in the file +.Pa sys/sys/time.h . +.Sh SEE ALSO +.Xr timeradd 3 , +.Xr microtime 9 , +.Xr tc_init 9 , +.Xr timeout 9 +.Sh HISTORY +Predecessors to these functions first appeared in +.Fx 5.0 +and were ported to +.Ox 3.6 . +They were modified to more closely resemble the +.Xr timeradd 3 +macros for +.Ox 6.6 . +.Sh AUTHORS +.An Poul-Henning Kamp Aq Mt phk@freebsd.org diff --git a/sys/kern/kern_tc.c b/sys/kern/kern_tc.c index 4717adc908e..16cf6cdc605 100644 --- a/sys/kern/kern_tc.c +++ b/sys/kern/kern_tc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_tc.c,v 1.47 2019/05/22 19:59:37 cheloha Exp $ */ +/* $OpenBSD: kern_tc.c,v 1.48 2019/06/03 01:27:30 cheloha Exp $ */ /* * Copyright (c) 2000 Poul-Henning Kamp <phk@FreeBSD.org> @@ -163,7 +163,7 @@ microboottime(struct timeval *tvp) struct bintime bt; binboottime(&bt); - bintime2timeval(&bt, tvp); + BINTIME_TO_TIMEVAL(&bt, tvp); } void @@ -177,7 +177,7 @@ binuptime(struct bintime *bt) gen = th->th_generation; membar_consumer(); *bt = th->th_offset; - bintime_addx(bt, th->th_scale * tc_delta(th)); + bintimeaddfrac(bt, th->th_scale * tc_delta(th), bt); membar_consumer(); } while (gen == 0 || gen != th->th_generation); } @@ -188,7 +188,7 @@ nanouptime(struct timespec *tsp) struct bintime bt; binuptime(&bt); - bintime2timespec(&bt, tsp); + BINTIME_TO_TIMESPEC(&bt, tsp); } void @@ -197,7 +197,7 @@ microuptime(struct timeval *tvp) struct bintime bt; binuptime(&bt); - bintime2timeval(&bt, tvp); + BINTIME_TO_TIMEVAL(&bt, tvp); } void @@ -211,8 +211,8 @@ bintime(struct bintime *bt) gen = th->th_generation; membar_consumer(); *bt = th->th_offset; - bintime_addx(bt, th->th_scale * tc_delta(th)); - bintime_add(bt, &th->th_boottime); + bintimeaddfrac(bt, th->th_scale * tc_delta(th), bt); + bintimeadd(bt, &th->th_boottime, bt); membar_consumer(); } while (gen == 0 || gen != th->th_generation); } @@ -223,7 +223,7 @@ nanotime(struct timespec *tsp) struct bintime bt; bintime(&bt); - bintime2timespec(&bt, tsp); + BINTIME_TO_TIMESPEC(&bt, tsp); } void @@ -232,7 +232,7 @@ microtime(struct timeval *tvp) struct bintime bt; bintime(&bt); - bintime2timeval(&bt, tvp); + BINTIME_TO_TIMEVAL(&bt, tvp); } void @@ -245,7 +245,7 @@ getnanouptime(struct timespec *tsp) th = timehands; gen = th->th_generation; membar_consumer(); - bintime2timespec(&th->th_offset, tsp); + BINTIME_TO_TIMESPEC(&th->th_offset, tsp); membar_consumer(); } while (gen == 0 || gen != th->th_generation); } @@ -260,7 +260,7 @@ getmicrouptime(struct timeval *tvp) th = timehands; gen = th->th_generation; membar_consumer(); - bintime2timeval(&th->th_offset, tvp); + BINTIME_TO_TIMEVAL(&th->th_offset, tvp); membar_consumer(); } while (gen == 0 || gen != th->th_generation); } @@ -361,9 +361,9 @@ tc_setrealtimeclock(const struct timespec *ts) rw_enter_write(&tc_lock); mtx_enter(&windup_mtx); binuptime(&bt2); - timespec2bintime(ts, &bt); - bintime_sub(&bt, &bt2); - bintime_add(&bt2, &timehands->th_boottime); + TIMESPEC_TO_BINTIME(ts, &bt); + bintimesub(&bt, &bt2, &bt); + bintimeadd(&bt2, &timehands->th_boottime, &bt2); /* XXX fiddle all the little crinkly bits around the fiords... */ tc_windup(&bt, NULL, &zero); @@ -373,7 +373,7 @@ tc_setrealtimeclock(const struct timespec *ts) enqueue_randomness(ts->tv_sec); if (timestepwarnings) { - bintime2timespec(&bt2, &ts2); + BINTIME_TO_TIMESPEC(&bt2, &ts2); log(LOG_INFO, "Time stepped from %lld.%09ld to %lld.%09ld\n", (long long)ts2.tv_sec, ts2.tv_nsec, (long long)ts->tv_sec, ts->tv_nsec); @@ -408,15 +408,13 @@ tc_setclock(const struct timespec *ts) enqueue_randomness(ts->tv_sec); mtx_enter(&windup_mtx); - timespec2bintime(ts, &bt); - bintime_sub(&bt, &timehands->th_boottime); + TIMESPEC_TO_BINTIME(ts, &bt); + bintimesub(&bt, &timehands->th_boottime, &bt); /* * Don't rewind the offset. */ - if (bt.sec < timehands->th_offset.sec || - (bt.sec == timehands->th_offset.sec && - bt.frac < timehands->th_offset.frac)) + if (bintimecmp(&bt, &timehands->th_offset, <)) rewind = 1; bt2 = timehands->th_offset; @@ -426,7 +424,7 @@ tc_setclock(const struct timespec *ts) mtx_leave(&windup_mtx); if (rewind) { - bintime2timespec(&bt, &earlier); + BINTIME_TO_TIMESPEC(&bt, &earlier); printf("%s: cannot rewind uptime to %lld.%09ld\n", __func__, (long long)earlier.tv_sec, earlier.tv_nsec); return; @@ -434,8 +432,8 @@ tc_setclock(const struct timespec *ts) #ifndef SMALL_KERNEL /* convert the bintime to ticks */ - bintime_sub(&bt, &bt2); - bintime_add(&naptime, &bt); + bintimesub(&bt, &bt2, &bt); + bintimeadd(&naptime, &bt, &naptime); adj_ticks = (uint64_t)hz * bt.sec + (((uint64_t)1000000 * (uint32_t)(bt.frac >> 32)) >> 32) / tick; if (adj_ticks > 0) { @@ -499,7 +497,7 @@ tc_windup(struct bintime *new_boottime, struct bintime *new_offset, ncount = 0; th->th_offset_count += delta; th->th_offset_count &= th->th_counter->tc_counter_mask; - bintime_addx(&th->th_offset, th->th_scale * delta); + bintimeaddfrac(&th->th_offset, th->th_scale * delta, &th->th_offset); #ifdef notyet /* @@ -533,7 +531,7 @@ tc_windup(struct bintime *new_boottime, struct bintime *new_offset, * case we missed a leap second. */ bt = th->th_offset; - bintime_add(&bt, &th->th_boottime); + bintimeadd(&bt, &th->th_boottime, &bt); i = bt.sec - tho->th_microtime.tv_sec; if (i > LARGE_STEP) i = 2; @@ -542,8 +540,8 @@ tc_windup(struct bintime *new_boottime, struct bintime *new_offset, /* Update the UTC timestamps used by the get*() functions. */ /* XXX shouldn't do this here. Should force non-`get' versions. */ - bintime2timeval(&bt, &th->th_microtime); - bintime2timespec(&bt, &th->th_nanotime); + BINTIME_TO_TIMEVAL(&bt, &th->th_microtime); + BINTIME_TO_TIMESPEC(&bt, &th->th_nanotime); /* Now is a good time to change timecounters. */ if (th->th_counter != active_tc) { diff --git a/sys/kern/kern_time.c b/sys/kern/kern_time.c index ca109f81434..b9030067cfb 100644 --- a/sys/kern/kern_time.c +++ b/sys/kern/kern_time.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_time.c,v 1.118 2019/06/01 14:11:17 mpi Exp $ */ +/* $OpenBSD: kern_time.c,v 1.119 2019/06/03 01:27:30 cheloha Exp $ */ /* $NetBSD: kern_time.c,v 1.20 1996/02/18 11:57:06 fvdl Exp $ */ /* @@ -116,8 +116,8 @@ clock_gettime(struct proc *p, clockid_t clock_id, struct timespec *tp) break; case CLOCK_UPTIME: binuptime(&bt); - bintime_sub(&bt, &naptime); - bintime2timespec(&bt, tp); + bintimesub(&bt, &naptime, &bt); + BINTIME_TO_TIMESPEC(&bt, tp); break; case CLOCK_MONOTONIC: case CLOCK_BOOTTIME: diff --git a/sys/sys/time.h b/sys/sys/time.h index b4e0d20c688..8d4beeec964 100644 --- a/sys/sys/time.h +++ b/sys/sys/time.h @@ -1,4 +1,4 @@ -/* $OpenBSD: time.h,v 1.40 2019/01/19 01:53:44 cheloha Exp $ */ +/* $OpenBSD: time.h,v 1.41 2019/06/03 01:27:30 cheloha Exp $ */ /* $NetBSD: time.h,v 1.18 1996/04/23 10:29:33 mycroft Exp $ */ /* @@ -172,39 +172,38 @@ struct bintime { uint64_t frac; }; +#define bintimecmp(btp, ctp, cmp) \ + ((btp)->sec == (ctp)->sec ? \ + (btp)->frac cmp (ctp)->frac : \ + (btp)->sec cmp (ctp)->sec) + static __inline void -bintime_addx(struct bintime *bt, uint64_t x) +bintimeaddfrac(const struct bintime *bt, uint64_t x, struct bintime *ct) { - uint64_t u; - - u = bt->frac; - bt->frac += x; - if (u > bt->frac) - bt->sec++; + ct->sec = bt->sec; + if (bt->frac > bt->frac + x) + ct->sec++; + ct->frac = bt->frac + x; } static __inline void -bintime_add(struct bintime *bt, const struct bintime *bt2) +bintimeadd(const struct bintime *bt, const struct bintime *ct, + struct bintime *dt) { - uint64_t u; - - u = bt->frac; - bt->frac += bt2->frac; - if (u > bt->frac) - bt->sec++; - bt->sec += bt2->sec; + dt->sec = bt->sec + ct->sec; + if (bt->frac > bt->frac + ct->frac) + dt->sec++; + dt->frac = bt->frac + ct->frac; } static __inline void -bintime_sub(struct bintime *bt, const struct bintime *bt2) +bintimesub(const struct bintime *bt, const struct bintime *ct, + struct bintime *dt) { - uint64_t u; - - u = bt->frac; - bt->frac -= bt2->frac; - if (u < bt->frac) - bt->sec--; - bt->sec -= bt2->sec; + dt->sec = bt->sec - ct->sec; + if (bt->frac < bt->frac - ct->frac) + dt->sec--; + dt->frac = bt->frac - ct->frac; } /*- @@ -222,34 +221,30 @@ bintime_sub(struct bintime *bt, const struct bintime *bt2) */ static __inline void -bintime2timespec(const struct bintime *bt, struct timespec *ts) +BINTIME_TO_TIMESPEC(const struct bintime *bt, struct timespec *ts) { - ts->tv_sec = bt->sec; ts->tv_nsec = (long)(((uint64_t)1000000000 * (uint32_t)(bt->frac >> 32)) >> 32); } static __inline void -timespec2bintime(const struct timespec *ts, struct bintime *bt) +TIMESPEC_TO_BINTIME(const struct timespec *ts, struct bintime *bt) { - bt->sec = ts->tv_sec; /* 18446744073 = int(2^64 / 1000000000) */ bt->frac = (uint64_t)ts->tv_nsec * (uint64_t)18446744073ULL; } static __inline void -bintime2timeval(const struct bintime *bt, struct timeval *tv) +BINTIME_TO_TIMEVAL(const struct bintime *bt, struct timeval *tv) { - tv->tv_sec = bt->sec; tv->tv_usec = (long)(((uint64_t)1000000 * (uint32_t)(bt->frac >> 32)) >> 32); } static __inline void -timeval2bintime(const struct timeval *tv, struct bintime *bt) +TIMEVAL_TO_BINTIME(const struct timeval *tv, struct bintime *bt) { - bt->sec = (time_t)tv->tv_sec; /* 18446744073709 = int(2^64 / 1000000) */ bt->frac = (uint64_t)tv->tv_usec * (uint64_t)18446744073709ULL; |