aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/posix-cpu-timers.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/posix-cpu-timers.c')
-rw-r--r--kernel/posix-cpu-timers.c98
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 */
15void update_rlimit_cpu(unsigned long rlim_new) 15void 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(&current->sighand->siglock); 22 spin_lock_irq(&current->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(&current->sighand->siglock); 24 spin_unlock_irq(&current->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
1073static 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;