Time
https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/time.h.html
Defines
-
CLOCK_REALTIME (0u)
Settable wall-clock (calendar) time.
At boot it reads the same as CLOCK_MONOTONIC, but it can be set to an arbitrary value with clock_settime() (when the QRT_CFG_CLOCK_SETTIME_ENABLE build option is enabled).
Because it can be set, this clock is not monotonic — setting it may move the time forwards or backwards. A forward jump immediately fires any pending absolute (TIMER_ABSTIME) sleep or timer that the new time has passed; a backward jump never fires one early. Relative sleeps and timers are never affected by setting the clock, even when created with
CLOCK_REALTIME.Use this clock for calendar timestamps and absolute scheduling that should follow clock_settime() changes.
-
CLOCK_MONOTONIC (1u)
Monotonic time since boot.
Counts elapsed time since the system started. It always advances at a steady rate, never jumps, and cannot be set — clock_settime() rejects it with EINVAL — so it is unaffected by any wall-clock change.
Use this clock to measure how much time has elapsed. Query its resolution with clock_getres().
-
TIMER_ABSTIME (0x01)
Absolute time flag.
Functions
-
int clock_getres(clockid_t clock_id, struct timespec *res)
Report the granularity of
clock_idintores.Both CLOCK_MONOTONIC and CLOCK_REALTIME report the same resolution, derived from the frequency of the System Timer.
Error numbers:
EINVAL if
clock_idis neither CLOCK_MONOTONIC nor CLOCK_REALTIME.
- Parameters:
clock_id – Clock identifier.
res – Pointer to a timespec where the resolution will be stored. Can be NULL, in which case the resolution is not stored.
- Returns:
0 on success, or -1 on error.
-
int clock_gettime(clockid_t clock_id, struct timespec *tp)
Read the current value of
clock_idintotp.CLOCK_MONOTONIC reports the time elapsed since boot. CLOCK_REALTIME reports the wall-clock time as last set by clock_settime(). When QRT_CFG_DEFER_ENABLE is enabled the call may also be made from a deferred function or a timer callback (see qrt_defer_call()).
Error numbers:
EINVAL if
tpis NULL orclock_idis not supported.
- Parameters:
clock_id – Clock identifier.
tp – Pointer to a timespec where the current time will be stored.
- Returns:
0 on success, or -1 on error.
-
int clock_settime(clockid_t clock_id, const struct timespec *tp)
Adjust CLOCK_REALTIME so that it currently reads
tp.Error numbers:
EINVAL if
clock_idis not CLOCK_REALTIME.EINVAL if
tpis NULL or has a negative seconds value or nanoseconds outside [0, 999’999’999].EINVAL if
tpis later than the clock can represent (2^62 - 1 System Timer ticks).
- Parameters:
clock_id – Clock identifier.
tp – Pointer to a timespec that specifies the new time for the specified clock.
- Returns:
0 on success, or -1 on error.
-
int clock_nanosleep(clockid_t clock_id, int flags, const struct timespec *rqtp, struct timespec *rmtp)
Block the calling thread for the duration specified by
rqtp, measured onclock_id.With TIMER_ABSTIME,
rqtpis treated as a deadline onclock_id; otherwise it is treated as a relative interval. A deadline that has already passed, one with negative seconds (before the epoch) included, returns 0 at once without suspending the caller. Remaining time is not reported back:rmtpis accepted but ignored.Error numbers:
EINVAL if
rqtpis NULL or has nanoseconds outside [0, 999’999’999].EINVAL if
rqtpis a relative interval with negative seconds.EINVAL if
clock_idis neither CLOCK_MONOTONIC nor CLOCK_REALTIME.
- Parameters:
clock_id – Clock identifier.
flags – Flags to control the behavior of the sleep operation.
TIMER_ABSTIME : the sleep time is interpreted as an absolute time.
rqtp – Pointer to a timespec that specifies the requested sleep duration.
rmtp – Not supported.
- Returns:
0 on success, or error number.
void *periodic_thread(void *arg) { unsigned int *periods = (unsigned int *)arg; struct timespec next; (void)clock_gettime(CLOCK_MONOTONIC, &next); for (;;) { next.tv_nsec += 10000000L; if (next.tv_nsec >= 1000000000L) { next.tv_nsec -= 1000000000L; next.tv_sec++; } (void)clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &next, NULL); (*periods)++; } return NULL; }
-
int nanosleep(const struct timespec *rqtp, struct timespec *rmtp)
Block the calling thread for the relative duration
rqtp.Equivalent to clock_nanosleep() against CLOCK_REALTIME with no flags. Remaining time is not reported back.
Error numbers:
EINVAL if
rqtpis NULL or has a negative seconds value or nanoseconds outside [0, 999’999’999].
- Parameters:
rqtp – Pointer to a timespec that specifies the requested sleep duration.
rmtp – Not supported.
- Returns:
0 on success, or -1 on error.
-
int timer_create(clockid_t clockid, struct sigevent *evp, timer_t *timerid)
Allocate a kernel timer and bind it to an expiration callback.
The timer is allocated from the privileged kernel heap and released by timer_delete(). Signal notification is not supported:
evpmust either request SIGEV_NONE (callback-less timer) or SIGEV_THREAD (invokesigev_notify_functionon expiry).The callback does not run in a thread: the kernel calls it directly on expiry, in the same context as a deferred call, and no thread runs until it returns. It must not block. Of the services declared here it may call only clock_gettime(), timer_gettime() and timer_settime(), and only when QRT_CFG_DEFER_ENABLE is enabled.
Because the callback runs in kernel context, with MPU support only a privileged thread can request SIGEV_THREAD; an unprivileged caller gets EPERM and no timer is created. SIGEV_NONE timers need no privilege.
Note
errno:
EINVAL if the clock ID is invalid.
EINVAL if timerid is NULL.
ENOTSUP if
evpis NULL or specifies an unsupported notification type (e.g. SIGEV_SIGNAL).EPERM if
evprequests SIGEV_THREAD and the caller is unprivileged (only with MPU support).EAGAIN if the limit on the number of existing timers is reached.
ENOMEM if the kernel heap has insufficient memory for the timer.
static timer_t timer; static volatile unsigned int expirations; static void on_expiry(union sigval value) { (void)value; expirations++; } int start_periodic_timer(void) { struct sigevent sev = { .sigev_notify = SIGEV_THREAD, .sigev_notify_function = on_expiry }; struct itimerspec its = { .it_interval = { 0, 10000000L }, .it_value = { 0, 10000000L } }; int status; status = timer_create(CLOCK_MONOTONIC, &sev, &timer); if (status == 0) { status = timer_settime(timer, 0, &its, NULL); } return status; }
- Parameters:
clockid – Clock identifier, CLOCK_MONOTONIC or CLOCK_REALTIME.
evp – Pointer to a sigevent that specifies the event to be delivered when the timer expires.
timerid – Pointer to a
timer_twhere the created timer ID will be stored.
- Returns:
0 on success, -1 on error.
-
int timer_delete(timer_t timerid)
Disarm a timer and return its memory to the kernel heap.
Error numbers:
EINVAL if
timeriddoes not refer to a currently allocated timer.
- Parameters:
timerid – Timer ID to be deleted.
- Returns:
0 on success, -1 on error.
-
int timer_gettime(timer_t timerid, struct itimerspec *value)
Report the time until the next expiration and the configured reload interval of
timerid.A disarmed timer reports zero in
it_value. A non-periodic timer reports zero init_interval. When QRT_CFG_DEFER_ENABLE is enabled the call may also be made from a deferred function or a timer callback (see qrt_defer_call()).Error numbers:
EINVAL if
timeriddoes not refer to a currently allocated timer, orvalueis NULL.
- Parameters:
timerid – Timer ID.
value – Pointer to a itimerspec where the remaining time will be stored.
- Returns:
0 on success, -1 on error and errno set.
-
int timer_settime(timer_t timerid, int flags, const struct itimerspec *value, struct itimerspec *ovalue)
Arm, re-arm, or disarm
timerid.The new configuration in
valueis applied as follows:it_valuezero disarms the timer, with or without TIMER_ABSTIME, whateverit_intervalholds.it_intervalstill sets the reload interval that timer_gettime() reports, zero when it is malformed.Non-zero
it_valuearms a one-shot timer whenit_intervalis zero, or a periodic timer otherwise.With TIMER_ABSTIME,
it_valueis treated as a deadline on the clock chosen at timer_create() time; otherwise it is relative. A deadline that has already passed, one with negative seconds (before the epoch) included, expires at once.
An expiration later than the clock can represent (2^62 - 1 System Timer ticks) is held at that limit, and a periodic timer whose next expiration reaches or passes it is disarmed after its last expiration.
The previous configuration is written to
ovaluewhen it is non-NULL. When QRT_CFG_DEFER_ENABLE is enabled the call may also be made from a deferred function or a timer callback (see qrt_defer_call()).Error numbers:
EINVAL if
timeriddoes not refer to a currently allocated timer, orvalueis NULL.EINVAL if
valuehas a non-zeroit_valueand contains a malformed timespec (nanoseconds outside [0, 999’999’999], or negative seconds init_intervalor in a relativeit_value).
- Parameters:
timerid – Timer ID.
flags – Flags to control the behavior of the timer set operation.
TIMER_ABSTIME : the time is interpreted as an absolute time.
value – Pointer to a itimerspec that specifies the new timer settings.
ovalue – Pointer to a itimerspec where the old timer settings will be stored. Can be NULL if not needed.
- Returns:
0 on success, -1 on error and errno set.
int timeout_restart(timer_t timer) { struct itimerspec one_shot = { .it_value = { 0, 100000000L } }; return timer_settime(timer, 0, &one_shot, NULL); } int timeout_cancel(timer_t timer) { struct itimerspec disarm = { .it_value = { 0, 0 } }; return timer_settime(timer, 0, &disarm, NULL); }
-
struct timespec
- #include <time.h>
Time value expressed as seconds plus nanoseconds.
-
struct itimerspec
- #include <time.h>
Timer setting: initial expiration and reload period.