cpu-timers: Cleanup arm_timer()

Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Oleg Nesterov <oleg@redhat.com>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Hidetoshi Seto <seto.hidetoshi@jp.fujitsu.com>
Cc: Balbir Singh <balbir@in.ibm.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
This commit is contained in:
Stanislaw Gruszka 2010-03-11 14:04:38 -08:00 committed by Thomas Gleixner
parent f55db60904
commit 5eb9aa6414
1 changed files with 35 additions and 69 deletions

View File

@ -547,97 +547,63 @@ static inline int expires_gt(cputime_t expires, cputime_t new_exp)
cputime_gt(expires, new_exp); cputime_gt(expires, new_exp);
} }
static inline int expires_le(cputime_t expires, cputime_t new_exp)
{
return !cputime_eq(expires, cputime_zero) &&
cputime_le(expires, new_exp);
}
/* /*
* Insert the timer on the appropriate list before any timers that * Insert the timer on the appropriate list before any timers that
* expire later. This must be called with the tasklist_lock held * expire later. This must be called with the tasklist_lock held
* for reading, and interrupts disabled. * for reading, and interrupts disabled.
*/ */
static void arm_timer(struct k_itimer *timer, union cpu_time_count now) static void arm_timer(struct k_itimer *timer)
{ {
struct task_struct *p = timer->it.cpu.task; struct task_struct *p = timer->it.cpu.task;
struct list_head *head, *listpos; struct list_head *head, *listpos;
struct task_cputime *cputime_expires;
struct cpu_timer_list *const nt = &timer->it.cpu; struct cpu_timer_list *const nt = &timer->it.cpu;
struct cpu_timer_list *next; struct cpu_timer_list *next;
head = (CPUCLOCK_PERTHREAD(timer->it_clock) ? if (CPUCLOCK_PERTHREAD(timer->it_clock)) {
p->cpu_timers : p->signal->cpu_timers); head = p->cpu_timers;
cputime_expires = &p->cputime_expires;
} else {
head = p->signal->cpu_timers;
cputime_expires = &p->signal->cputime_expires;
}
head += CPUCLOCK_WHICH(timer->it_clock); head += CPUCLOCK_WHICH(timer->it_clock);
BUG_ON(!irqs_disabled()); BUG_ON(!irqs_disabled());
spin_lock(&p->sighand->siglock); spin_lock(&p->sighand->siglock);
listpos = head; listpos = head;
if (CPUCLOCK_WHICH(timer->it_clock) == CPUCLOCK_SCHED) { list_for_each_entry(next, head, entry) {
list_for_each_entry(next, head, entry) { if (cpu_time_before(timer->it_clock, nt->expires, next->expires))
if (next->expires.sched > nt->expires.sched) break;
break; listpos = &next->entry;
listpos = &next->entry;
}
} else {
list_for_each_entry(next, head, entry) {
if (cputime_gt(next->expires.cpu, nt->expires.cpu))
break;
listpos = &next->entry;
}
} }
list_add(&nt->entry, listpos); list_add(&nt->entry, listpos);
if (listpos == head) { if (listpos == head) {
union cpu_time_count *exp = &nt->expires;
/* /*
* We are the new earliest-expiring timer. * We are the new earliest-expiring POSIX 1.b timer, hence
* If we are a thread timer, there can always * need to update expiration cache. Take into account that
* be a process timer telling us to stop earlier. * for process timers we share expiration cache with itimers
* and RLIMIT_CPU and for thread timers with RLIMIT_RTTIME.
*/ */
if (CPUCLOCK_PERTHREAD(timer->it_clock)) { switch (CPUCLOCK_WHICH(timer->it_clock)) {
union cpu_time_count *exp = &nt->expires; case CPUCLOCK_PROF:
if (expires_gt(cputime_expires->prof_exp, exp->cpu))
switch (CPUCLOCK_WHICH(timer->it_clock)) { cputime_expires->prof_exp = exp->cpu;
default: break;
BUG(); case CPUCLOCK_VIRT:
case CPUCLOCK_PROF: if (expires_gt(cputime_expires->virt_exp, exp->cpu))
if (expires_gt(p->cputime_expires.prof_exp, cputime_expires->virt_exp = exp->cpu;
exp->cpu)) break;
p->cputime_expires.prof_exp = exp->cpu; case CPUCLOCK_SCHED:
break; if (cputime_expires->sched_exp == 0 ||
case CPUCLOCK_VIRT: cputime_expires->sched_exp > exp->sched)
if (expires_gt(p->cputime_expires.virt_exp, cputime_expires->sched_exp = exp->sched;
exp->cpu)) break;
p->cputime_expires.virt_exp = exp->cpu;
break;
case CPUCLOCK_SCHED:
if (p->cputime_expires.sched_exp == 0 ||
p->cputime_expires.sched_exp > exp->sched)
p->cputime_expires.sched_exp =
exp->sched;
break;
}
} else {
struct signal_struct *const sig = p->signal;
union cpu_time_count *exp = &timer->it.cpu.expires;
/*
* For a process timer, set the cached expiration time.
*/
switch (CPUCLOCK_WHICH(timer->it_clock)) {
default:
BUG();
case CPUCLOCK_VIRT:
if (expires_gt(sig->cputime_expires.virt_exp, exp->cpu))
sig->cputime_expires.virt_exp = exp->cpu;
case CPUCLOCK_PROF:
if (expires_gt(sig->cputime_expires.prof_exp, exp->cpu))
sig->cputime_expires.prof_exp = exp->cpu;
break;
case CPUCLOCK_SCHED:
sig->cputime_expires.sched_exp = exp->sched;
break;
}
} }
} }
@ -819,7 +785,7 @@ int posix_cpu_timer_set(struct k_itimer *timer, int flags,
if (new_expires.sched != 0 && if (new_expires.sched != 0 &&
(timer->it_sigev_notify & ~SIGEV_THREAD_ID) != SIGEV_NONE && (timer->it_sigev_notify & ~SIGEV_THREAD_ID) != SIGEV_NONE &&
cpu_time_before(timer->it_clock, val, new_expires)) { cpu_time_before(timer->it_clock, val, new_expires)) {
arm_timer(timer, val); arm_timer(timer);
} }
read_unlock(&tasklist_lock); read_unlock(&tasklist_lock);
@ -1283,7 +1249,7 @@ void posix_cpu_timer_schedule(struct k_itimer *timer)
/* /*
* Now re-arm for the new expiry time. * Now re-arm for the new expiry time.
*/ */
arm_timer(timer, now); arm_timer(timer);
out_unlock: out_unlock:
read_unlock(&tasklist_lock); read_unlock(&tasklist_lock);