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 /kernel | |
| parent | 45bfe98bd790b5ded00462cd582effcfb42263cc (diff) | |
| parent | c9db4fa11526affde83603fe52595bd1260c1354 (diff) | |
Merge master.kernel.org:/pub/scm/linux/kernel/git/tglx/hrtimer-2.6
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/hrtimer.c | 34 |
1 files changed, 19 insertions, 15 deletions
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 | } |
