diff options
author | Linus Torvalds <torvalds@g5.osdl.org> | 2006-01-12 13:22:11 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-01-12 13:22:11 -0500 |
commit | 661dd5c840851194c7ee5a2603d5354dcf9bd212 (patch) | |
tree | ae8698638f21deeca51c1522bb8ccfd6a7735770 | |
parent | 45bfe98bd790b5ded00462cd582effcfb42263cc (diff) | |
parent | c9db4fa11526affde83603fe52595bd1260c1354 (diff) |
Merge master.kernel.org:/pub/scm/linux/kernel/git/tglx/hrtimer-2.6
-rw-r--r-- | include/linux/hrtimer.h | 12 | ||||
-rw-r--r-- | include/linux/ktime.h | 4 | ||||
-rw-r--r-- | kernel/hrtimer.c | 34 |
3 files changed, 25 insertions, 25 deletions
diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h index cf5cfdf8d613..089bfb1fa01a 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,8 +84,8 @@ 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 | ktime_t resolution; |
92 | ktime_t (*get_time)(void); | 89 | ktime_t (*get_time)(void); |
93 | struct hrtimer *curr_timer; | 90 | struct hrtimer *curr_timer; |
94 | }; | 91 | }; |
@@ -125,8 +122,7 @@ static inline int hrtimer_active(const struct hrtimer *timer) | |||
125 | } | 122 | } |
126 | 123 | ||
127 | /* Forward a hrtimer so it expires after now: */ | 124 | /* Forward a hrtimer so it expires after now: */ |
128 | extern unsigned long hrtimer_forward(struct hrtimer *timer, | 125 | extern unsigned long hrtimer_forward(struct hrtimer *timer, ktime_t interval); |
129 | const ktime_t interval); | ||
130 | 126 | ||
131 | /* Precise sleep: */ | 127 | /* Precise sleep: */ |
132 | extern long hrtimer_nanosleep(struct timespec *rqtp, | 128 | extern long hrtimer_nanosleep(struct timespec *rqtp, |
diff --git a/include/linux/ktime.h b/include/linux/ktime.h index 222a047cc145..1bd6552cc341 100644 --- a/include/linux/ktime.h +++ b/include/linux/ktime.h | |||
@@ -272,8 +272,8 @@ static inline u64 ktime_to_ns(const ktime_t kt) | |||
272 | * idea of the (in)accuracy of timers. Timer values are rounded up to | 272 | * idea of the (in)accuracy of timers. Timer values are rounded up to |
273 | * this resolution values. | 273 | * this resolution values. |
274 | */ | 274 | */ |
275 | #define KTIME_REALTIME_RES (NSEC_PER_SEC/HZ) | 275 | #define KTIME_REALTIME_RES (ktime_t){ .tv64 = TICK_NSEC } |
276 | #define KTIME_MONOTONIC_RES (NSEC_PER_SEC/HZ) | 276 | #define KTIME_MONOTONIC_RES (ktime_t){ .tv64 = TICK_NSEC } |
277 | 277 | ||
278 | /* Get the monotonic time in timespec format: */ | 278 | /* Get the monotonic time in timespec format: */ |
279 | extern void ktime_get_ts(struct timespec *ts); | 279 | extern void ktime_get_ts(struct timespec *ts); |
diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c index f073a2461faa..04ccab099e84 100644 --- a/kernel/hrtimer.c +++ b/kernel/hrtimer.c | |||
@@ -275,7 +275,7 @@ void unlock_hrtimer_base(const struct hrtimer *timer, unsigned long *flags) | |||
275 | * The number of overruns is added to the overrun field. | 275 | * The number of overruns is added to the overrun field. |
276 | */ | 276 | */ |
277 | unsigned long | 277 | unsigned long |
278 | hrtimer_forward(struct hrtimer *timer, const ktime_t interval) | 278 | hrtimer_forward(struct hrtimer *timer, ktime_t interval) |
279 | { | 279 | { |
280 | unsigned long orun = 1; | 280 | unsigned long orun = 1; |
281 | ktime_t delta, now; | 281 | ktime_t delta, now; |
@@ -287,6 +287,9 @@ hrtimer_forward(struct hrtimer *timer, const ktime_t interval) | |||
287 | if (delta.tv64 < 0) | 287 | if (delta.tv64 < 0) |
288 | return 0; | 288 | return 0; |
289 | 289 | ||
290 | if (interval.tv64 < timer->base->resolution.tv64) | ||
291 | interval.tv64 = timer->base->resolution.tv64; | ||
292 | |||
290 | if (unlikely(delta.tv64 >= interval.tv64)) { | 293 | if (unlikely(delta.tv64 >= interval.tv64)) { |
291 | nsec_t incr = ktime_to_ns(interval); | 294 | nsec_t incr = ktime_to_ns(interval); |
292 | 295 | ||
@@ -314,7 +317,6 @@ hrtimer_forward(struct hrtimer *timer, const ktime_t interval) | |||
314 | static void enqueue_hrtimer(struct hrtimer *timer, struct hrtimer_base *base) | 317 | static void enqueue_hrtimer(struct hrtimer *timer, struct hrtimer_base *base) |
315 | { | 318 | { |
316 | struct rb_node **link = &base->active.rb_node; | 319 | struct rb_node **link = &base->active.rb_node; |
317 | struct list_head *prev = &base->pending; | ||
318 | struct rb_node *parent = NULL; | 320 | struct rb_node *parent = NULL; |
319 | struct hrtimer *entry; | 321 | struct hrtimer *entry; |
320 | 322 | ||
@@ -330,22 +332,23 @@ static void enqueue_hrtimer(struct hrtimer *timer, struct hrtimer_base *base) | |||
330 | */ | 332 | */ |
331 | if (timer->expires.tv64 < entry->expires.tv64) | 333 | if (timer->expires.tv64 < entry->expires.tv64) |
332 | link = &(*link)->rb_left; | 334 | link = &(*link)->rb_left; |
333 | else { | 335 | else |
334 | link = &(*link)->rb_right; | 336 | link = &(*link)->rb_right; |
335 | prev = &entry->list; | ||
336 | } | ||
337 | } | 337 | } |
338 | 338 | ||
339 | /* | 339 | /* |
340 | * Insert the timer to the rbtree and to the sorted list: | 340 | * Insert the timer to the rbtree and check whether it |
341 | * replaces the first pending timer | ||
341 | */ | 342 | */ |
342 | rb_link_node(&timer->node, parent, link); | 343 | rb_link_node(&timer->node, parent, link); |
343 | rb_insert_color(&timer->node, &base->active); | 344 | rb_insert_color(&timer->node, &base->active); |
344 | list_add(&timer->list, prev); | ||
345 | 345 | ||
346 | timer->state = HRTIMER_PENDING; | 346 | timer->state = HRTIMER_PENDING; |
347 | } | ||
348 | 347 | ||
348 | if (!base->first || timer->expires.tv64 < | ||
349 | rb_entry(base->first, struct hrtimer, node)->expires.tv64) | ||
350 | base->first = &timer->node; | ||
351 | } | ||
349 | 352 | ||
350 | /* | 353 | /* |
351 | * __remove_hrtimer - internal function to remove a timer | 354 | * __remove_hrtimer - internal function to remove a timer |
@@ -355,9 +358,11 @@ static void enqueue_hrtimer(struct hrtimer *timer, struct hrtimer_base *base) | |||
355 | static void __remove_hrtimer(struct hrtimer *timer, struct hrtimer_base *base) | 358 | static void __remove_hrtimer(struct hrtimer *timer, struct hrtimer_base *base) |
356 | { | 359 | { |
357 | /* | 360 | /* |
358 | * Remove the timer from the sorted list and from the rbtree: | 361 | * Remove the timer from the rbtree and replace the |
362 | * first entry pointer if necessary. | ||
359 | */ | 363 | */ |
360 | list_del(&timer->list); | 364 | if (base->first == &timer->node) |
365 | base->first = rb_next(&timer->node); | ||
361 | rb_erase(&timer->node, &base->active); | 366 | rb_erase(&timer->node, &base->active); |
362 | } | 367 | } |
363 | 368 | ||
@@ -516,9 +521,8 @@ int hrtimer_get_res(const clockid_t which_clock, struct timespec *tp) | |||
516 | { | 521 | { |
517 | struct hrtimer_base *bases; | 522 | struct hrtimer_base *bases; |
518 | 523 | ||
519 | tp->tv_sec = 0; | ||
520 | bases = per_cpu(hrtimer_bases, raw_smp_processor_id()); | 524 | bases = per_cpu(hrtimer_bases, raw_smp_processor_id()); |
521 | tp->tv_nsec = bases[which_clock].resolution; | 525 | *tp = ktime_to_timespec(bases[which_clock].resolution); |
522 | 526 | ||
523 | return 0; | 527 | return 0; |
524 | } | 528 | } |
@@ -529,16 +533,17 @@ int hrtimer_get_res(const clockid_t which_clock, struct timespec *tp) | |||
529 | static inline void run_hrtimer_queue(struct hrtimer_base *base) | 533 | static inline void run_hrtimer_queue(struct hrtimer_base *base) |
530 | { | 534 | { |
531 | ktime_t now = base->get_time(); | 535 | ktime_t now = base->get_time(); |
536 | struct rb_node *node; | ||
532 | 537 | ||
533 | spin_lock_irq(&base->lock); | 538 | spin_lock_irq(&base->lock); |
534 | 539 | ||
535 | while (!list_empty(&base->pending)) { | 540 | while ((node = base->first)) { |
536 | struct hrtimer *timer; | 541 | struct hrtimer *timer; |
537 | int (*fn)(void *); | 542 | int (*fn)(void *); |
538 | int restart; | 543 | int restart; |
539 | void *data; | 544 | void *data; |
540 | 545 | ||
541 | timer = list_entry(base->pending.next, struct hrtimer, list); | 546 | timer = rb_entry(node, struct hrtimer, node); |
542 | if (now.tv64 <= timer->expires.tv64) | 547 | if (now.tv64 <= timer->expires.tv64) |
543 | break; | 548 | break; |
544 | 549 | ||
@@ -732,7 +737,6 @@ static void __devinit init_hrtimers_cpu(int cpu) | |||
732 | 737 | ||
733 | for (i = 0; i < MAX_HRTIMER_BASES; i++) { | 738 | for (i = 0; i < MAX_HRTIMER_BASES; i++) { |
734 | spin_lock_init(&base->lock); | 739 | spin_lock_init(&base->lock); |
735 | INIT_LIST_HEAD(&base->pending); | ||
736 | base++; | 740 | base++; |
737 | } | 741 | } |
738 | } | 742 | } |