From c0a3132963db68f1fbbd0e316b73de100fee3f08 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Mon, 9 Jan 2006 20:52:32 -0800 Subject: [PATCH] hrtimer: hrtimer core code hrtimer subsystem core. It is initialized at bootup and expired by the timer interrupt, but is otherwise not utilized by any other subsystem yet. Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/hrtimer.h | 130 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 include/linux/hrtimer.h (limited to 'include/linux/hrtimer.h') diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h new file mode 100644 index 000000000000..64f8d554fbb8 --- /dev/null +++ b/include/linux/hrtimer.h @@ -0,0 +1,130 @@ +/* + * include/linux/hrtimer.h + * + * hrtimers - High-resolution kernel timers + * + * Copyright(C) 2005, Thomas Gleixner + * Copyright(C) 2005, Red Hat, Inc., Ingo Molnar + * + * data type definitions, declarations, prototypes + * + * Started by: Thomas Gleixner and Ingo Molnar + * + * For licencing details see kernel-base/COPYING + */ +#ifndef _LINUX_HRTIMER_H +#define _LINUX_HRTIMER_H + +#include +#include +#include +#include +#include + +/* + * Mode arguments of xxx_hrtimer functions: + */ +enum hrtimer_mode { + HRTIMER_ABS, /* Time value is absolute */ + HRTIMER_REL, /* Time value is relative to now */ +}; + +enum hrtimer_restart { + HRTIMER_NORESTART, + HRTIMER_RESTART, +}; + +/* + * Timer states: + */ +enum hrtimer_state { + HRTIMER_INACTIVE, /* Timer is inactive */ + HRTIMER_EXPIRED, /* Timer is expired */ + HRTIMER_PENDING, /* Timer is pending */ +}; + +struct hrtimer_base; + +/** + * struct hrtimer - the basic hrtimer structure + * + * @node: red black tree node for time ordered insertion + * @list: list head for easier access to the time ordered list, + * without walking the red black tree. + * @expires: the absolute expiry time in the hrtimers internal + * representation. The time is related to the clock on + * which the timer is based. + * @state: state of the timer + * @function: timer expiry callback function + * @data: argument for the callback function + * @base: pointer to the timer base (per cpu and per clock) + * + * The hrtimer structure must be initialized by init_hrtimer_#CLOCKTYPE() + */ +struct hrtimer { + struct rb_node node; + struct list_head list; + ktime_t expires; + enum hrtimer_state state; + int (*function)(void *); + void *data; + struct hrtimer_base *base; +}; + +/** + * struct hrtimer_base - the timer base for a specific clock + * + * @index: clock type index for per_cpu support when moving a timer + * to a base on another cpu. + * @lock: lock protecting the base and associated timers + * @active: red black tree root node for the active timers + * @pending: list of pending timers for simple time ordered access + * @resolution: the resolution of the clock, in nanoseconds + * @get_time: function to retrieve the current time of the clock + * @curr_timer: the timer which is executing a callback right now + */ +struct hrtimer_base { + clockid_t index; + spinlock_t lock; + struct rb_root active; + struct list_head pending; + unsigned long resolution; + ktime_t (*get_time)(void); + struct hrtimer *curr_timer; +}; + +/* Exported timer functions: */ + +/* Initialize timers: */ +extern void hrtimer_init(struct hrtimer *timer, const clockid_t which_clock); +extern void hrtimer_rebase(struct hrtimer *timer, const clockid_t which_clock); + + +/* Basic timer operations: */ +extern int hrtimer_start(struct hrtimer *timer, ktime_t tim, + const enum hrtimer_mode mode); +extern int hrtimer_cancel(struct hrtimer *timer); +extern int hrtimer_try_to_cancel(struct hrtimer *timer); + +#define hrtimer_restart(timer) hrtimer_start((timer), (timer)->expires, HRTIMER_ABS) + +/* Query timers: */ +extern ktime_t hrtimer_get_remaining(const struct hrtimer *timer); +extern int hrtimer_get_res(const clockid_t which_clock, struct timespec *tp); + +static inline int hrtimer_active(const struct hrtimer *timer) +{ + return timer->state == HRTIMER_PENDING; +} + +/* Forward a hrtimer so it expires after now: */ +extern unsigned long hrtimer_forward(struct hrtimer *timer, + const ktime_t interval); + +/* Soft interrupt function to run the hrtimer queues: */ +extern void hrtimer_run_queues(void); + +/* Bootup initialization: */ +extern void __init hrtimers_init(void); + +#endif -- cgit From 10c94ec16dd187f8d8dfdbb088e98330c05bf03c Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Mon, 9 Jan 2006 20:52:35 -0800 Subject: [PATCH] hrtimer: create hrtimer nanosleep API introduce the hrtimer_nanosleep() and hrtimer_nanosleep_real() APIs. Not yet used by any code. Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/hrtimer.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'include/linux/hrtimer.h') diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h index 64f8d554fbb8..2ac20b48b2f3 100644 --- a/include/linux/hrtimer.h +++ b/include/linux/hrtimer.h @@ -121,6 +121,12 @@ static inline int hrtimer_active(const struct hrtimer *timer) extern unsigned long hrtimer_forward(struct hrtimer *timer, const ktime_t interval); +/* Precise sleep: */ +extern long hrtimer_nanosleep(struct timespec *rqtp, + struct timespec __user *rmtp, + const enum hrtimer_mode mode, + const clockid_t clockid); + /* Soft interrupt function to run the hrtimer queues: */ extern void hrtimer_run_queues(void); -- cgit From becf8b5d00f4b47e847f98322cdaf8cd16243861 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Mon, 9 Jan 2006 20:52:38 -0800 Subject: [PATCH] hrtimer: convert posix timers completely - convert posix-timers.c to use hrtimers - remove the now obsolete abslist code Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar Signed-off-by: Miklos Szeredi Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/hrtimer.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'include/linux/hrtimer.h') diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h index 2ac20b48b2f3..cf5cfdf8d613 100644 --- a/include/linux/hrtimer.h +++ b/include/linux/hrtimer.h @@ -93,6 +93,13 @@ struct hrtimer_base { struct hrtimer *curr_timer; }; +/* + * clock_was_set() is a NOP for non- high-resolution systems. The + * time-sorted order guarantees that a timer does not expire early and + * is expired in the next softirq when the clock was advanced. + */ +#define clock_was_set() do { } while (0) + /* Exported timer functions: */ /* Initialize timers: */ -- cgit From 288867ec5c377db82933b64460ce050e5c998ee9 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Thu, 12 Jan 2006 11:25:54 +0100 Subject: [hrtimer] Remove listhead from hrtimer struct The list_head in the hrtimer structure was introduced for easy access to the first timer with the further extensions of real high resolution timers in mind, but it turned out in the course of development that it is not necessary for the standard use case. Remove the list head and access the first expiry timer by a datafield in the timer base. Signed-off-by: Thomas Gleixner --- include/linux/hrtimer.h | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'include/linux/hrtimer.h') diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h index cf5cfdf8d613..abb674c9b764 100644 --- a/include/linux/hrtimer.h +++ b/include/linux/hrtimer.h @@ -49,8 +49,6 @@ struct hrtimer_base; * struct hrtimer - the basic hrtimer structure * * @node: red black tree node for time ordered insertion - * @list: list head for easier access to the time ordered list, - * without walking the red black tree. * @expires: the absolute expiry time in the hrtimers internal * representation. The time is related to the clock on * which the timer is based. @@ -63,7 +61,6 @@ struct hrtimer_base; */ struct hrtimer { struct rb_node node; - struct list_head list; ktime_t expires; enum hrtimer_state state; int (*function)(void *); @@ -78,7 +75,7 @@ struct hrtimer { * to a base on another cpu. * @lock: lock protecting the base and associated timers * @active: red black tree root node for the active timers - * @pending: list of pending timers for simple time ordered access + * @first: pointer to the timer node which expires first * @resolution: the resolution of the clock, in nanoseconds * @get_time: function to retrieve the current time of the clock * @curr_timer: the timer which is executing a callback right now @@ -87,7 +84,7 @@ struct hrtimer_base { clockid_t index; spinlock_t lock; struct rb_root active; - struct list_head pending; + struct rb_node *first; unsigned long resolution; ktime_t (*get_time)(void); struct hrtimer *curr_timer; -- cgit From e2787630c1abb075c935cf47e91beb7c656f48c4 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Thu, 12 Jan 2006 11:36:14 +0100 Subject: [hrtimer] Change resolution storage to ktime_t format Change the storage format of the per base resolution to ktime_t to make it easier accessible in the hrtimers code. Change the resolution from (NSEC_PER_SEC/HZ) to TICK_NSEC as Roman pointed out. TICK_NSEC is closer to the real resolution. Signed-off-by: Thomas Gleixner --- include/linux/hrtimer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux/hrtimer.h') diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h index abb674c9b764..98c5c1537b5d 100644 --- a/include/linux/hrtimer.h +++ b/include/linux/hrtimer.h @@ -85,7 +85,7 @@ struct hrtimer_base { spinlock_t lock; struct rb_root active; struct rb_node *first; - unsigned long resolution; + ktime_t resolution; ktime_t (*get_time)(void); struct hrtimer *curr_timer; }; -- cgit From c9db4fa11526affde83603fe52595bd1260c1354 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Thu, 12 Jan 2006 11:47:34 +0100 Subject: [hrtimer] Enforce resolution as lower limit of intervals Roman Zippel pointed out that the missing lower limit of intervals leads to an accounting error in the overrun count. Enforce the lower limit of intervals to resolution in the timer forwarding code. Signed-off-by: Thomas Gleixner --- include/linux/hrtimer.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'include/linux/hrtimer.h') diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h index 98c5c1537b5d..089bfb1fa01a 100644 --- a/include/linux/hrtimer.h +++ b/include/linux/hrtimer.h @@ -122,8 +122,7 @@ static inline int hrtimer_active(const struct hrtimer *timer) } /* Forward a hrtimer so it expires after now: */ -extern unsigned long hrtimer_forward(struct hrtimer *timer, - const ktime_t interval); +extern unsigned long hrtimer_forward(struct hrtimer *timer, ktime_t interval); /* Precise sleep: */ extern long hrtimer_nanosleep(struct timespec *rqtp, -- cgit