diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2011-04-27 08:16:42 -0400 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2011-05-02 15:39:15 -0400 |
commit | 99ee5315dac6211e972fa3f23bcc9a0343ff58c4 (patch) | |
tree | 6663d6ceaabcb9bac03193e2781cdbe6a139f70c /include/linux | |
parent | b12a03ce4880bd13786a98db6de494a3e0123129 (diff) |
timerfd: Allow timers to be cancelled when clock was set
Some applications must be aware of clock realtime being set
backward. A simple example is a clock applet which arms a timer for
the next minute display. If clock realtime is set backward then the
applet displays a stale time for the amount of time which the clock
was set backwards. Due to that applications poll the time because we
don't have an interface.
Extend the timerfd interface by adding a flag which puts the timer
onto a different internal realtime clock. All timers on this clock are
expired whenever the clock was set.
The timerfd core records the monotonic offset when the timer is
created. When the timer is armed, then the current offset is compared
to the previous recorded offset. When it has changed, then
timerfd_settime returns -ECANCELED. When a timer is read the offset is
compared and if it changed -ECANCELED returned to user space. Periodic
timers are not rearmed in the cancelation case.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: John Stultz <johnstul@us.ibm.com>
Cc: Chris Friesen <chris.friesen@genband.com>
Tested-by: Kay Sievers <kay.sievers@vrfy.org>
Cc: "Kirill A. Shutemov" <kirill@shutemov.name>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Davide Libenzi <davidel@xmailserver.org>
Reviewed-by: Alexander Shishkin <virtuoso@slind.org>
Link: http://lkml.kernel.org/r/%3Calpine.LFD.2.02.1104271359580.3323%40ionos%3E
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'include/linux')
-rw-r--r-- | include/linux/hrtimer.h | 2 | ||||
-rw-r--r-- | include/linux/time.h | 6 | ||||
-rw-r--r-- | include/linux/timerfd.h | 3 |
3 files changed, 10 insertions, 1 deletions
diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h index 4135c88fe4fa..eda4ccde0730 100644 --- a/include/linux/hrtimer.h +++ b/include/linux/hrtimer.h | |||
@@ -155,6 +155,7 @@ enum hrtimer_base_type { | |||
155 | HRTIMER_BASE_REALTIME, | 155 | HRTIMER_BASE_REALTIME, |
156 | HRTIMER_BASE_MONOTONIC, | 156 | HRTIMER_BASE_MONOTONIC, |
157 | HRTIMER_BASE_BOOTTIME, | 157 | HRTIMER_BASE_BOOTTIME, |
158 | HRTIMER_BASE_REALTIME_COS, | ||
158 | HRTIMER_MAX_CLOCK_BASES, | 159 | HRTIMER_MAX_CLOCK_BASES, |
159 | }; | 160 | }; |
160 | 161 | ||
@@ -310,6 +311,7 @@ extern void hrtimers_resume(void); | |||
310 | extern ktime_t ktime_get(void); | 311 | extern ktime_t ktime_get(void); |
311 | extern ktime_t ktime_get_real(void); | 312 | extern ktime_t ktime_get_real(void); |
312 | extern ktime_t ktime_get_boottime(void); | 313 | extern ktime_t ktime_get_boottime(void); |
314 | extern ktime_t ktime_get_monotonic_offset(void); | ||
313 | 315 | ||
314 | DECLARE_PER_CPU(struct tick_device, tick_cpu_device); | 316 | DECLARE_PER_CPU(struct tick_device, tick_cpu_device); |
315 | 317 | ||
diff --git a/include/linux/time.h b/include/linux/time.h index b3061782dec3..a9242773eb24 100644 --- a/include/linux/time.h +++ b/include/linux/time.h | |||
@@ -302,6 +302,12 @@ struct itimerval { | |||
302 | * The IDs of various hardware clocks: | 302 | * The IDs of various hardware clocks: |
303 | */ | 303 | */ |
304 | #define CLOCK_SGI_CYCLE 10 | 304 | #define CLOCK_SGI_CYCLE 10 |
305 | |||
306 | #ifdef __KERNEL__ | ||
307 | /* This clock is not exposed to user space */ | ||
308 | #define CLOCK_REALTIME_COS 15 | ||
309 | #endif | ||
310 | |||
305 | #define MAX_CLOCKS 16 | 311 | #define MAX_CLOCKS 16 |
306 | #define CLOCKS_MASK (CLOCK_REALTIME | CLOCK_MONOTONIC) | 312 | #define CLOCKS_MASK (CLOCK_REALTIME | CLOCK_MONOTONIC) |
307 | #define CLOCKS_MONO CLOCK_MONOTONIC | 313 | #define CLOCKS_MONO CLOCK_MONOTONIC |
diff --git a/include/linux/timerfd.h b/include/linux/timerfd.h index 2d0792983f8c..e9571fc8f1a0 100644 --- a/include/linux/timerfd.h +++ b/include/linux/timerfd.h | |||
@@ -19,6 +19,7 @@ | |||
19 | * shared O_* flags. | 19 | * shared O_* flags. |
20 | */ | 20 | */ |
21 | #define TFD_TIMER_ABSTIME (1 << 0) | 21 | #define TFD_TIMER_ABSTIME (1 << 0) |
22 | #define TFD_TIMER_CANCELON_SET (1 << 1) | ||
22 | #define TFD_CLOEXEC O_CLOEXEC | 23 | #define TFD_CLOEXEC O_CLOEXEC |
23 | #define TFD_NONBLOCK O_NONBLOCK | 24 | #define TFD_NONBLOCK O_NONBLOCK |
24 | 25 | ||
@@ -26,6 +27,6 @@ | |||
26 | /* Flags for timerfd_create. */ | 27 | /* Flags for timerfd_create. */ |
27 | #define TFD_CREATE_FLAGS TFD_SHARED_FCNTL_FLAGS | 28 | #define TFD_CREATE_FLAGS TFD_SHARED_FCNTL_FLAGS |
28 | /* Flags for timerfd_settime. */ | 29 | /* Flags for timerfd_settime. */ |
29 | #define TFD_SETTIME_FLAGS TFD_TIMER_ABSTIME | 30 | #define TFD_SETTIME_FLAGS (TFD_TIMER_ABSTIME | TFD_TIMER_CANCELON_SET) |
30 | 31 | ||
31 | #endif /* _LINUX_TIMERFD_H */ | 32 | #endif /* _LINUX_TIMERFD_H */ |