916 lines
24 KiB
HTML
916 lines
24 KiB
HTML
|
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
|
<HTML><HEAD><TITLE>Man page of TIMERFD_CREATE</TITLE>
|
|
</HEAD><BODY>
|
|
<H1>TIMERFD_CREATE</H1>
|
|
Section: Linux Programmer's Manual (2)<BR>Updated: 2019-03-06<BR><A HREF="#index">Index</A>
|
|
<A HREF="/cgi-bin/man/man2html">Return to Main Contents</A><HR>
|
|
|
|
<A NAME="lbAB"> </A>
|
|
<H2>NAME</H2>
|
|
|
|
timerfd_create, timerfd_settime, timerfd_gettime -
|
|
timers that notify via file descriptors
|
|
<A NAME="lbAC"> </A>
|
|
<H2>SYNOPSIS</H2>
|
|
|
|
<PRE>
|
|
<B>#include <<A HREF="file:///usr/include/sys/timerfd.h">sys/timerfd.h</A>></B>
|
|
|
|
<B>int timerfd_create(int </B><I>clockid</I><B>, int </B><I>flags</I><B>);</B>
|
|
|
|
<B>int timerfd_settime(int </B><I>fd</I><B>, int </B><I>flags</I><B>,</B>
|
|
<B> const struct itimerspec *</B><I>new_value</I><B>,</B>
|
|
<B> struct itimerspec *</B><I>old_value</I><B>);</B>
|
|
|
|
<B>int timerfd_gettime(int </B><I>fd</I><B>, struct itimerspec *</B><I>curr_value</I><B>);</B>
|
|
</PRE>
|
|
|
|
<A NAME="lbAD"> </A>
|
|
<H2>DESCRIPTION</H2>
|
|
|
|
These system calls create and operate on a timer
|
|
that delivers timer expiration notifications via a file descriptor.
|
|
They provide an alternative to the use of
|
|
<B><A HREF="/cgi-bin/man/man2html?2+setitimer">setitimer</A></B>(2)
|
|
|
|
or
|
|
<B><A HREF="/cgi-bin/man/man2html?2+timer_create">timer_create</A></B>(2),
|
|
|
|
with the advantage that the file descriptor may be monitored by
|
|
<B><A HREF="/cgi-bin/man/man2html?2+select">select</A></B>(2),
|
|
|
|
<B><A HREF="/cgi-bin/man/man2html?2+poll">poll</A></B>(2),
|
|
|
|
and
|
|
<B><A HREF="/cgi-bin/man/man2html?7+epoll">epoll</A></B>(7).
|
|
|
|
<P>
|
|
|
|
The use of these three system calls is analogous to the use of
|
|
<B><A HREF="/cgi-bin/man/man2html?2+timer_create">timer_create</A></B>(2),
|
|
|
|
<B><A HREF="/cgi-bin/man/man2html?2+timer_settime">timer_settime</A></B>(2),
|
|
|
|
and
|
|
<B><A HREF="/cgi-bin/man/man2html?2+timer_gettime">timer_gettime</A></B>(2).
|
|
|
|
(There is no analog of
|
|
<B><A HREF="/cgi-bin/man/man2html?2+timer_getoverrun">timer_getoverrun</A></B>(2),
|
|
|
|
since that functionality is provided by
|
|
<B><A HREF="/cgi-bin/man/man2html?2+read">read</A></B>(2),
|
|
|
|
as described below.)
|
|
|
|
<A NAME="lbAE"> </A>
|
|
<H3>timerfd_create()</H3>
|
|
|
|
<B>timerfd_create</B>()
|
|
|
|
creates a new timer object,
|
|
and returns a file descriptor that refers to that timer.
|
|
The
|
|
<I>clockid</I>
|
|
|
|
argument specifies the clock that is used to mark the progress
|
|
of the timer, and must be one of the following:
|
|
<DL COMPACT>
|
|
<DT id="1"><B>CLOCK_REALTIME</B>
|
|
|
|
<DD>
|
|
A settable system-wide real-time clock.
|
|
<DT id="2"><B>CLOCK_MONOTONIC</B>
|
|
|
|
<DD>
|
|
A nonsettable monotonically increasing clock that measures time
|
|
from some unspecified point in the past that does not change
|
|
after system startup.
|
|
<DT id="3"><B>CLOCK_BOOTTIME</B> (Since Linux 3.15)
|
|
|
|
<DD>
|
|
|
|
Like
|
|
<B>CLOCK_MONOTONIC</B>,
|
|
|
|
this is a monotonically increasing clock.
|
|
However, whereas the
|
|
<B>CLOCK_MONOTONIC</B>
|
|
|
|
clock does not measure the time while a system is suspended, the
|
|
<B>CLOCK_BOOTTIME</B>
|
|
|
|
clock does include the time during which the system is suspended.
|
|
This is useful for applications that need to be suspend-aware.
|
|
<B>CLOCK_REALTIME</B>
|
|
|
|
is not suitable for such applications, since that clock is affected
|
|
by discontinuous changes to the system clock.
|
|
<DT id="4"><B>CLOCK_REALTIME_ALARM</B> (since Linux 3.11)
|
|
|
|
<DD>
|
|
|
|
This clock is like
|
|
<B>CLOCK_REALTIME</B>,
|
|
|
|
but will wake the system if it is suspended.
|
|
The caller must have the
|
|
<B>CAP_WAKE_ALARM</B>
|
|
|
|
capability in order to set a timer against this clock.
|
|
<DT id="5"><B>CLOCK_BOOTTIME_ALARM</B> (since Linux 3.11)
|
|
|
|
<DD>
|
|
|
|
This clock is like
|
|
<B>CLOCK_BOOTTIME</B>,
|
|
|
|
but will wake the system if it is suspended.
|
|
The caller must have the
|
|
<B>CAP_WAKE_ALARM</B>
|
|
|
|
capability in order to set a timer against this clock.
|
|
</DL>
|
|
<P>
|
|
|
|
The current value of each of these clocks can be retrieved using
|
|
<B><A HREF="/cgi-bin/man/man2html?2+clock_gettime">clock_gettime</A></B>(2).
|
|
|
|
<P>
|
|
|
|
Starting with Linux 2.6.27, the following values may be bitwise ORed in
|
|
<I>flags</I>
|
|
|
|
to change the behavior of
|
|
<B>timerfd_create</B>():
|
|
|
|
<DL COMPACT>
|
|
<DT id="6"><B>TFD_NONBLOCK</B>
|
|
|
|
<DD>
|
|
Set the
|
|
<B>O_NONBLOCK</B>
|
|
|
|
file status flag on the open file description (see
|
|
<B><A HREF="/cgi-bin/man/man2html?2+open">open</A></B>(2))
|
|
|
|
referred to by the new file descriptor.
|
|
Using this flag saves extra calls to
|
|
<B><A HREF="/cgi-bin/man/man2html?2+fcntl">fcntl</A></B>(2)
|
|
|
|
to achieve the same result.
|
|
<DT id="7"><B>TFD_CLOEXEC</B>
|
|
|
|
<DD>
|
|
Set the close-on-exec
|
|
(<B>FD_CLOEXEC</B>)
|
|
|
|
flag on the new file descriptor.
|
|
See the description of the
|
|
<B>O_CLOEXEC</B>
|
|
|
|
flag in
|
|
<B><A HREF="/cgi-bin/man/man2html?2+open">open</A></B>(2)
|
|
|
|
for reasons why this may be useful.
|
|
</DL>
|
|
<P>
|
|
|
|
In Linux versions up to and including 2.6.26,
|
|
<I>flags</I>
|
|
|
|
must be specified as zero.
|
|
<A NAME="lbAF"> </A>
|
|
<H3>timerfd_settime()</H3>
|
|
|
|
<B>timerfd_settime</B>()
|
|
|
|
arms (starts) or disarms (stops)
|
|
the timer referred to by the file descriptor
|
|
<I>fd</I>.
|
|
|
|
<P>
|
|
|
|
The
|
|
<I>new_value</I>
|
|
|
|
argument specifies the initial expiration and interval for the timer.
|
|
The
|
|
<I>itimerspec</I>
|
|
|
|
structure used for this argument contains two fields,
|
|
each of which is in turn a structure of type
|
|
<I>timespec</I>:
|
|
|
|
<P>
|
|
|
|
|
|
|
|
struct timespec {
|
|
<BR> time_t tv_sec; /* Seconds */
|
|
<BR> long tv_nsec; /* Nanoseconds */
|
|
};
|
|
<P>
|
|
struct itimerspec {
|
|
<BR> struct timespec it_interval; /* Interval for periodic timer */
|
|
<BR> struct timespec it_value; /* Initial expiration */
|
|
};
|
|
|
|
|
|
<P>
|
|
|
|
<I>new_value.it_value</I>
|
|
|
|
specifies the initial expiration of the timer,
|
|
in seconds and nanoseconds.
|
|
Setting either field of
|
|
<I>new_value.it_value</I>
|
|
|
|
to a nonzero value arms the timer.
|
|
Setting both fields of
|
|
<I>new_value.it_value</I>
|
|
|
|
to zero disarms the timer.
|
|
<P>
|
|
|
|
Setting one or both fields of
|
|
<I>new_value.it_interval</I>
|
|
|
|
to nonzero values specifies the period, in seconds and nanoseconds,
|
|
for repeated timer expirations after the initial expiration.
|
|
If both fields of
|
|
<I>new_value.it_interval</I>
|
|
|
|
are zero, the timer expires just once, at the time specified by
|
|
<I>new_value.it_value</I>.
|
|
|
|
<P>
|
|
|
|
By default,
|
|
the initial expiration time specified in
|
|
<I>new_value</I>
|
|
|
|
is interpreted relative to the current time
|
|
on the timer's clock at the time of the call (i.e.,
|
|
<I>new_value.it_value</I>
|
|
|
|
specifies a time relative to the current value of the clock specified by
|
|
<I>clockid</I>).
|
|
|
|
An absolute timeout can be selected via the
|
|
<I>flags</I>
|
|
|
|
argument.
|
|
<P>
|
|
|
|
The
|
|
<I>flags</I>
|
|
|
|
argument is a bit mask that can include the following values:
|
|
<DL COMPACT>
|
|
<DT id="8"><B>TFD_TIMER_ABSTIME</B>
|
|
|
|
<DD>
|
|
Interpret
|
|
<I>new_value.it_value</I>
|
|
|
|
as an absolute value on the timer's clock.
|
|
The timer will expire when the value of the timer's
|
|
clock reaches the value specified in
|
|
<I>new_value.it_value</I>.
|
|
|
|
<DT id="9"><B>TFD_TIMER_CANCEL_ON_SET</B>
|
|
|
|
<DD>
|
|
If this flag is specified along with
|
|
<B>TFD_TIMER_ABSTIME</B>
|
|
|
|
and the clock for this timer is
|
|
<B>CLOCK_REALTIME</B>
|
|
|
|
or
|
|
<B>CLOCK_REALTIME_ALARM</B>,
|
|
|
|
then mark this timer as cancelable if the real-time clock
|
|
undergoes a discontinuous change
|
|
(<B><A HREF="/cgi-bin/man/man2html?2+settimeofday">settimeofday</A></B>(2),
|
|
|
|
<B><A HREF="/cgi-bin/man/man2html?2+clock_settime">clock_settime</A></B>(2),
|
|
|
|
or similar).
|
|
When such changes occur, a current or future
|
|
<B><A HREF="/cgi-bin/man/man2html?2+read">read</A></B>(2)
|
|
|
|
from the file descriptor will fail with the error
|
|
<B>ECANCELED</B>.
|
|
|
|
</DL>
|
|
<P>
|
|
|
|
If the
|
|
<I>old_value</I>
|
|
|
|
argument is not NULL, then the
|
|
<I>itimerspec</I>
|
|
|
|
structure that it points to is used to return the setting of the timer
|
|
that was current at the time of the call;
|
|
see the description of
|
|
<B>timerfd_gettime</B>()
|
|
|
|
following.
|
|
|
|
<A NAME="lbAG"> </A>
|
|
<H3>timerfd_gettime()</H3>
|
|
|
|
<B>timerfd_gettime</B>()
|
|
|
|
returns, in
|
|
<I>curr_value</I>,
|
|
|
|
an
|
|
<I>itimerspec</I>
|
|
|
|
structure that contains the current setting of the timer
|
|
referred to by the file descriptor
|
|
<I>fd</I>.
|
|
|
|
<P>
|
|
|
|
The
|
|
<I>it_value</I>
|
|
|
|
field returns the amount of time
|
|
until the timer will next expire.
|
|
If both fields of this structure are zero,
|
|
then the timer is currently disarmed.
|
|
This field always contains a relative value, regardless of whether the
|
|
<B>TFD_TIMER_ABSTIME</B>
|
|
|
|
flag was specified when setting the timer.
|
|
<P>
|
|
|
|
The
|
|
<I>it_interval</I>
|
|
|
|
field returns the interval of the timer.
|
|
If both fields of this structure are zero,
|
|
then the timer is set to expire just once, at the time specified by
|
|
<I>curr_value.it_value</I>.
|
|
|
|
<A NAME="lbAH"> </A>
|
|
<H3>Operating on a timer file descriptor</H3>
|
|
|
|
The file descriptor returned by
|
|
<B>timerfd_create</B>()
|
|
|
|
supports the following operations:
|
|
<DL COMPACT>
|
|
<DT id="10"><B><A HREF="/cgi-bin/man/man2html?2+read">read</A></B>(2)
|
|
|
|
<DD>
|
|
If the timer has already expired one or more times since
|
|
its settings were last modified using
|
|
<B>timerfd_settime</B>(),
|
|
|
|
or since the last successful
|
|
<B><A HREF="/cgi-bin/man/man2html?2+read">read</A></B>(2),
|
|
|
|
then the buffer given to
|
|
<B><A HREF="/cgi-bin/man/man2html?2+read">read</A></B>(2)
|
|
|
|
returns an unsigned 8-byte integer
|
|
(<I>uint64_t</I>)
|
|
|
|
containing the number of expirations that have occurred.
|
|
(The returned value is in host byte order---that is,
|
|
the native byte order for integers on the host machine.)
|
|
<DT id="11"><DD>
|
|
If no timer expirations have occurred at the time of the
|
|
<B><A HREF="/cgi-bin/man/man2html?2+read">read</A></B>(2),
|
|
|
|
then the call either blocks until the next timer expiration,
|
|
or fails with the error
|
|
<B>EAGAIN</B>
|
|
|
|
if the file descriptor has been made nonblocking
|
|
(via the use of the
|
|
<B><A HREF="/cgi-bin/man/man2html?2+fcntl">fcntl</A></B>(2)
|
|
|
|
<B>F_SETFL</B>
|
|
|
|
operation to set the
|
|
<B>O_NONBLOCK</B>
|
|
|
|
flag).
|
|
<DT id="12"><DD>
|
|
A
|
|
<B><A HREF="/cgi-bin/man/man2html?2+read">read</A></B>(2)
|
|
|
|
fails with the error
|
|
<B>EINVAL</B>
|
|
|
|
if the size of the supplied buffer is less than 8 bytes.
|
|
<DT id="13"><DD>
|
|
If the associated clock is either
|
|
<B>CLOCK_REALTIME</B>
|
|
|
|
or
|
|
<B>CLOCK_REALTIME_ALARM</B>,
|
|
|
|
the timer is absolute
|
|
(<B>TFD_TIMER_ABSTIME</B>),
|
|
|
|
and the flag
|
|
<B>TFD_TIMER_CANCEL_ON_SET</B>
|
|
|
|
was specified when calling
|
|
<B>timerfd_settime</B>(),
|
|
|
|
then
|
|
<B><A HREF="/cgi-bin/man/man2html?2+read">read</A></B>(2)
|
|
|
|
fails with the error
|
|
<B>ECANCELED</B>
|
|
|
|
if the real-time clock undergoes a discontinuous change.
|
|
(This allows the reading application to discover
|
|
such discontinuous changes to the clock.)
|
|
<DT id="14"><B><A HREF="/cgi-bin/man/man2html?2+poll">poll</A></B>(2), <B><A HREF="/cgi-bin/man/man2html?2+select">select</A></B>(2) (and similar)
|
|
|
|
<DD>
|
|
The file descriptor is readable
|
|
(the
|
|
<B><A HREF="/cgi-bin/man/man2html?2+select">select</A></B>(2)
|
|
|
|
<I>readfds</I>
|
|
|
|
argument; the
|
|
<B><A HREF="/cgi-bin/man/man2html?2+poll">poll</A></B>(2)
|
|
|
|
<B>POLLIN</B>
|
|
|
|
flag)
|
|
if one or more timer expirations have occurred.
|
|
<DT id="15"><DD>
|
|
The file descriptor also supports the other file-descriptor
|
|
multiplexing APIs:
|
|
<B><A HREF="/cgi-bin/man/man2html?2+pselect">pselect</A></B>(2),
|
|
|
|
<B><A HREF="/cgi-bin/man/man2html?2+ppoll">ppoll</A></B>(2),
|
|
|
|
and
|
|
<B><A HREF="/cgi-bin/man/man2html?7+epoll">epoll</A></B>(7).
|
|
|
|
<DT id="16"><B><A HREF="/cgi-bin/man/man2html?2+ioctl">ioctl</A></B>(2)
|
|
|
|
<DD>
|
|
The following timerfd-specific command is supported:
|
|
<DL COMPACT><DT id="17"><DD>
|
|
<DL COMPACT>
|
|
<DT id="18"><B>TFD_IOC_SET_TICKS</B> (since Linux 3.17)
|
|
|
|
<DD>
|
|
|
|
Adjust the number of timer expirations that have occurred.
|
|
The argument is a pointer to a nonzero 8-byte integer
|
|
(<I>uint64_t</I>*)
|
|
|
|
containing the new number of expirations.
|
|
Once the number is set, any waiter on the timer is woken up.
|
|
The only purpose of this command is to restore the expirations
|
|
for the purpose of checkpoint/restore.
|
|
This operation is available only if the kernel was configured with the
|
|
<B>CONFIG_CHECKPOINT_RESTORE</B>
|
|
|
|
option.
|
|
</DL>
|
|
</DL>
|
|
|
|
<DT id="19"><B><A HREF="/cgi-bin/man/man2html?2+close">close</A></B>(2)
|
|
|
|
<DD>
|
|
When the file descriptor is no longer required it should be closed.
|
|
When all file descriptors associated with the same timer object
|
|
have been closed,
|
|
the timer is disarmed and its resources are freed by the kernel.
|
|
|
|
</DL>
|
|
<A NAME="lbAI"> </A>
|
|
<H3><A HREF="/cgi-bin/man/man2html?2+fork">fork</A>(2) semantics</H3>
|
|
|
|
After a
|
|
<B><A HREF="/cgi-bin/man/man2html?2+fork">fork</A></B>(2),
|
|
|
|
the child inherits a copy of the file descriptor created by
|
|
<B>timerfd_create</B>().
|
|
|
|
The file descriptor refers to the same underlying
|
|
timer object as the corresponding file descriptor in the parent,
|
|
and
|
|
<B><A HREF="/cgi-bin/man/man2html?2+read">read</A></B>(2)s
|
|
|
|
in the child will return information about
|
|
expirations of the timer.
|
|
|
|
<A NAME="lbAJ"> </A>
|
|
<H3><A HREF="/cgi-bin/man/man2html?2+execve">execve</A>(2) semantics</H3>
|
|
|
|
A file descriptor created by
|
|
<B>timerfd_create</B>()
|
|
|
|
is preserved across
|
|
<B><A HREF="/cgi-bin/man/man2html?2+execve">execve</A></B>(2),
|
|
|
|
and continues to generate timer expirations if the timer was armed.
|
|
<A NAME="lbAK"> </A>
|
|
<H2>RETURN VALUE</H2>
|
|
|
|
On success,
|
|
<B>timerfd_create</B>()
|
|
|
|
returns a new file descriptor.
|
|
On error, -1 is returned and
|
|
<I>errno</I>
|
|
|
|
is set to indicate the error.
|
|
<P>
|
|
|
|
<B>timerfd_settime</B>()
|
|
|
|
and
|
|
<B>timerfd_gettime</B>()
|
|
|
|
return 0 on success;
|
|
on error they return -1, and set
|
|
<I>errno</I>
|
|
|
|
to indicate the error.
|
|
<A NAME="lbAL"> </A>
|
|
<H2>ERRORS</H2>
|
|
|
|
<B>timerfd_create</B>()
|
|
|
|
can fail with the following errors:
|
|
<DL COMPACT>
|
|
<DT id="20"><B>EINVAL</B>
|
|
|
|
<DD>
|
|
The
|
|
<I>clockid</I>
|
|
|
|
argument is neither
|
|
<B>CLOCK_MONOTONIC</B>
|
|
|
|
nor
|
|
<B>CLOCK_REALTIME</B>;
|
|
|
|
<DT id="21"><B>EINVAL</B>
|
|
|
|
<DD>
|
|
<I>flags</I>
|
|
|
|
is invalid;
|
|
or, in Linux 2.6.26 or earlier,
|
|
<I>flags</I>
|
|
|
|
is nonzero.
|
|
<DT id="22"><B>EMFILE</B>
|
|
|
|
<DD>
|
|
The per-process limit on the number of open file descriptors has been reached.
|
|
<DT id="23"><B>ENFILE</B>
|
|
|
|
<DD>
|
|
The system-wide limit on the total number of open files has been
|
|
reached.
|
|
<DT id="24"><B>ENODEV</B>
|
|
|
|
<DD>
|
|
Could not mount (internal) anonymous inode device.
|
|
<DT id="25"><B>ENOMEM</B>
|
|
|
|
<DD>
|
|
There was insufficient kernel memory to create the timer.
|
|
</DL>
|
|
<P>
|
|
|
|
<B>timerfd_settime</B>()
|
|
|
|
and
|
|
<B>timerfd_gettime</B>()
|
|
|
|
can fail with the following errors:
|
|
<DL COMPACT>
|
|
<DT id="26"><B>EBADF</B>
|
|
|
|
<DD>
|
|
<I>fd</I>
|
|
|
|
is not a valid file descriptor.
|
|
<DT id="27"><B>EFAULT</B>
|
|
|
|
<DD>
|
|
<I>new_value</I>,
|
|
|
|
<I>old_value</I>,
|
|
|
|
or
|
|
<I>curr_value</I>
|
|
|
|
is not valid a pointer.
|
|
<DT id="28"><B>EINVAL</B>
|
|
|
|
<DD>
|
|
<I>fd</I>
|
|
|
|
is not a valid timerfd file descriptor.
|
|
</DL>
|
|
<P>
|
|
|
|
<B>timerfd_settime</B>()
|
|
|
|
can also fail with the following errors:
|
|
<DL COMPACT>
|
|
<DT id="29"><B>EINVAL</B>
|
|
|
|
<DD>
|
|
<I>new_value</I>
|
|
|
|
is not properly initialized (one of the
|
|
<I>tv_nsec</I>
|
|
|
|
falls outside the range zero to 999,999,999).
|
|
<DT id="30"><B>EINVAL</B>
|
|
|
|
<DD>
|
|
|
|
|
|
<I>flags</I>
|
|
|
|
is invalid.
|
|
</DL>
|
|
<A NAME="lbAM"> </A>
|
|
<H2>VERSIONS</H2>
|
|
|
|
These system calls are available on Linux since kernel 2.6.25.
|
|
Library support is provided by glibc since version 2.8.
|
|
<A NAME="lbAN"> </A>
|
|
<H2>CONFORMING TO</H2>
|
|
|
|
These system calls are Linux-specific.
|
|
<A NAME="lbAO"> </A>
|
|
<H2>BUGS</H2>
|
|
|
|
Currently,
|
|
|
|
<B>timerfd_create</B>()
|
|
|
|
supports fewer types of clock IDs than
|
|
<B><A HREF="/cgi-bin/man/man2html?2+timer_create">timer_create</A></B>(2).
|
|
|
|
<A NAME="lbAP"> </A>
|
|
<H2>EXAMPLE</H2>
|
|
|
|
The following program creates a timer and then monitors its progress.
|
|
The program accepts up to three command-line arguments.
|
|
The first argument specifies the number of seconds for
|
|
the initial expiration of the timer.
|
|
The second argument specifies the interval for the timer, in seconds.
|
|
The third argument specifies the number of times the program should
|
|
allow the timer to expire before terminating.
|
|
The second and third command-line arguments are optional.
|
|
<P>
|
|
|
|
The following shell session demonstrates the use of the program:
|
|
<P>
|
|
|
|
|
|
|
|
$<B> a.out 3 1 100</B>
|
|
|
|
0.000: timer started
|
|
3.000: read: 1; total=1
|
|
4.000: read: 1; total=2
|
|
<B>^Z </B> # type control-Z to suspend the program
|
|
|
|
[1]+ Stopped ./timerfd3_demo 3 1 100
|
|
$ <B>fg</B> # Resume execution after a few seconds
|
|
|
|
a.out 3 1 100
|
|
9.660: read: 5; total=7
|
|
10.000: read: 1; total=8
|
|
11.000: read: 1; total=9
|
|
<B>^C </B> # type control-C to suspend the program
|
|
|
|
|
|
|
|
<A NAME="lbAQ"> </A>
|
|
<H3>Program source</H3>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include <<A HREF="file:///usr/include/sys/timerfd.h">sys/timerfd.h</A>>
|
|
#include <<A HREF="file:///usr/include/time.h">time.h</A>>
|
|
#include <<A HREF="file:///usr/include/unistd.h">unistd.h</A>>
|
|
#include <<A HREF="file:///usr/include/stdlib.h">stdlib.h</A>>
|
|
#include <<A HREF="file:///usr/include/stdio.h">stdio.h</A>>
|
|
#include <<A HREF="file:///usr/include/stdint.h">stdint.h</A>> /* Definition of uint64_t */
|
|
<P>
|
|
#define handle_error(msg) \
|
|
<BR> do { perror(msg); exit(EXIT_FAILURE); } while (0)
|
|
<P>
|
|
static void
|
|
print_elapsed_time(void)
|
|
{
|
|
<BR> static struct timespec start;
|
|
<BR> struct timespec curr;
|
|
<BR> static int first_call = 1;
|
|
<BR> int secs, nsecs;
|
|
<P>
|
|
<BR> if (first_call) {
|
|
<BR> first_call = 0;
|
|
<BR> if (clock_gettime(CLOCK_MONOTONIC, &start) == -1)
|
|
<BR> handle_error("clock_gettime");
|
|
<BR> }
|
|
<P>
|
|
<BR> if (clock_gettime(CLOCK_MONOTONIC, &curr) == -1)
|
|
<BR> handle_error("clock_gettime");
|
|
<P>
|
|
<BR> secs = curr.tv_sec - start.tv_sec;
|
|
<BR> nsecs = curr.tv_nsec - start.tv_nsec;
|
|
<BR> if (nsecs < 0) {
|
|
<BR> secs--;
|
|
<BR> nsecs += 1000000000;
|
|
<BR> }
|
|
<BR> printf("%d.%03d: ", secs, (nsecs + 500000) / 1000000);
|
|
}
|
|
<P>
|
|
int
|
|
main(int argc, char *argv[])
|
|
{
|
|
<BR> struct itimerspec new_value;
|
|
<BR> int max_exp, fd;
|
|
<BR> struct timespec now;
|
|
<BR> uint64_t exp, tot_exp;
|
|
<BR> ssize_t s;
|
|
<P>
|
|
<BR> if ((argc != 2) && (argc != 4)) {
|
|
<BR> fprintf(stderr, "%s init-secs [interval-secs max-exp]\n",
|
|
<BR> argv[0]);
|
|
<BR> exit(EXIT_FAILURE);
|
|
<BR> }
|
|
<P>
|
|
<BR> if (clock_gettime(CLOCK_REALTIME, &now) == -1)
|
|
<BR> handle_error("clock_gettime");
|
|
<P>
|
|
<BR> /* Create a CLOCK_REALTIME absolute timer with initial
|
|
<BR> expiration and interval as specified in command line */
|
|
<P>
|
|
<BR> new_value.it_value.tv_sec = now.tv_sec + atoi(argv[1]);
|
|
<BR> new_value.it_value.tv_nsec = now.tv_nsec;
|
|
<BR> if (argc == 2) {
|
|
<BR> new_value.it_interval.tv_sec = 0;
|
|
<BR> max_exp = 1;
|
|
<BR> } else {
|
|
<BR> new_value.it_interval.tv_sec = atoi(argv[2]);
|
|
<BR> max_exp = atoi(argv[3]);
|
|
<BR> }
|
|
<BR> new_value.it_interval.tv_nsec = 0;
|
|
<P>
|
|
<BR> fd = timerfd_create(CLOCK_REALTIME, 0);
|
|
<BR> if (fd == -1)
|
|
<BR> handle_error("timerfd_create");
|
|
<P>
|
|
<BR> if (timerfd_settime(fd, TFD_TIMER_ABSTIME, &new_value, NULL) == -1)
|
|
<BR> handle_error("timerfd_settime");
|
|
<P>
|
|
<BR> print_elapsed_time();
|
|
<BR> printf("timer started\n");
|
|
<P>
|
|
<BR> for (tot_exp = 0; tot_exp < max_exp;) {
|
|
<BR> s = read(fd, &exp, sizeof(uint64_t));
|
|
<BR> if (s != sizeof(uint64_t))
|
|
<BR> handle_error("read");
|
|
<P>
|
|
<BR> tot_exp += exp;
|
|
<BR> print_elapsed_time();
|
|
<BR> printf("read: %llu; total=%llu\n",
|
|
<BR> (unsigned long long) exp,
|
|
<BR> (unsigned long long) tot_exp);
|
|
<BR> }
|
|
<P>
|
|
<BR> exit(EXIT_SUCCESS);
|
|
}
|
|
|
|
<A NAME="lbAR"> </A>
|
|
<H2>SEE ALSO</H2>
|
|
|
|
<B><A HREF="/cgi-bin/man/man2html?2+eventfd">eventfd</A></B>(2),
|
|
|
|
<B><A HREF="/cgi-bin/man/man2html?2+poll">poll</A></B>(2),
|
|
|
|
<B><A HREF="/cgi-bin/man/man2html?2+read">read</A></B>(2),
|
|
|
|
<B><A HREF="/cgi-bin/man/man2html?2+select">select</A></B>(2),
|
|
|
|
<B><A HREF="/cgi-bin/man/man2html?2+setitimer">setitimer</A></B>(2),
|
|
|
|
<B><A HREF="/cgi-bin/man/man2html?2+signalfd">signalfd</A></B>(2),
|
|
|
|
<B><A HREF="/cgi-bin/man/man2html?2+timer_create">timer_create</A></B>(2),
|
|
|
|
<B><A HREF="/cgi-bin/man/man2html?2+timer_gettime">timer_gettime</A></B>(2),
|
|
|
|
<B><A HREF="/cgi-bin/man/man2html?2+timer_settime">timer_settime</A></B>(2),
|
|
|
|
<B><A HREF="/cgi-bin/man/man2html?7+epoll">epoll</A></B>(7),
|
|
|
|
<B><A HREF="/cgi-bin/man/man2html?7+time">time</A></B>(7)
|
|
|
|
<A NAME="lbAS"> </A>
|
|
<H2>COLOPHON</H2>
|
|
|
|
This page is part of release 5.05 of the Linux
|
|
<I>man-pages</I>
|
|
|
|
project.
|
|
A description of the project,
|
|
information about reporting bugs,
|
|
and the latest version of this page,
|
|
can be found at
|
|
<A HREF="https://www.kernel.org/doc/man-pages/.">https://www.kernel.org/doc/man-pages/.</A>
|
|
<P>
|
|
|
|
<HR>
|
|
<A NAME="index"> </A><H2>Index</H2>
|
|
<DL>
|
|
<DT id="31"><A HREF="#lbAB">NAME</A><DD>
|
|
<DT id="32"><A HREF="#lbAC">SYNOPSIS</A><DD>
|
|
<DT id="33"><A HREF="#lbAD">DESCRIPTION</A><DD>
|
|
<DL>
|
|
<DT id="34"><A HREF="#lbAE">timerfd_create()</A><DD>
|
|
<DT id="35"><A HREF="#lbAF">timerfd_settime()</A><DD>
|
|
<DT id="36"><A HREF="#lbAG">timerfd_gettime()</A><DD>
|
|
<DT id="37"><A HREF="#lbAH">Operating on a timer file descriptor</A><DD>
|
|
<DT id="38"><A HREF="#lbAI">fork(2) semantics</A><DD>
|
|
<DT id="39"><A HREF="#lbAJ">execve(2) semantics</A><DD>
|
|
</DL>
|
|
<DT id="40"><A HREF="#lbAK">RETURN VALUE</A><DD>
|
|
<DT id="41"><A HREF="#lbAL">ERRORS</A><DD>
|
|
<DT id="42"><A HREF="#lbAM">VERSIONS</A><DD>
|
|
<DT id="43"><A HREF="#lbAN">CONFORMING TO</A><DD>
|
|
<DT id="44"><A HREF="#lbAO">BUGS</A><DD>
|
|
<DT id="45"><A HREF="#lbAP">EXAMPLE</A><DD>
|
|
<DL>
|
|
<DT id="46"><A HREF="#lbAQ">Program source</A><DD>
|
|
</DL>
|
|
<DT id="47"><A HREF="#lbAR">SEE ALSO</A><DD>
|
|
<DT id="48"><A HREF="#lbAS">COLOPHON</A><DD>
|
|
</DL>
|
|
<HR>
|
|
This document was created by
|
|
<A HREF="/cgi-bin/man/man2html">man2html</A>,
|
|
using the manual pages.<BR>
|
|
Time: 00:05:35 GMT, March 31, 2021
|
|
</BODY>
|
|
</HTML>
|