diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2006-01-12 05:25:54 -0500 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2006-01-12 05:25:54 -0500 |
commit | 288867ec5c377db82933b64460ce050e5c998ee9 (patch) | |
tree | d1c0c2e89cb7ffa2ac613e9b1740b81a813965a7 | |
parent | 593195f9b2309693f27b402f34573f7920b82c3e (diff) |
[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 <tglx@linutronix.de>
-rw-r--r-- | include/linux/hrtimer.h | 7 | ||||
-rw-r--r-- | kernel/hrtimer.c | 26 |
2 files changed, 16 insertions, 17 deletions
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; | |||
49 | * struct hrtimer - the basic hrtimer structure | 49 | * struct hrtimer - the basic hrtimer structure |
50 | * | 50 | * |
51 | * @node: red black tree node for time ordered insertion | 51 | * @node: red black tree node for time ordered insertion |
52 | * @list: list head for easier access to the time ordered list, | ||
53 | * without walking the red black tree. | ||
54 | * @expires: the absolute expiry time in the hrtimers internal | 52 | * @expires: the absolute expiry time in the hrtimers internal |
55 | * representation. The time is related to the clock on | 53 | * representation. The time is related to the clock on |
56 | * which the timer is based. | 54 | * which the timer is based. |
@@ -63,7 +61,6 @@ struct hrtimer_base; | |||
63 | */ | 61 | */ |
64 | struct hrtimer { | 62 | struct hrtimer { |
65 | struct rb_node node; | 63 | struct rb_node node; |
66 | struct list_head list; | ||
67 | ktime_t expires; | 64 | ktime_t expires; |
68 | enum hrtimer_state state; | 65 | enum hrtimer_state state; |
69 | int (*function)(void *); | 66 | int (*function)(void *); |
@@ -78,7 +75,7 @@ struct hrtimer { | |||
78 | * to a base on another cpu. | 75 | * to a base on another cpu. |
79 | * @lock: lock protecting the base and associated timers | 76 | * @lock: lock protecting the base and associated timers |
80 | * @active: red black tree root node for the active timers | 77 | * @active: red black tree root node for the active timers |
81 | * @pending: list of pending timers for simple time ordered access | 78 | * @first: pointer to the timer node which expires first |
82 | * @resolution: the resolution of the clock, in nanoseconds | 79 | * @resolution: the resolution of the clock, in nanoseconds |
83 | * @get_time: function to retrieve the current time of the clock | 80 | * @get_time: function to retrieve the current time of the clock |
84 | * @curr_timer: the timer which is executing a callback right now | 81 | * @curr_timer: the timer which is executing a callback right now |
@@ -87,7 +84,7 @@ struct hrtimer_base { | |||
87 | clockid_t index; | 84 | clockid_t index; |
88 | spinlock_t lock; | 85 | spinlock_t lock; |
89 | struct rb_root active; | 86 | struct rb_root active; |
90 | struct list_head pending; | 87 | struct rb_node *first; |
91 | unsigned long resolution; | 88 | unsigned long resolution; |
92 | ktime_t (*get_time)(void); | 89 | ktime_t (*get_time)(void); |
93 | struct hrtimer *curr_timer; | 90 | struct hrtimer *curr_timer; |
diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c index f073a2461faa..e6e8278bcb18 100644 --- a/kernel/hrtimer.c +++ b/kernel/hrtimer.c | |||
@@ -314,7 +314,6 @@ hrtimer_forward(struct hrtimer *timer, const ktime_t interval) | |||
314 | static void enqueue_hrtimer(struct hrtimer *timer, struct hrtimer_base *base) | 314 | static void enqueue_hrtimer(struct hrtimer *timer, struct hrtimer_base *base) |
315 | { | 315 | { |
316 | struct rb_node **link = &base->active.rb_node; | 316 | struct rb_node **link = &base->active.rb_node; |
317 | struct list_head *prev = &base->pending; | ||
318 | struct rb_node *parent = NULL; | 317 | struct rb_node *parent = NULL; |
319 | struct hrtimer *entry; | 318 | struct hrtimer *entry; |
320 | 319 | ||
@@ -330,22 +329,23 @@ static void enqueue_hrtimer(struct hrtimer *timer, struct hrtimer_base *base) | |||
330 | */ | 329 | */ |
331 | if (timer->expires.tv64 < entry->expires.tv64) | 330 | if (timer->expires.tv64 < entry->expires.tv64) |
332 | link = &(*link)->rb_left; | 331 | link = &(*link)->rb_left; |
333 | else { | 332 | else |
334 | link = &(*link)->rb_right; | 333 | link = &(*link)->rb_right; |
335 | prev = &entry->list; | ||
336 | } | ||
337 | } | 334 | } |
338 | 335 | ||
339 | /* | 336 | /* |
340 | * Insert the timer to the rbtree and to the sorted list: | 337 | * Insert the timer to the rbtree and check whether it |
338 | * replaces the first pending timer | ||
341 | */ | 339 | */ |
342 | rb_link_node(&timer->node, parent, link); | 340 | rb_link_node(&timer->node, parent, link); |
343 | rb_insert_color(&timer->node, &base->active); | 341 | rb_insert_color(&timer->node, &base->active); |
344 | list_add(&timer->list, prev); | ||
345 | 342 | ||
346 | timer->state = HRTIMER_PENDING; | 343 | timer->state = HRTIMER_PENDING; |
347 | } | ||
348 | 344 | ||
345 | if (!base->first || timer->expires.tv64 < | ||
346 | rb_entry(base->first, struct hrtimer, node)->expires.tv64) | ||
347 | base->first = &timer->node; | ||
348 | } | ||
349 | 349 | ||
350 | /* | 350 | /* |
351 | * __remove_hrtimer - internal function to remove a timer | 351 | * __remove_hrtimer - internal function to remove a timer |
@@ -355,9 +355,11 @@ static void enqueue_hrtimer(struct hrtimer *timer, struct hrtimer_base *base) | |||
355 | static void __remove_hrtimer(struct hrtimer *timer, struct hrtimer_base *base) | 355 | static void __remove_hrtimer(struct hrtimer *timer, struct hrtimer_base *base) |
356 | { | 356 | { |
357 | /* | 357 | /* |
358 | * Remove the timer from the sorted list and from the rbtree: | 358 | * Remove the timer from the rbtree and replace the |
359 | * first entry pointer if necessary. | ||
359 | */ | 360 | */ |
360 | list_del(&timer->list); | 361 | if (base->first == &timer->node) |
362 | base->first = rb_next(&timer->node); | ||
361 | rb_erase(&timer->node, &base->active); | 363 | rb_erase(&timer->node, &base->active); |
362 | } | 364 | } |
363 | 365 | ||
@@ -529,16 +531,17 @@ int hrtimer_get_res(const clockid_t which_clock, struct timespec *tp) | |||
529 | static inline void run_hrtimer_queue(struct hrtimer_base *base) | 531 | static inline void run_hrtimer_queue(struct hrtimer_base *base) |
530 | { | 532 | { |
531 | ktime_t now = base->get_time(); | 533 | ktime_t now = base->get_time(); |
534 | struct rb_node *node; | ||
532 | 535 | ||
533 | spin_lock_irq(&base->lock); | 536 | spin_lock_irq(&base->lock); |
534 | 537 | ||
535 | while (!list_empty(&base->pending)) { | 538 | while ((node = base->first)) { |
536 | struct hrtimer *timer; | 539 | struct hrtimer *timer; |
537 | int (*fn)(void *); | 540 | int (*fn)(void *); |
538 | int restart; | 541 | int restart; |
539 | void *data; | 542 | void *data; |
540 | 543 | ||
541 | timer = list_entry(base->pending.next, struct hrtimer, list); | 544 | timer = rb_entry(node, struct hrtimer, node); |
542 | if (now.tv64 <= timer->expires.tv64) | 545 | if (now.tv64 <= timer->expires.tv64) |
543 | break; | 546 | break; |
544 | 547 | ||
@@ -732,7 +735,6 @@ static void __devinit init_hrtimers_cpu(int cpu) | |||
732 | 735 | ||
733 | for (i = 0; i < MAX_HRTIMER_BASES; i++) { | 736 | for (i = 0; i < MAX_HRTIMER_BASES; i++) { |
734 | spin_lock_init(&base->lock); | 737 | spin_lock_init(&base->lock); |
735 | INIT_LIST_HEAD(&base->pending); | ||
736 | base++; | 738 | base++; |
737 | } | 739 | } |
738 | } | 740 | } |