356 lines
8.4 KiB
Groff
356 lines
8.4 KiB
Groff
.\" $OpenBSD: clock_gettime.2,v 1.32 2022/03/31 17:27:16 naddy Exp $
|
|
.\"
|
|
.\" Copyright (c) 1980, 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.
|
|
.\"
|
|
.Dd $Mdocdate: March 31 2022 $
|
|
.Dt CLOCK_GETTIME 2
|
|
.Os
|
|
.Sh NAME
|
|
.Nm clock_gettime ,
|
|
.Nm clock_settime ,
|
|
.Nm clock_getres
|
|
.Nd get or set the time
|
|
.Sh SYNOPSIS
|
|
.In time.h
|
|
.Ft int
|
|
.Fn clock_gettime "clockid_t clock" "struct timespec *now"
|
|
.Ft int
|
|
.Fn clock_settime "clockid_t clock" "const struct timespec *now"
|
|
.Ft int
|
|
.Fn clock_getres "clockid_t clock" "struct timespec *res"
|
|
.Sh DESCRIPTION
|
|
The
|
|
.Fn clock_gettime
|
|
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 any of the following constants:
|
|
.Bl -tag -width CLOCK_MONOTONIC
|
|
.It Dv CLOCK_REALTIME
|
|
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
|
|
The monotonic clock.
|
|
Its absolute value is meaningless.
|
|
The clock begins at an undefined positive point and advances continuously.
|
|
.It Dv CLOCK_BOOTTIME
|
|
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
|
|
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
|
|
.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
|
|
.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 ,
|
|
and
|
|
.Fn clock_getres
|
|
will fail if:
|
|
.Bl -tag -width Er
|
|
.It Bq Er EINVAL
|
|
The
|
|
.Fa clock
|
|
is invalid.
|
|
.It Bq Er EFAULT
|
|
.Fa now
|
|
or
|
|
.Fa res
|
|
reference invalid memory.
|
|
.El
|
|
.Pp
|
|
In addition,
|
|
.Fn clock_settime
|
|
may return the following errors:
|
|
.Bl -tag -width Er
|
|
.It Bq Er EPERM
|
|
A user other than the superuser attempted to set the time.
|
|
.It Bq Er EINVAL
|
|
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
|
|
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 ,
|
|
.Xr adjtime 2 ,
|
|
.Xr getitimer 2 ,
|
|
.Xr gettimeofday 2 ,
|
|
.Xr clock_getcpuclockid 3 ,
|
|
.Xr ctime 3 ,
|
|
.Xr pthread_getcpuclockid 3 ,
|
|
.Xr strftime 3 ,
|
|
.Xr time 3 ,
|
|
.Xr timespecadd 3 ,
|
|
.Xr securelevel 7
|
|
.Sh STANDARDS
|
|
The
|
|
.Fn clock_gettime ,
|
|
.Fn clock_settime ,
|
|
and
|
|
.Fn clock_getres
|
|
functions conform to
|
|
.St -p1003.1-2008 .
|
|
.Pp
|
|
The
|
|
.Dv CLOCK_BOOTTIME
|
|
and
|
|
.Dv CLOCK_UPTIME
|
|
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 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 first available in
|
|
.Ox 5.5 .
|
|
.Pp
|
|
The
|
|
.Dv CLOCK_BOOTTIME
|
|
clock first appeared in
|
|
Linux 2.6.39
|
|
and was first available in
|
|
.Ox 6.3 .
|