aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorGeorge Anzinger <george@wildturkeyranch.net>2006-02-01 06:05:11 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-02-01 11:53:13 -0500
commit7978672c4d9a1e6a6081de3a9d9ba5e5b24904a0 (patch)
treea7deb3a6e339e691078c770d4b9cbc05d99a2243 /kernel
parentff60a5dc4fa584d47022d2533bc5c53b80096fb5 (diff)
[PATCH] hrtimers: cleanups and simplifications
Clean up the interface to hrtimers by changing the init code to pass the mode as well as the clock. This allow the init code to select the correct base and eliminates extra timer re-init code in posix-timers. We also simplify the restart interface nanosleep use. Signed-off-by: George Anzinger <george@mvista.com> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/fork.c2
-rw-r--r--kernel/hrtimer.c59
-rw-r--r--kernel/posix-timers.c37
3 files changed, 34 insertions, 64 deletions
diff --git a/kernel/fork.c b/kernel/fork.c
index 4ae8cfc1c89c..7f0ab5ee948c 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -802,7 +802,7 @@ static inline int copy_signal(unsigned long clone_flags, struct task_struct * ts
802 init_sigpending(&sig->shared_pending); 802 init_sigpending(&sig->shared_pending);
803 INIT_LIST_HEAD(&sig->posix_timers); 803 INIT_LIST_HEAD(&sig->posix_timers);
804 804
805 hrtimer_init(&sig->real_timer, CLOCK_MONOTONIC); 805 hrtimer_init(&sig->real_timer, CLOCK_MONOTONIC, HRTIMER_REL);
806 sig->it_real_incr.tv64 = 0; 806 sig->it_real_incr.tv64 = 0;
807 sig->real_timer.function = it_real_fn; 807 sig->real_timer.function = it_real_fn;
808 sig->real_timer.data = tsk; 808 sig->real_timer.data = tsk;
diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c
index f580dd9db286..efff9496b2fa 100644
--- a/kernel/hrtimer.c
+++ b/kernel/hrtimer.c
@@ -66,6 +66,12 @@ EXPORT_SYMBOL_GPL(ktime_get_real);
66 66
67/* 67/*
68 * The timer bases: 68 * The timer bases:
69 *
70 * Note: If we want to add new timer bases, we have to skip the two
71 * clock ids captured by the cpu-timers. We do this by holding empty
72 * entries rather than doing math adjustment of the clock ids.
73 * This ensures that we capture erroneous accesses to these clock ids
74 * rather than moving them into the range of valid clock id's.
69 */ 75 */
70 76
71#define MAX_HRTIMER_BASES 2 77#define MAX_HRTIMER_BASES 2
@@ -483,29 +489,25 @@ ktime_t hrtimer_get_remaining(const struct hrtimer *timer)
483} 489}
484 490
485/** 491/**
486 * hrtimer_rebase - rebase an initialized hrtimer to a different base 492 * hrtimer_init - initialize a timer to the given clock
487 * 493 *
488 * @timer: the timer to be rebased 494 * @timer: the timer to be initialized
489 * @clock_id: the clock to be used 495 * @clock_id: the clock to be used
496 * @mode: timer mode abs/rel
490 */ 497 */
491void hrtimer_rebase(struct hrtimer *timer, const clockid_t clock_id) 498void hrtimer_init(struct hrtimer *timer, clockid_t clock_id,
499 enum hrtimer_mode mode)
492{ 500{
493 struct hrtimer_base *bases; 501 struct hrtimer_base *bases;
494 502
503 memset(timer, 0, sizeof(struct hrtimer));
504
495 bases = per_cpu(hrtimer_bases, raw_smp_processor_id()); 505 bases = per_cpu(hrtimer_bases, raw_smp_processor_id());
496 timer->base = &bases[clock_id];
497}
498 506
499/** 507 if (clock_id == CLOCK_REALTIME && mode != HRTIMER_ABS)
500 * hrtimer_init - initialize a timer to the given clock 508 clock_id = CLOCK_MONOTONIC;
501 * 509
502 * @timer: the timer to be initialized 510 timer->base = &bases[clock_id];
503 * @clock_id: the clock to be used
504 */
505void hrtimer_init(struct hrtimer *timer, const clockid_t clock_id)
506{
507 memset(timer, 0, sizeof(struct hrtimer));
508 hrtimer_rebase(timer, clock_id);
509} 511}
510 512
511/** 513/**
@@ -643,8 +645,7 @@ schedule_hrtimer_interruptible(struct hrtimer *timer,
643 return schedule_hrtimer(timer, mode); 645 return schedule_hrtimer(timer, mode);
644} 646}
645 647
646static long __sched 648static long __sched nanosleep_restart(struct restart_block *restart)
647nanosleep_restart(struct restart_block *restart, clockid_t clockid)
648{ 649{
649 struct timespec __user *rmtp; 650 struct timespec __user *rmtp;
650 struct timespec tu; 651 struct timespec tu;
@@ -654,7 +655,7 @@ nanosleep_restart(struct restart_block *restart, clockid_t clockid)
654 655
655 restart->fn = do_no_restart_syscall; 656 restart->fn = do_no_restart_syscall;
656 657
657 hrtimer_init(&timer, clockid); 658 hrtimer_init(&timer, (clockid_t) restart->arg3, HRTIMER_ABS);
658 659
659 timer.expires.tv64 = ((u64)restart->arg1 << 32) | (u64) restart->arg0; 660 timer.expires.tv64 = ((u64)restart->arg1 << 32) | (u64) restart->arg0;
660 661
@@ -674,16 +675,6 @@ nanosleep_restart(struct restart_block *restart, clockid_t clockid)
674 return -ERESTART_RESTARTBLOCK; 675 return -ERESTART_RESTARTBLOCK;
675} 676}
676 677
677static long __sched nanosleep_restart_mono(struct restart_block *restart)
678{
679 return nanosleep_restart(restart, CLOCK_MONOTONIC);
680}
681
682static long __sched nanosleep_restart_real(struct restart_block *restart)
683{
684 return nanosleep_restart(restart, CLOCK_REALTIME);
685}
686
687long hrtimer_nanosleep(struct timespec *rqtp, struct timespec __user *rmtp, 678long hrtimer_nanosleep(struct timespec *rqtp, struct timespec __user *rmtp,
688 const enum hrtimer_mode mode, const clockid_t clockid) 679 const enum hrtimer_mode mode, const clockid_t clockid)
689{ 680{
@@ -692,7 +683,7 @@ long hrtimer_nanosleep(struct timespec *rqtp, struct timespec __user *rmtp,
692 struct timespec tu; 683 struct timespec tu;
693 ktime_t rem; 684 ktime_t rem;
694 685
695 hrtimer_init(&timer, clockid); 686 hrtimer_init(&timer, clockid, mode);
696 687
697 timer.expires = timespec_to_ktime(*rqtp); 688 timer.expires = timespec_to_ktime(*rqtp);
698 689
@@ -700,7 +691,7 @@ long hrtimer_nanosleep(struct timespec *rqtp, struct timespec __user *rmtp,
700 if (rem.tv64 <= 0) 691 if (rem.tv64 <= 0)
701 return 0; 692 return 0;
702 693
703 /* Absolute timers do not update the rmtp value: */ 694 /* Absolute timers do not update the rmtp value and restart: */
704 if (mode == HRTIMER_ABS) 695 if (mode == HRTIMER_ABS)
705 return -ERESTARTNOHAND; 696 return -ERESTARTNOHAND;
706 697
@@ -710,11 +701,11 @@ long hrtimer_nanosleep(struct timespec *rqtp, struct timespec __user *rmtp,
710 return -EFAULT; 701 return -EFAULT;
711 702
712 restart = &current_thread_info()->restart_block; 703 restart = &current_thread_info()->restart_block;
713 restart->fn = (clockid == CLOCK_MONOTONIC) ? 704 restart->fn = nanosleep_restart;
714 nanosleep_restart_mono : nanosleep_restart_real;
715 restart->arg0 = timer.expires.tv64 & 0xFFFFFFFF; 705 restart->arg0 = timer.expires.tv64 & 0xFFFFFFFF;
716 restart->arg1 = timer.expires.tv64 >> 32; 706 restart->arg1 = timer.expires.tv64 >> 32;
717 restart->arg2 = (unsigned long) rmtp; 707 restart->arg2 = (unsigned long) rmtp;
708 restart->arg3 = (unsigned long) timer.base->index;
718 709
719 return -ERESTART_RESTARTBLOCK; 710 return -ERESTART_RESTARTBLOCK;
720} 711}
@@ -741,10 +732,8 @@ static void __devinit init_hrtimers_cpu(int cpu)
741 struct hrtimer_base *base = per_cpu(hrtimer_bases, cpu); 732 struct hrtimer_base *base = per_cpu(hrtimer_bases, cpu);
742 int i; 733 int i;
743 734
744 for (i = 0; i < MAX_HRTIMER_BASES; i++) { 735 for (i = 0; i < MAX_HRTIMER_BASES; i++, base++)
745 spin_lock_init(&base->lock); 736 spin_lock_init(&base->lock);
746 base++;
747 }
748} 737}
749 738
750#ifdef CONFIG_HOTPLUG_CPU 739#ifdef CONFIG_HOTPLUG_CPU
diff --git a/kernel/posix-timers.c b/kernel/posix-timers.c
index 3b606d361b52..28e72fd0029f 100644
--- a/kernel/posix-timers.c
+++ b/kernel/posix-timers.c
@@ -194,9 +194,7 @@ static inline int common_clock_set(const clockid_t which_clock,
194 194
195static int common_timer_create(struct k_itimer *new_timer) 195static int common_timer_create(struct k_itimer *new_timer)
196{ 196{
197 hrtimer_init(&new_timer->it.real.timer, new_timer->it_clock); 197 hrtimer_init(&new_timer->it.real.timer, new_timer->it_clock, 0);
198 new_timer->it.real.timer.data = new_timer;
199 new_timer->it.real.timer.function = posix_timer_fn;
200 return 0; 198 return 0;
201} 199}
202 200
@@ -693,6 +691,7 @@ common_timer_set(struct k_itimer *timr, int flags,
693 struct itimerspec *new_setting, struct itimerspec *old_setting) 691 struct itimerspec *new_setting, struct itimerspec *old_setting)
694{ 692{
695 struct hrtimer *timer = &timr->it.real.timer; 693 struct hrtimer *timer = &timr->it.real.timer;
694 enum hrtimer_mode mode;
696 695
697 if (old_setting) 696 if (old_setting)
698 common_timer_get(timr, old_setting); 697 common_timer_get(timr, old_setting);
@@ -714,14 +713,10 @@ common_timer_set(struct k_itimer *timr, int flags,
714 if (!new_setting->it_value.tv_sec && !new_setting->it_value.tv_nsec) 713 if (!new_setting->it_value.tv_sec && !new_setting->it_value.tv_nsec)
715 return 0; 714 return 0;
716 715
717 /* Posix madness. Only absolute CLOCK_REALTIME timers 716 mode = flags & TIMER_ABSTIME ? HRTIMER_ABS : HRTIMER_REL;
718 * are affected by clock sets. So we must reiniatilize 717 hrtimer_init(&timr->it.real.timer, timr->it_clock, mode);
719 * the timer. 718 timr->it.real.timer.data = timr;
720 */ 719 timr->it.real.timer.function = posix_timer_fn;
721 if (timr->it_clock == CLOCK_REALTIME && (flags & TIMER_ABSTIME))
722 hrtimer_rebase(timer, CLOCK_REALTIME);
723 else
724 hrtimer_rebase(timer, CLOCK_MONOTONIC);
725 720
726 timer->expires = timespec_to_ktime(new_setting->it_value); 721 timer->expires = timespec_to_ktime(new_setting->it_value);
727 722
@@ -732,8 +727,7 @@ common_timer_set(struct k_itimer *timr, int flags,
732 if (((timr->it_sigev_notify & ~SIGEV_THREAD_ID) == SIGEV_NONE)) 727 if (((timr->it_sigev_notify & ~SIGEV_THREAD_ID) == SIGEV_NONE))
733 return 0; 728 return 0;
734 729
735 hrtimer_start(timer, timer->expires, (flags & TIMER_ABSTIME) ? 730 hrtimer_start(timer, timer->expires, mode);
736 HRTIMER_ABS : HRTIMER_REL);
737 return 0; 731 return 0;
738} 732}
739 733
@@ -948,21 +942,8 @@ sys_clock_getres(const clockid_t which_clock, struct timespec __user *tp)
948static int common_nsleep(const clockid_t which_clock, int flags, 942static int common_nsleep(const clockid_t which_clock, int flags,
949 struct timespec *tsave, struct timespec __user *rmtp) 943 struct timespec *tsave, struct timespec __user *rmtp)
950{ 944{
951 int mode = flags & TIMER_ABSTIME ? HRTIMER_ABS : HRTIMER_REL; 945 return hrtimer_nanosleep(tsave, rmtp, flags & TIMER_ABSTIME ?
952 int clockid = which_clock; 946 HRTIMER_ABS : HRTIMER_REL, which_clock);
953
954 switch (which_clock) {
955 case CLOCK_REALTIME:
956 /* Posix madness. Only absolute timers on clock realtime
957 are affected by clock set. */
958 if (mode != HRTIMER_ABS)
959 clockid = CLOCK_MONOTONIC;
960 case CLOCK_MONOTONIC:
961 break;
962 default:
963 return -EINVAL;
964 }
965 return hrtimer_nanosleep(tsave, rmtp, mode, clockid);
966} 947}
967 948
968asmlinkage long 949asmlinkage long