]> git.ipfire.org Git - thirdparty/man-pages.git/commitdiff
Describes timerfd_create(), timerfd_settime(), and timerfd_gettime(),
authorMichael Kerrisk <mtk.manpages@gmail.com>
Tue, 12 Feb 2008 14:32:46 +0000 (14:32 +0000)
committerMichael Kerrisk <mtk.manpages@gmail.com>
Tue, 12 Feb 2008 14:32:46 +0000 (14:32 +0000)
new in 2.6.2.25.

man2/timerfd_create.2 [new file with mode: 0644]

diff --git a/man2/timerfd_create.2 b/man2/timerfd_create.2
new file mode 100644 (file)
index 0000000..8245c09
--- /dev/null
@@ -0,0 +1,508 @@
+.\" Copyright (C) 2008 Michael Kerrisk <mtk.manpages@gmail.com>
+.\"
+.\" This program is free software; you can redistribute it and/or modify
+.\" it under the terms of the GNU General Public License as published by
+.\" the Free Software Foundation; either version 2 of the License, or
+.\" (at your option) any later version.
+.\"
+.\" This program is distributed in the hope that it will be useful,
+.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
+.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+.\" GNU General Public License for more details.
+.\"
+.\" You should have received a copy of the GNU General Public License
+.\" along with this program; if not, write to the Free Software
+.\" Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+.\" MA  02111-1307  USA
+.\"
+.TH TIMERFD_CREATE 2 2008-02-19 Linux "Linux Programmer's Manual"
+.SH NAME
+timerfd_create, timerfd_settime, timerfd_gettime \-
+timers that notify via file descriptors
+.SH SYNOPSIS
+.\" FIXME verify that this is the right header file in glibc
+.nf
+.B #include <sys/timerfd.h>
+.sp
+.BI "int timerfd_create(int " clockid ", int " flags );
+.sp
+.BI "int timerfd_settime(int " fd ", int " flags ,
+.BI "                    const struct itimerspec *" new_value ,
+.BI "                    struct itimerspec *" curr_value );
+.sp
+.BI "int timerfd_gettime(int " fd ", struct itimerspec *" curr_value );
+.fi
+.SH DESCRIPTION
+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
+.BR setitimer (2)
+or
+.BR timer_create (3),
+with the advantage that the file descriptor may be monitored by
+.BR select (2),
+.BR poll (2),
+and
+.BR epoll (7).
+
+The use of these three system calls is analogous to the use of
+.BR timer_create (3),
+.BR timer_settime (3),
+and
+.BR timer_gettime (3).
+(There is no analog of
+.BR timer_gettoverrun (3),
+since that functionality is provided by
+.BR read (2),
+as described below.)
+.\"
+.SS timerfd_create()
+.BR timerfd_create ()
+creates a new timer object,
+and returns a file descriptor that refers to that timer.
+The
+.I clockid
+argument specifies the clock that is used to mark the progress
+of the timer, and must be either
+.B CLOCK_REALTIME
+or
+.BR CLOCK_MONOTONIC .
+.B CLOCK_REALTIME
+is a settable system-wide clock.
+.B CLOCK_MONOTONIC
+is a non-settable clock that is not affected
+by discontinuous changes in the system clock
+(e.g., manual changes to system time).
+The current value of each of these clocks can be retrieved using
+.BR clock_gettime (3).
+
+The
+.I flags
+argument is reserved for future use.
+.\" Eventually it will probably allow O_CLOEXEC and maybe O_NONBLOCK.
+As at Linux 2.6.25, this argument must be specified as zero.
+.\"
+.SS timerfd_settime()
+.BR timerfd_settime ()
+arms (starts) or disarms (stops)
+the timer referred to by the file descriptor
+.IR fd .
+
+The
+.I new_value
+argument specifies the initial expiration and interval for the timer.
+The
+.I itimer
+structure used for this argument contains two fields,
+each of which is in turn a structure of type
+.IR timespec :
+.in +4n
+.nf
+
+struct timespec {
+    time_t tv_sec;                /* Seconds */
+    long   tv_nsec;               /* Nanoseconds */
+};
+
+struct itimerspec {
+    struct timespec it_interval;  /* Interval for periodic timer */
+    struct timespec it_value;     /* Initial expiration */
+};
+.fi
+.in
+.PP
+.I new_value.it_value
+specifies the initial expiration of the timer,
+in seconds and nanoseconds.
+Setting either field of
+.I new_value.it_value
+to a nonzero value arms the timer.
+Setting both fields of
+.I new_value.it_value
+to zero disarms the timer.
+
+Setting one or both fields of
+.I new_value.it_interval
+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
+are zero, the timer expires just once, at the time specified by
+.IR new_value.it_value .
+
+The
+.I flags
+argument is either 0, to start a relative timer
+.RI ( new_value.it_interval
+specifies a time relative to the current value of the clock specified by
+.IR clockid ),
+or
+.BR TFD_TIMER_ABSTIME ,
+to start an absolute timer
+.RI ( new_value.it_interval
+specifies an absolute time for the clock specified by
+.IR clockid ;
+that is, the timer will expire when the value of that
+clock reaches the value specified in
+.IR new_value.it_interval ).
+
+The
+.I curr_value
+argument returns a structure containing the setting of the timer that
+was current at the time of the call; see the description of
+.BR timerfd_gettime ()
+following.
+.\"
+.SS timerfd_gettime()
+.BR timerfd_gettime ()
+returns, in
+.IR curr_value ,
+an
+.IR itimerspec
+that contains the current setting of the timer
+referred to by the file descriptor
+.IR fd .
+
+The
+.I it_value
+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
+.BR TFD_TIMER_ABSTIME
+flag was specified when setting the timer.
+
+The
+.I it_interval
+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
+.IR curr_value.it_value .
+.SS Operating on a timer file descriptor
+The file descriptor returned by
+.BR timerfd_create ()
+supports the following operations:
+.TP
+.BR read (2)
+If the timer has already expired one or more times since
+its settings were last modified using
+.BR timerfd_settime (),
+or since the last successful
+.BR read (2),
+then the buffer given to
+.BR read (2)
+returns an unsigned 8-byte integer
+.RI ( uint64_t )
+containing the number of expirations that have occurred.
+(The returned value is in host byte order,
+i.e., the native byte order for integers on the host machine.)
+.IP
+If no timer expirations have occurred at the time of the
+.BR read (2),
+then the call either blocks until the next timer expiration,
+or fails with the error
+.B EAGAIN
+if the file descriptor has been made non-blocking
+(via the use of the
+.BR fcntl (2)
+.B F_SETFL
+operation to set the
+.B O_NONBLOCK
+flag).
+.IP
+A
+.BR read (2)
+will fail with the error
+.B EINVAL
+if the size of the supplied buffer is less than 8 bytes.
+.TP
+.BR poll "(2), " select "(2) (and similar)"
+The file descriptor is readable
+(the
+.BR select (2)
+.I readfds
+argument; the
+.BR poll (2)
+.B POLLIN
+flag)
+if one or more timer expirations have occurred.
+.IP
+The file descriptor also supports the other file-descriptor
+multiplexing APIs:
+.BR pselect (2),
+.BR ppoll (2),
+and
+.BR epoll (7).
+.TP
+.BR close (2)
+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.
+.\"
+.SS fork(2) semantics
+After a
+.BR fork (2),
+the child inherits a copy of the file descriptor created by
+.BR timerfd_create ().
+The file descriptor refers to the same underlying
+timer object as the corresponding file descriptor in the parent,
+and
+.BR read (2)s
+in the child will return information about
+expirations of the timer.
+.\"
+.SS execve(2) semantics
+A file descriptor created by
+.BR timerfd_create ()
+is preserved across
+.BR execve (2),
+and continues to generate timer expirations if the timer was armed.
+.SH "RETURN VALUE"
+On success,
+.BR timerfd_create ()
+returns a new file descriptor.
+On error, \-1 is returned and
+.I errno
+is set to indicate the error.
+
+.BR timerfd_settime ()
+and
+.BR timerfd_gettime ()
+return 0 on success;
+on error they return \-1, and set
+.I errno
+to indicate the error.
+.SH ERRORS
+.BR timerfd_create ()
+can fail with the following errors:
+.TP
+.B EINVAL
+The
+.I clockid
+argument is neither
+.B CLOCK_MONOTONIC
+nor
+.BR CLOCK_REALTIME ;
+or
+.I flags
+is invalid.
+.TP
+.B EMFILE
+The per-process limit of open file descriptors has been reached.
+.TP
+.B ENFILE
+The system-wide limit on the total number of open files has been
+reached.
+.TP
+.B ENODEV
+Could not mount (internal) anonymous inode device.
+.TP
+.B ENOMEM
+There was insufficient kernel memory to create the timer.
+.PP
+.BR timerfd_settime ()
+and
+.BR timerfd_gettime ()
+can fail with the following errors:
+.TP
+.B EBADF
+.I fd
+is not a valid file descriptor.
+.TP
+.B EINVAL
+.I fd
+is not a valid timerfd file descriptor.
+.I new_value
+is not properly initialized (one of the
+.I tv_nsec
+falls outside the range zero to 999,999,999).
+.SH VERSIONS
+These system calls are available on Linux since kernel 2.6.25.
+.\" FIXME . check later to see when glibc support is provided
+As at February 2008 (glibc 2.7), the details of the glibc interface
+have not been finalized, so that, for example,
+the eventual header file may be different from that shown on this page.
+.SH CONFORMING TO
+These system calls are Linux-specific.
+.SH EXAMPLE
+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.
+
+The following shell session demonstrates the use of the program:
+.in +4n
+.nf
+
+$ a.out 3 1 100
+0.000: timer started
+3.000: read: 1; total=1
+4.000: read: 1; total=2
+[type control-Z to suspend the program]
+[1]+  Stopped                 ./timerfd3_demo 3 1 100
+$ fg                # 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
+[type control-C to terminate the program]
+.fi
+.in
+.nf
+
+.\" FIXME . Check later what header file glibc uses for timerfd
+.\"
+.\" The commented out code here is what we currently need until
+.\" the required stuff is in glibc
+.\"
+.\"
+.\"/* Link with -lrt */
+.\"#define _GNU_SOURCE
+.\"#include <sys/syscall.h>
+.\"#include <unistd.h>
+.\"#include <time.h>
+.\"#if defined(__i386__)
+.\"#define __NR_timerfd_create 322
+.\"#define __NR_timerfd_settime 325
+.\"#define __NR_timerfd_gettime 326
+.\"#endif
+.\"
+.\"static int
+.\"timerfd_create(int clockid, int flags)
+.\"{
+.\"    return syscall(__NR_timerfd_create, clockid, flags);
+.\"}
+.\"
+.\"static int
+.\"timerfd_settime(int fd, int flags, struct itimerspec *new_value,
+.\"        struct itimerspec *curr_value)
+.\"{
+.\"    return syscall(__NR_timerfd_settime, fd, flags, new_value,
+.\"                   curr_value);
+.\"}
+.\"
+.\"static int
+.\"timerfd_gettime(int fd, struct itimerspec *curr_value)
+.\"{
+.\"    return syscall(__NR_timerfd_gettime, fd, curr_value);
+.\"}
+.\"
+.\"#define TFD_TIMER_ABSTIME (1 << 0)
+.\"
+.\"////////////////////////////////////////////////////////////
+.\" FIXME verify that this is the right header file in glibc
+#include <sys/timerfd.h>
+#include <time.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdint.h>        /* Definition of uint64_t */
+
+#define handle_error(msg) \\
+        do { perror(msg); exit(EXIT_FAILURE); } while (0)
+
+static void
+print_elapsed_time(void)
+{
+    static struct timespec start;
+    struct timespec curr;
+    static int first_call = 1;
+    int secs, nsecs;
+
+    if (first_call) {
+        first_call = 0;
+        if (clock_gettime(CLOCK_MONOTONIC, &start) == \-1)
+            handle_error("clock_gettime");
+    }
+
+    if (clock_gettime(CLOCK_MONOTONIC, &curr) == \-1)
+        handle_error("clock_gettime");
+
+    secs = curr.tv_sec \- start.tv_sec;
+    nsecs = curr.tv_nsec \- start.tv_nsec;
+    if (nsecs < 0) {
+        secs\-\-;
+        nsecs += 1000000000;
+    }
+    printf("%d.%03d: ", secs, (nsecs + 500000) / 1000000);
+}
+
+int
+main(int argc, char *argv[])
+{
+    struct itimerspec new_value;
+    int max_exp, fd;
+    struct timespec now;
+    uint64_t exp, tot_exp;
+    ssize_t s;
+
+    if ((argc != 2) && (argc != 4)) {
+        fprintf(stderr, "%s init\-secs [interval\-secs max\-exp]\\n",
+                argv[0]);
+        exit(EXIT_FAILURE);
+    }
+
+    if (clock_gettime(CLOCK_REALTIME, &now) == \-1)
+        handle_error("clock_gettime");
+
+    /* Create a CLOCK_REALTIME absolute timer with initial
+       expiration and interval as specified in command line */
+
+    new_value.it_value.tv_sec = now.tv_sec + atoi(argv[1]);
+    new_value.it_value.tv_nsec = now.tv_nsec;
+    if (argc == 2) {
+        new_value.it_interval.tv_sec = 0;
+        max_exp = 1;
+    } else {
+        new_value.it_interval.tv_sec = atoi(argv[2]);
+        max_exp = atoi(argv[3]);
+    }
+    new_value.it_interval.tv_nsec = 0;
+
+    fd = timerfd_create(CLOCK_REALTIME, 0);
+    if (fd == \-1)
+        handle_error("timerfd_create");
+
+    s = timerfd_settime(fd, TFD_TIMER_ABSTIME, &new_value, NULL);
+    if (s == \-1)
+        handle_error("timerfd_settime");
+
+    print_elapsed_time();
+    printf("timer started\\n");
+
+    for (tot_exp = 0; tot_exp < max_exp;) {
+        s = read(fd, &exp, sizeof(uint64_t));
+        if (s != sizeof(uint64_t))
+            handle_error("read");
+
+        tot_exp += exp;
+        print_elapsed_time();
+        printf("read: %llu; total=%llu\\n",
+                (unsigned long long) exp,
+                (unsigned long long) tot_exp);
+    }
+
+    exit(EXIT_SUCCESS);
+}
+.fi
+.SH "SEE ALSO"
+.BR eventfd (2),
+.BR poll (2),
+.BR read (2),
+.BR select (2),
+.BR setitimer (2),
+.BR signalfd (2),
+.BR timer_create (3),
+.BR timer_gettime (3),
+.BR timer_settime (3),
+.BR epoll (7),
+.BR time (7)
+.\" FIXME Create links for timerfd_settime.2 and timerfd_gettime.2.
+.\" FIXME have SEE ALSO in setitimer.2 refer to this page.
+.\" FIXME have SEE ALSO in time.7 refer to this page.