diff options
author | Stanislaw Gruszka <sgruszka@redhat.com> | 2009-07-29 06:15:26 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-08-03 08:48:35 -0400 |
commit | 42c4ab41a176ee784c0f28c0b29025a8fc34f05a (patch) | |
tree | 370393a0e02faa7a6a7d211205b31ceb74880359 /kernel/posix-cpu-timers.c | |
parent | ed680c4ad478d0fee9740f7d029087f181346564 (diff) |
itimers: Merge ITIMER_VIRT and ITIMER_PROF
Both cpu itimers have same data flow in the few places, this
patch make unification of code related with VIRT and PROF
itimers.
Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
Acked-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Acked-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Oleg Nesterov <oleg@redhat.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
LKML-Reference: <1248862529-6063-2-git-send-email-sgruszka@redhat.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'kernel/posix-cpu-timers.c')
-rw-r--r-- | kernel/posix-cpu-timers.c | 98 |
1 files changed, 46 insertions, 52 deletions
diff --git a/kernel/posix-cpu-timers.c b/kernel/posix-cpu-timers.c index bece7c0b67b2..9b2d5e4dc8c4 100644 --- a/kernel/posix-cpu-timers.c +++ b/kernel/posix-cpu-timers.c | |||
@@ -14,11 +14,11 @@ | |||
14 | */ | 14 | */ |
15 | void update_rlimit_cpu(unsigned long rlim_new) | 15 | void update_rlimit_cpu(unsigned long rlim_new) |
16 | { | 16 | { |
17 | cputime_t cputime; | 17 | cputime_t cputime = secs_to_cputime(rlim_new); |
18 | struct signal_struct *const sig = current->signal; | ||
18 | 19 | ||
19 | cputime = secs_to_cputime(rlim_new); | 20 | if (cputime_eq(sig->it[CPUCLOCK_PROF].expires, cputime_zero) || |
20 | if (cputime_eq(current->signal->it_prof_expires, cputime_zero) || | 21 | cputime_gt(sig->it[CPUCLOCK_PROF].expires, cputime)) { |
21 | cputime_gt(current->signal->it_prof_expires, cputime)) { | ||
22 | spin_lock_irq(¤t->sighand->siglock); | 22 | spin_lock_irq(¤t->sighand->siglock); |
23 | set_process_cpu_timer(current, CPUCLOCK_PROF, &cputime, NULL); | 23 | set_process_cpu_timer(current, CPUCLOCK_PROF, &cputime, NULL); |
24 | spin_unlock_irq(¤t->sighand->siglock); | 24 | spin_unlock_irq(¤t->sighand->siglock); |
@@ -613,6 +613,9 @@ static void arm_timer(struct k_itimer *timer, union cpu_time_count now) | |||
613 | break; | 613 | break; |
614 | } | 614 | } |
615 | } else { | 615 | } else { |
616 | struct signal_struct *const sig = p->signal; | ||
617 | union cpu_time_count *exp = &timer->it.cpu.expires; | ||
618 | |||
616 | /* | 619 | /* |
617 | * For a process timer, set the cached expiration time. | 620 | * For a process timer, set the cached expiration time. |
618 | */ | 621 | */ |
@@ -620,30 +623,27 @@ static void arm_timer(struct k_itimer *timer, union cpu_time_count now) | |||
620 | default: | 623 | default: |
621 | BUG(); | 624 | BUG(); |
622 | case CPUCLOCK_VIRT: | 625 | case CPUCLOCK_VIRT: |
623 | if (!cputime_eq(p->signal->it_virt_expires, | 626 | if (!cputime_eq(sig->it[CPUCLOCK_VIRT].expires, |
624 | cputime_zero) && | 627 | cputime_zero) && |
625 | cputime_lt(p->signal->it_virt_expires, | 628 | cputime_lt(sig->it[CPUCLOCK_VIRT].expires, |
626 | timer->it.cpu.expires.cpu)) | 629 | exp->cpu)) |
627 | break; | 630 | break; |
628 | p->signal->cputime_expires.virt_exp = | 631 | sig->cputime_expires.virt_exp = exp->cpu; |
629 | timer->it.cpu.expires.cpu; | ||
630 | break; | 632 | break; |
631 | case CPUCLOCK_PROF: | 633 | case CPUCLOCK_PROF: |
632 | if (!cputime_eq(p->signal->it_prof_expires, | 634 | if (!cputime_eq(sig->it[CPUCLOCK_PROF].expires, |
633 | cputime_zero) && | 635 | cputime_zero) && |
634 | cputime_lt(p->signal->it_prof_expires, | 636 | cputime_lt(sig->it[CPUCLOCK_PROF].expires, |
635 | timer->it.cpu.expires.cpu)) | 637 | exp->cpu)) |
636 | break; | 638 | break; |
637 | i = p->signal->rlim[RLIMIT_CPU].rlim_cur; | 639 | i = sig->rlim[RLIMIT_CPU].rlim_cur; |
638 | if (i != RLIM_INFINITY && | 640 | if (i != RLIM_INFINITY && |
639 | i <= cputime_to_secs(timer->it.cpu.expires.cpu)) | 641 | i <= cputime_to_secs(exp->cpu)) |
640 | break; | 642 | break; |
641 | p->signal->cputime_expires.prof_exp = | 643 | sig->cputime_expires.prof_exp = exp->cpu; |
642 | timer->it.cpu.expires.cpu; | ||
643 | break; | 644 | break; |
644 | case CPUCLOCK_SCHED: | 645 | case CPUCLOCK_SCHED: |
645 | p->signal->cputime_expires.sched_exp = | 646 | sig->cputime_expires.sched_exp = exp->sched; |
646 | timer->it.cpu.expires.sched; | ||
647 | break; | 647 | break; |
648 | } | 648 | } |
649 | } | 649 | } |
@@ -1070,6 +1070,27 @@ static void stop_process_timers(struct task_struct *tsk) | |||
1070 | spin_unlock_irqrestore(&cputimer->lock, flags); | 1070 | spin_unlock_irqrestore(&cputimer->lock, flags); |
1071 | } | 1071 | } |
1072 | 1072 | ||
1073 | static void check_cpu_itimer(struct task_struct *tsk, struct cpu_itimer *it, | ||
1074 | cputime_t *expires, cputime_t cur_time, int signo) | ||
1075 | { | ||
1076 | if (cputime_eq(it->expires, cputime_zero)) | ||
1077 | return; | ||
1078 | |||
1079 | if (cputime_ge(cur_time, it->expires)) { | ||
1080 | it->expires = it->incr; | ||
1081 | if (!cputime_eq(it->expires, cputime_zero)) | ||
1082 | it->expires = cputime_add(it->expires, cur_time); | ||
1083 | |||
1084 | __group_send_sig_info(signo, SEND_SIG_PRIV, tsk); | ||
1085 | } | ||
1086 | |||
1087 | if (!cputime_eq(it->expires, cputime_zero) && | ||
1088 | (cputime_eq(*expires, cputime_zero) || | ||
1089 | cputime_lt(it->expires, *expires))) { | ||
1090 | *expires = it->expires; | ||
1091 | } | ||
1092 | } | ||
1093 | |||
1073 | /* | 1094 | /* |
1074 | * Check for any per-thread CPU timers that have fired and move them | 1095 | * Check for any per-thread CPU timers that have fired and move them |
1075 | * off the tsk->*_timers list onto the firing list. Per-thread timers | 1096 | * off the tsk->*_timers list onto the firing list. Per-thread timers |
@@ -1089,10 +1110,10 @@ static void check_process_timers(struct task_struct *tsk, | |||
1089 | * Don't sample the current process CPU clocks if there are no timers. | 1110 | * Don't sample the current process CPU clocks if there are no timers. |
1090 | */ | 1111 | */ |
1091 | if (list_empty(&timers[CPUCLOCK_PROF]) && | 1112 | if (list_empty(&timers[CPUCLOCK_PROF]) && |
1092 | cputime_eq(sig->it_prof_expires, cputime_zero) && | 1113 | cputime_eq(sig->it[CPUCLOCK_PROF].expires, cputime_zero) && |
1093 | sig->rlim[RLIMIT_CPU].rlim_cur == RLIM_INFINITY && | 1114 | sig->rlim[RLIMIT_CPU].rlim_cur == RLIM_INFINITY && |
1094 | list_empty(&timers[CPUCLOCK_VIRT]) && | 1115 | list_empty(&timers[CPUCLOCK_VIRT]) && |
1095 | cputime_eq(sig->it_virt_expires, cputime_zero) && | 1116 | cputime_eq(sig->it[CPUCLOCK_VIRT].expires, cputime_zero) && |
1096 | list_empty(&timers[CPUCLOCK_SCHED])) { | 1117 | list_empty(&timers[CPUCLOCK_SCHED])) { |
1097 | stop_process_timers(tsk); | 1118 | stop_process_timers(tsk); |
1098 | return; | 1119 | return; |
@@ -1152,38 +1173,11 @@ static void check_process_timers(struct task_struct *tsk, | |||
1152 | /* | 1173 | /* |
1153 | * Check for the special case process timers. | 1174 | * Check for the special case process timers. |
1154 | */ | 1175 | */ |
1155 | if (!cputime_eq(sig->it_prof_expires, cputime_zero)) { | 1176 | check_cpu_itimer(tsk, &sig->it[CPUCLOCK_PROF], &prof_expires, ptime, |
1156 | if (cputime_ge(ptime, sig->it_prof_expires)) { | 1177 | SIGPROF); |
1157 | /* ITIMER_PROF fires and reloads. */ | 1178 | check_cpu_itimer(tsk, &sig->it[CPUCLOCK_VIRT], &virt_expires, utime, |
1158 | sig->it_prof_expires = sig->it_prof_incr; | 1179 | SIGVTALRM); |
1159 | if (!cputime_eq(sig->it_prof_expires, cputime_zero)) { | 1180 | |
1160 | sig->it_prof_expires = cputime_add( | ||
1161 | sig->it_prof_expires, ptime); | ||
1162 | } | ||
1163 | __group_send_sig_info(SIGPROF, SEND_SIG_PRIV, tsk); | ||
1164 | } | ||
1165 | if (!cputime_eq(sig->it_prof_expires, cputime_zero) && | ||
1166 | (cputime_eq(prof_expires, cputime_zero) || | ||
1167 | cputime_lt(sig->it_prof_expires, prof_expires))) { | ||
1168 | prof_expires = sig->it_prof_expires; | ||
1169 | } | ||
1170 | } | ||
1171 | if (!cputime_eq(sig->it_virt_expires, cputime_zero)) { | ||
1172 | if (cputime_ge(utime, sig->it_virt_expires)) { | ||
1173 | /* ITIMER_VIRTUAL fires and reloads. */ | ||
1174 | sig->it_virt_expires = sig->it_virt_incr; | ||
1175 | if (!cputime_eq(sig->it_virt_expires, cputime_zero)) { | ||
1176 | sig->it_virt_expires = cputime_add( | ||
1177 | sig->it_virt_expires, utime); | ||
1178 | } | ||
1179 | __group_send_sig_info(SIGVTALRM, SEND_SIG_PRIV, tsk); | ||
1180 | } | ||
1181 | if (!cputime_eq(sig->it_virt_expires, cputime_zero) && | ||
1182 | (cputime_eq(virt_expires, cputime_zero) || | ||
1183 | cputime_lt(sig->it_virt_expires, virt_expires))) { | ||
1184 | virt_expires = sig->it_virt_expires; | ||
1185 | } | ||
1186 | } | ||
1187 | if (sig->rlim[RLIMIT_CPU].rlim_cur != RLIM_INFINITY) { | 1181 | if (sig->rlim[RLIMIT_CPU].rlim_cur != RLIM_INFINITY) { |
1188 | unsigned long psecs = cputime_to_secs(ptime); | 1182 | unsigned long psecs = cputime_to_secs(ptime); |
1189 | cputime_t x; | 1183 | cputime_t x; |