summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcheloha <cheloha@cvs.openbsd.org>2019-06-03 01:27:31 +0000
committercheloha <cheloha@cvs.openbsd.org>2019-06-03 01:27:31 +0000
commit8462915bcbbfceaacadcb124aea7494de9067b67 (patch)
treecc2797608205d270b64d672b420ef800760197b9
parent1a6db7afbda625bea54b11bd578b5ee38ec96b99 (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/Makefile6
-rw-r--r--share/man/man9/bintimeadd.9185
-rw-r--r--sys/kern/kern_tc.c52
-rw-r--r--sys/kern/kern_time.c6
-rw-r--r--sys/sys/time.h59
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;