summaryrefslogtreecommitdiffstats
path: root/lib/libc
diff options
context:
space:
mode:
authorcheloha <cheloha@openbsd.org>2020-10-25 00:54:51 +0000
committercheloha <cheloha@openbsd.org>2020-10-25 00:54:51 +0000
commit018d9bc21737ff29df69832acedefe06041857b4 (patch)
treef20e5d8e72e510581b83f37a423e514d001b096c /lib/libc
parentneeds a Makefile... (diff)
downloadwireguard-openbsd-018d9bc21737ff29df69832acedefe06041857b4.tar.xz
wireguard-openbsd-018d9bc21737ff29df69832acedefe06041857b4.zip
clock_gettime.2: overhaul manpage
The clock_gettime.2 page is clumsy. It will be easier to use if it is reorganized to emphasize clock_gettime(2), a general and widely used interface, over clock_settime(2), a special-purpose and rarely used interface. While doing that I found a bunch of other things I wanted to tweak or improve: - Simplify the NAME summary. No need to mention "calibration" or "date". - "now", "res", and "clock" are better argument names than "tp" and "clock_id". - The CLOCK_* list is a bunch of fragments. Rewrite the list to make it easier to understand what the clocks represent and how they behave. - Mention clock_settime(2) *after* the list of clocks. Almost nobody needs to use it. It shouldn't lead the page alongside clock_gettime(2). - Drop the adjtime(2) reference. We could mention it in a CAVEATS section but it definitely doesn't belong here in the DESCRIPTION. - Drop the useless init(8) reference. - Add a bunch of EXAMPLES demonstrating how to actually use each clock. - Clean up the ERRORS. - Update the cross references. - Add a HISTORY for the interfaces and each clock. High-level structural ideas from jmc@ and schwarze@. Edited by jmc@. ok jmc@, probably ok schwarze@
Diffstat (limited to 'lib/libc')
-rw-r--r--lib/libc/sys/clock_gettime.2317
1 files changed, 241 insertions, 76 deletions
diff --git a/lib/libc/sys/clock_gettime.2 b/lib/libc/sys/clock_gettime.2
index 70fa87c4b7a..796bfd0512d 100644
--- a/lib/libc/sys/clock_gettime.2
+++ b/lib/libc/sys/clock_gettime.2
@@ -1,4 +1,4 @@
-.\" $OpenBSD: clock_gettime.2,v 1.30 2019/01/18 05:27:25 cheloha Exp $
+.\" $OpenBSD: clock_gettime.2,v 1.31 2020/10/25 00:54:51 cheloha Exp $
.\"
.\" Copyright (c) 1980, 1991, 1993
.\" The Regents of the University of California. All rights reserved.
@@ -27,92 +27,224 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd $Mdocdate: January 18 2019 $
+.Dd $Mdocdate: October 25 2020 $
.Dt CLOCK_GETTIME 2
.Os
.Sh NAME
.Nm clock_gettime ,
.Nm clock_settime ,
.Nm clock_getres
-.Nd get/set/calibrate date and time
+.Nd get or set the time
.Sh SYNOPSIS
.In time.h
.Ft int
-.Fn clock_gettime "clockid_t clock_id" "struct timespec *tp"
+.Fn clock_gettime "clockid_t clock" "struct timespec *now"
.Ft int
-.Fn clock_settime "clockid_t clock_id" "const struct timespec *tp"
+.Fn clock_settime "clockid_t clock" "const struct timespec *now"
.Ft int
-.Fn clock_getres "clockid_t clock_id" "struct timespec *tp"
+.Fn clock_getres "clockid_t clock" "struct timespec *res"
.Sh DESCRIPTION
The
.Fn clock_gettime
-and
-.Fn clock_settime
-functions
-allow the calling process to retrieve or set the value used by a clock
-which is specified by
-.Fa clock_id .
-.Pp
-.Fa clock_id
-can be a value from
+function reads the given
+.Fa clock
+and writes its absolute value to
+.Fa now .
+The
+.Fa clock
+may be a value returned by
.Xr clock_getcpuclockid 3
or
.Xr pthread_getcpuclockid 3 ,
-or one of the following predefined values:
+or any of the following constants:
.Bl -tag -width CLOCK_MONOTONIC
.It Dv CLOCK_REALTIME
-time that increments as a wall clock should
-.It Dv CLOCK_PROCESS_CPUTIME_ID
-time that increments when the CPU is running in user or kernel mode
-on behalf of the calling process
-.It Dv CLOCK_THREAD_CPUTIME_ID
-time that increments when the CPU is running in user or kernel mode
-on behalf of the calling thread
+The Coordinated Universal Time
+.Pq UTC
+clock.
+Its absolute value is the time elapsed since
+Jan 1 1970 00:00:00 UTC
+.Pq the Epoch .
+The clock normally advances continuously,
+though it may jump discontinuously if a process calls
+.Xr settimeofday 2
+or
+.Fn clock_settime
+.Pq see below .
.It Dv CLOCK_MONOTONIC
-time that increments as a wall clock should but whose absolute value
-is meaningless and cannot jump,
-providing accurate realtime interval measurement,
-even across suspend and resume
+The monotonic clock.
+Its absolute value is meaningless.
+The clock begins at an undefined positive point and advances continuously.
.It Dv CLOCK_BOOTTIME
-time whose absolute value is the time that has elapsed since the
-system was booted
+The uptime clock.
+Its absolute value is the time elapsed since the system booted.
+The clock begins at zero and advances continuously.
.It Dv CLOCK_UPTIME
-time whose absolute value is the time the system has been running
-and not suspended,
-providing accurate uptime measurement, both absolute and interval
+The runtime clock.
+Its absolute value is the time elapsed since the system booted
+less any time the system was suspended.
+The clock begins at zero and advances while the system is not suspended.
+.It Dv CLOCK_PROCESS_CPUTIME_ID
+The process CPU clock.
+Its absolute value begins at zero and advances while the calling process
+is running in user or kernel mode.
+.It Dv CLOCK_THREAD_CPUTIME_ID
+The thread CPU clock.
+Its absolute value begins at zero and advances while the calling thread
+is running in user or kernel mode.
.El
.Pp
-The structure pointed to by
-.Fa tp
-is defined in
-.In sys/time.h
-as:
+The
+.Fn clock_settime
+function sets the given
+.Fa clock
+to the absolute value
+.Fa now .
+Only the
+.Dv CLOCK_REALTIME
+clock may be set and only the superuser may set it.
+If the system
+.Xr securelevel 7
+is 2 or greater the time may only be advanced.
+This limitation is imposed to prevent a malicious superuser
+from setting arbitrary timestamps on files.
+.Pp
+The
+.Fn clock_getres
+function retrieves the resolution of the given
+.Fa clock
+and writes it to
+.Fa res
+if
+.Fa res
+is
+.Pf non- Dv NULL .
+The
+.Fa clock
+may be any of the clocks accepted by
+.Fn clock_gettime
+as described earlier.
+.Pp
+The
+.Fa now
+and
+.Fa res
+arguments are
+.Dv timespec
+structures as defined in
+.In sys/time.h :
.Bd -literal -offset indent
struct timespec {
time_t tv_sec; /* seconds */
long tv_nsec; /* and nanoseconds */
};
.Ed
-.Pp
-Only the
-.Dv CLOCK_REALTIME
-clock can be set, and only the superuser may do so.
-If the system securelevel is greater than 1 (see
-.Xr init 8 ) ,
-the time may only be advanced.
-This limitation is imposed to prevent a malicious superuser
-from setting arbitrary time stamps on files.
-The system time can still be adjusted backwards using the
-.Xr adjtime 2
-system call even when the system is secure.
-.Pp
-The resolution (granularity) of a clock is returned by the
-.Fn clock_getres
-call.
-This value is placed in a (non-null)
-.Fa *tp .
.Sh RETURN VALUES
.Rv -std
+.Sh EXAMPLES
+Use the
+.Dv CLOCK_REALTIME
+clock to determine the time of day.
+Its absolute value can be passed to functions like
+.Xr gmtime 3
+and
+.Xr strftime 3
+to produce a human-readable string:
+.Bd -literal -offset indent
+char str[64];
+struct timespec now;
+struct tm *tmbuf;
+
+clock_gettime(CLOCK_REALTIME, &now);
+tmbuf = gmtime(&now.tv_sec);
+if (tmbuf == NULL)
+ err(1, "gmtime");
+if (strftime(str, sizeof(str), "%a %b %e %T %Y %Z", tmbuf) == 0)
+ err(1, "strftime");
+printf("%s (%lld.%09ld seconds since the Epoch)\\n",
+ str, (long long)now.tv_sec, now.tv_nsec);
+.Ed
+.Pp
+Use the
+.Dv CLOCK_MONOTONIC
+clock to measure elapsed time.
+The
+.Xr timespecsub 3
+function simplifies arithmetic operations on
+.Dv timespec
+structures:
+.Bd -literal -offset indent
+struct timespec elapsed, start, stop, timeout;
+
+timeout.tv_sec = 2;
+timeout.tv_nsec = 500000000;
+
+clock_gettime(CLOCK_MONOTONIC, &start);
+nanosleep(&timeout, NULL);
+clock_gettime(CLOCK_MONOTONIC, &stop);
+
+timespecsub(&stop, &start, &elapsed);
+printf("nanosleep: expected %lld.%09ld actual %lld.%09ld\\n",
+ (long long)timeout.tv_sec, timeout.tv_nsec,
+ (long long)elapsed.tv_sec, elapsed.tv_nsec);
+.Ed
+.Pp
+Use the
+.Dv CLOCK_PROCESS_CPUTIME_ID
+or
+.Dv CLOCK_THREAD_CPUTIME_ID
+clocks to measure CPU time instead of elapsed time:
+.Bd -literal -offset indent
+struct timespec cputime, start, stop;
+volatile int i;
+
+clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &start);
+for (i = 0; i < INT_MAX; i++)
+ continue;
+clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &stop);
+
+timespecsub(&stop, &start, &cputime);
+printf("CPU time: %lld.%09lds\\n",
+ (long long)cputime.tv_sec, cputime.tv_nsec);
+.Ed
+.Pp
+How much time has elapsed since the system booted?
+Has the system been suspended for any of that time?
+.Bd -literal -offset indent
+struct timespec diff, total, running;
+
+clock_gettime(CLOCK_BOOTTIME, &total);
+clock_gettime(CLOCK_UPTIME, &running);
+timespecsub(&total, &running, &diff);
+
+printf("Seconds since boot: %8lld.%09ld\\n",
+ (long long)total.tv_sec, total.tv_nsec);
+printf("Seconds suspended: %8lld.%09ld\\n",
+ (long long)diff.tv_sec, diff.tv_nsec);
+.Ed
+.Pp
+Set the
+.Dv CLOCK_REALTIME
+clock to Jan 1 00:00:00 2000 UTC:
+.Bd -literal -offset indent
+struct tm y2k;
+struct timespec ts;
+
+y2k.tm_year = 100; /* 2000 */
+y2k.tm_mon = 0; /* January */
+y2k.tm_mday = 1;
+y2k.tm_hour = 0;
+y2k.tm_min = 0;
+y2k.tm_sec = 0;
+
+ts.tv_nsec = 0;
+ts.tv_sec = timegm(&y2k);
+if (ts.tv_sec == -1)
+ err(1, "timegm");
+
+if (clock_settime(CLOCK_REALTIME, &ts) == -1)
+ err(1, "clock_settime");
+.Ed
.Sh ERRORS
.Fn clock_gettime ,
.Fn clock_settime ,
@@ -121,12 +253,14 @@ and
will fail if:
.Bl -tag -width Er
.It Bq Er EINVAL
-.Fa clock_id
-is not a valid value.
-.It Bq Er EFAULT
The
-.Fa tp
-argument address referenced invalid memory.
+.Fa clock
+is invalid.
+.It Bq Er EFAULT
+.Fa now
+or
+.Fa res
+reference invalid memory.
.El
.Pp
In addition,
@@ -136,12 +270,18 @@ may return the following errors:
.It Bq Er EPERM
A user other than the superuser attempted to set the time.
.It Bq Er EINVAL
-.Fa clock_id
-specifies a clock that isn't settable,
-.Fa tp
+The
+.Fa clock
+is not
+.Dv CLOCK_REALTIME .
+.It Bq Er EINVAL
+.Fa now
specifies a nanosecond value less than zero or greater than or equal to
-1000 million,
-or a value outside the range of the specified clock.
+one billion.
+.It Bq Er EINVAL
+.Fa now
+specifies a value outside the range of the given
+.Fa clock .
.El
.Sh SEE ALSO
.Xr date 1 ,
@@ -150,13 +290,17 @@ or a value outside the range of the specified clock.
.Xr gettimeofday 2 ,
.Xr clock_getcpuclockid 3 ,
.Xr ctime 3 ,
-.Xr pthread_getcpuclockid 3
+.Xr pthread_getcpuclockid 3 ,
+.Xr strftime 3 ,
+.Xr time 3 ,
+.Xr timespecadd 3 ,
+.Xr securelevel 7
.Sh STANDARDS
The
-.Fn clock_getres ,
.Fn clock_gettime ,
+.Fn clock_settime ,
and
-.Fn clock_settime
+.Fn clock_getres
functions conform to
.St -p1003.1-2008 .
.Pp
@@ -164,27 +308,48 @@ The
.Dv CLOCK_BOOTTIME
and
.Dv CLOCK_UPTIME
-clocks are extensions to that.
+clocks are extensions to that specification.
.Sh HISTORY
The
+.Fn clock_gettime ,
+.Fn clock_settime ,
+and
+.Fn clock_getres
+functions and the
+.Dv CLOCK_REALTIME
+clock first appeared in
+.St -p1003.1b-93
+and were first available in
+.Ox 2.1 .
+.Pp
+The
+.Dv CLOCK_MONOTONIC
+clock first appeared in
+IEEE Std 1003.1j-2000
+.Pq Qo POSIX.1j Qc
+and was first available in
+.Ox 3.4 .
+.Pp
+The
.Dv CLOCK_PROCESS_CPUTIME_ID
and
.Dv CLOCK_THREAD_CPUTIME_ID
-clocks appeared in
+clocks first appeared in
+IEEE Std 1003.1d-1999
+.Pq Qo POSIX.1d Qc
+and were first available in
.Ox 5.4 .
+.Pp
The
.Dv CLOCK_UPTIME
clock first appeared in
.Fx 7.0
-and was added to
-.Ox
-in
+and was first available in
.Ox 5.5 .
+.Pp
The
.Dv CLOCK_BOOTTIME
clock first appeared in
Linux 2.6.39
-and was added to
-.Ox
-in
+and was first available in
.Ox 6.3 .