diff options
author | 2020-10-25 00:54:51 +0000 | |
---|---|---|
committer | 2020-10-25 00:54:51 +0000 | |
commit | 018d9bc21737ff29df69832acedefe06041857b4 (patch) | |
tree | f20e5d8e72e510581b83f37a423e514d001b096c /lib/libc | |
parent | needs a Makefile... (diff) | |
download | wireguard-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.2 | 317 |
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 . |