diff options
author | Davide Libenzi <davidel@xmailserver.org> | 2007-05-11 01:23:16 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-05-11 11:29:36 -0400 |
commit | b215e283992899650c4271e7385c79e26fb9a88e (patch) | |
tree | 3f950814510422606821f1b0b373d65e4d9ed303 /include | |
parent | 6d18c9220965b437287c3a7e803725c24992ceac (diff) |
signal/timer/event: timerfd core
This patch introduces a new system call for timers events delivered though
file descriptors. This allows timer event to be used with standard POSIX
poll(2), select(2) and read(2). As a consequence of supporting the Linux
f_op->poll subsystem, they can be used with epoll(2) too.
The system call is defined as:
int timerfd(int ufd, int clockid, int flags, const struct itimerspec *utmr);
The "ufd" parameter allows for re-use (re-programming) of an existing timerfd
w/out going through the close/open cycle (same as signalfd). If "ufd" is -1,
s new file descriptor will be created, otherwise the existing "ufd" will be
re-programmed.
The "clockid" parameter is either CLOCK_MONOTONIC or CLOCK_REALTIME. The time
specified in the "utmr->it_value" parameter is the expiry time for the timer.
If the TFD_TIMER_ABSTIME flag is set in "flags", this is an absolute time,
otherwise it's a relative time.
If the time specified in the "utmr->it_interval" is not zero (.tv_sec == 0,
tv_nsec == 0), this is the period at which the following ticks should be
generated.
The "utmr->it_interval" should be set to zero if only one tick is requested.
Setting the "utmr->it_value" to zero will disable the timer, or will create a
timerfd without the timer enabled.
The function returns the new (or same, in case "ufd" is a valid timerfd
descriptor) file, or -1 in case of error.
As stated before, the timerfd file descriptor supports poll(2), select(2) and
epoll(2). When a timer event happened on the timerfd, a POLLIN mask will be
returned.
The read(2) call can be used, and it will return a u32 variable holding the
number of "ticks" that happened on the interface since the last call to
read(2). The read(2) call supportes the O_NONBLOCK flag too, and EAGAIN will
be returned if no ticks happened.
A quick test program, shows timerfd working correctly on my amd64 box:
http://www.xmailserver.org/timerfd-test.c
[akpm@linux-foundation.org: add sys_timerfd to sys_ni.c]
Signed-off-by: Davide Libenzi <davidel@xmailserver.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'include')
-rw-r--r-- | include/linux/syscalls.h | 2 | ||||
-rw-r--r-- | include/linux/timerfd.h | 17 |
2 files changed, 19 insertions, 0 deletions
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index e049f14a75b7..fc637be1d9cf 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h | |||
@@ -605,6 +605,8 @@ asmlinkage long sys_set_robust_list(struct robust_list_head __user *head, | |||
605 | size_t len); | 605 | size_t len); |
606 | asmlinkage long sys_getcpu(unsigned __user *cpu, unsigned __user *node, struct getcpu_cache __user *cache); | 606 | asmlinkage long sys_getcpu(unsigned __user *cpu, unsigned __user *node, struct getcpu_cache __user *cache); |
607 | asmlinkage long sys_signalfd(int ufd, sigset_t __user *user_mask, size_t sizemask); | 607 | asmlinkage long sys_signalfd(int ufd, sigset_t __user *user_mask, size_t sizemask); |
608 | asmlinkage long sys_timerfd(int ufd, int clockid, int flags, | ||
609 | const struct itimerspec __user *utmr); | ||
608 | 610 | ||
609 | int kernel_execve(const char *filename, char *const argv[], char *const envp[]); | 611 | int kernel_execve(const char *filename, char *const argv[], char *const envp[]); |
610 | 612 | ||
diff --git a/include/linux/timerfd.h b/include/linux/timerfd.h new file mode 100644 index 000000000000..cf2b10d75731 --- /dev/null +++ b/include/linux/timerfd.h | |||
@@ -0,0 +1,17 @@ | |||
1 | /* | ||
2 | * include/linux/timerfd.h | ||
3 | * | ||
4 | * Copyright (C) 2007 Davide Libenzi <davidel@xmailserver.org> | ||
5 | * | ||
6 | */ | ||
7 | |||
8 | #ifndef _LINUX_TIMERFD_H | ||
9 | #define _LINUX_TIMERFD_H | ||
10 | |||
11 | |||
12 | #define TFD_TIMER_ABSTIME (1 << 0) | ||
13 | |||
14 | |||
15 | |||
16 | #endif /* _LINUX_TIMERFD_H */ | ||
17 | |||