diff options
author | cheloha <cheloha@openbsd.org> | 2020-06-22 21:16:07 +0000 |
---|---|---|
committer | cheloha <cheloha@openbsd.org> | 2020-06-22 21:16:07 +0000 |
commit | 8dca5d44636110d0ff0cfe71785c8f18da7ca99e (patch) | |
tree | 30226e4bdfd4d9e481f3abe43d2e583e583b7b5f | |
parent | Add opalcons(4), a driver for the OPAL console. (diff) | |
download | wireguard-openbsd-8dca5d44636110d0ff0cfe71785c8f18da7ca99e.tar.xz wireguard-openbsd-8dca5d44636110d0ff0cfe71785c8f18da7ca99e.zip |
timecounting: add gettime(9), getuptime(9)
time_second and time_uptime are used widely in the tree. This is a
problem on 32-bit platforms because time_t is 64-bit, so there is a
potential split-read whenever they are used at or below IPL_CLOCK.
Here are two replacement interfaces: gettime(9) and getuptime(9).
The "get" prefix signifies that they do not read the hardware
timecounter, i.e. they are fast and low-res. The lack of a unit
(e.g. micro, nano) signifies that they yield a plain time_t.
As an optimization on LP64 platforms we can just return time_second or
time_uptime, as a single read is atomic. On 32-bit platforms we need
to do the lockless read loop and get the values from the timecounter.
In a subsequent diff these will be substituted for time_second and
time_uptime almost everywhere in the kernel.
With input from visa@ and dlg@.
ok kettenis@
-rw-r--r-- | share/man/man9/microtime.9 | 16 | ||||
-rw-r--r-- | sys/kern/kern_tc.c | 46 | ||||
-rw-r--r-- | sys/sys/time.h | 5 |
3 files changed, 62 insertions, 5 deletions
diff --git a/share/man/man9/microtime.9 b/share/man/man9/microtime.9 index fc69d8ae607..f8904c6f6a0 100644 --- a/share/man/man9/microtime.9 +++ b/share/man/man9/microtime.9 @@ -1,4 +1,4 @@ -.\" $OpenBSD: microtime.9,v 1.20 2020/05/20 17:21:07 cheloha Exp $ +.\" $OpenBSD: microtime.9,v 1.21 2020/06/22 21:16:07 cheloha Exp $ .\" $NetBSD: microtime.9,v 1.2 1999/03/16 00:40:47 garbled Exp $ .\" .\" Copyright (c) 1998 The NetBSD Foundation, Inc. @@ -28,7 +28,7 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.Dd $Mdocdate: May 20 2020 $ +.Dd $Mdocdate: June 22 2020 $ .Dt MICROTIME 9 .Os .Sh NAME @@ -46,7 +46,9 @@ .Nm bintime , .Nm binuptime , .Nm binruntime , -.Nm binboottime +.Nm binboottime , +.Nm gettime , +.Nm getuptime .Nd system clocks .Sh SYNOPSIS .In sys/time.h @@ -110,6 +112,14 @@ .Fo binboottime .Fa "struct bintime *tv" .Fc +.Ft time_t +.Fo gettime +.Fa "void" +.Fc +.Ft time_t +.Fo getuptime +.Fa "void" +.Fc .Sh DESCRIPTION This family of functions return different system clocks in various formats. The "uptime" functions return the monotonically increasing time since boot. diff --git a/sys/kern/kern_tc.c b/sys/kern/kern_tc.c index 88d4a3379f9..54d50b1a6f7 100644 --- a/sys/kern/kern_tc.c +++ b/sys/kern/kern_tc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_tc.c,v 1.57 2020/05/29 04:42:25 deraadt Exp $ */ +/* $OpenBSD: kern_tc.c,v 1.58 2020/06/22 21:16:07 cheloha Exp $ */ /* * Copyright (c) 2000 Poul-Henning Kamp <phk@FreeBSD.org> @@ -208,6 +208,28 @@ microuptime(struct timeval *tvp) BINTIME_TO_TIMEVAL(&bt, tvp); } +time_t +getuptime(void) +{ +#if defined(__LP64__) + return time_uptime; /* atomic */ +#else + time_t now; + struct timehands *th; + u_int gen; + + do { + th = timehands; + gen = th->th_generation; + membar_consumer(); + now = th->th_offset.sec; + membar_consumer(); + } while (gen == 0 || gen != th->th_generation); + + return now; +#endif +} + void binruntime(struct bintime *bt) { @@ -268,6 +290,28 @@ microtime(struct timeval *tvp) BINTIME_TO_TIMEVAL(&bt, tvp); } +time_t +gettime(void) +{ +#if defined(__LP64__) + return time_second; /* atomic */ +#else + time_t now; + struct timehands *th; + u_int gen; + + do { + th = timehands; + gen = th->th_generation; + membar_consumer(); + now = th->th_microtime.tv_sec; + membar_consumer(); + } while (gen == 0 || gen != th->th_generation); + + return now; +#endif +} + void getnanouptime(struct timespec *tsp) { diff --git a/sys/sys/time.h b/sys/sys/time.h index e758a64ce07..8d462ce71b7 100644 --- a/sys/sys/time.h +++ b/sys/sys/time.h @@ -1,4 +1,4 @@ -/* $OpenBSD: time.h,v 1.51 2020/05/20 17:21:08 cheloha Exp $ */ +/* $OpenBSD: time.h,v 1.52 2020/06/22 21:16:07 cheloha Exp $ */ /* $NetBSD: time.h,v 1.18 1996/04/23 10:29:33 mycroft Exp $ */ /* @@ -298,6 +298,9 @@ void nanoboottime(struct timespec *); void binruntime(struct bintime *); void nanoruntime(struct timespec *); +time_t gettime(void); +time_t getuptime(void); + struct proc; int clock_gettime(struct proc *, clockid_t, struct timespec *); |