Skip to content

Commit

Permalink
posix_cpu_timers: consolidate expired timers check
Browse files Browse the repository at this point in the history
Consolidate the common code amongst per thread and per process timers list
on tick time.

List traversal, expiry check and subsequent updates can be shared in a
common helper.

Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Stanislaw Gruszka <sgruszka@redhat.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Oleg Nesterov <oleg@redhat.com>
Cc: KOSAKI Motohiro <kosaki.motohiro@gmail.com>
Cc: Olivier Langlois <olivier@trillion01.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
  • Loading branch information
Frederic Weisbecker committed Jul 3, 2013
1 parent 1a7fa51 commit 2473f3e
Showing 1 changed file with 33 additions and 85 deletions.
118 changes: 33 additions & 85 deletions kernel/posix-cpu-timers.c
Original file line number Diff line number Diff line change
Expand Up @@ -862,6 +862,28 @@ static void posix_cpu_timer_get(struct k_itimer *timer, struct itimerspec *itp)
}
}

static unsigned long long
check_timers_list(struct list_head *timers,
struct list_head *firing,
unsigned long long curr)
{
int maxfire = 20;

while (!list_empty(timers)) {
struct cpu_timer_list *t;

t = list_first_entry(timers, struct cpu_timer_list, entry);

if (!--maxfire || curr < t->expires)
return t->expires;

t->firing = 1;
list_move_tail(&t->entry, firing);
}

return 0;
}

/*
* Check for any per-thread CPU timers that have fired and move them off
* the tsk->cpu_timers[N] list onto the firing list. Here we update the
Expand All @@ -870,54 +892,20 @@ static void posix_cpu_timer_get(struct k_itimer *timer, struct itimerspec *itp)
static void check_thread_timers(struct task_struct *tsk,
struct list_head *firing)
{
int maxfire;
struct list_head *timers = tsk->cpu_timers;
struct signal_struct *const sig = tsk->signal;
struct task_cputime *tsk_expires = &tsk->cputime_expires;
unsigned long long expires;
unsigned long soft;

maxfire = 20;
tsk->cputime_expires.prof_exp = 0;
while (!list_empty(timers)) {
struct cpu_timer_list *t = list_first_entry(timers,
struct cpu_timer_list,
entry);
if (!--maxfire || prof_ticks(tsk) < t->expires) {
tsk->cputime_expires.prof_exp = expires_to_cputime(t->expires);
break;
}
t->firing = 1;
list_move_tail(&t->entry, firing);
}
expires = check_timers_list(timers, firing, prof_ticks(tsk));
tsk_expires->prof_exp = expires_to_cputime(expires);

++timers;
maxfire = 20;
tsk->cputime_expires.virt_exp = 0;
while (!list_empty(timers)) {
struct cpu_timer_list *t = list_first_entry(timers,
struct cpu_timer_list,
entry);
if (!--maxfire || virt_ticks(tsk) < t->expires) {
tsk->cputime_expires.virt_exp = expires_to_cputime(t->expires);
break;
}
t->firing = 1;
list_move_tail(&t->entry, firing);
}
expires = check_timers_list(++timers, firing, virt_ticks(tsk));
tsk_expires->virt_exp = expires_to_cputime(expires);

++timers;
maxfire = 20;
tsk->cputime_expires.sched_exp = 0;
while (!list_empty(timers)) {
struct cpu_timer_list *t = list_first_entry(timers,
struct cpu_timer_list,
entry);
if (!--maxfire || tsk->se.sum_exec_runtime < t->expires) {
tsk->cputime_expires.sched_exp = t->expires;
break;
}
t->firing = 1;
list_move_tail(&t->entry, firing);
}
tsk_expires->sched_exp = check_timers_list(++timers, firing,
tsk->se.sum_exec_runtime);

/*
* Check for the special case thread timers.
Expand Down Expand Up @@ -1002,7 +990,6 @@ static void check_cpu_itimer(struct task_struct *tsk, struct cpu_itimer *it,
static void check_process_timers(struct task_struct *tsk,
struct list_head *firing)
{
int maxfire;
struct signal_struct *const sig = tsk->signal;
unsigned long long utime, ptime, virt_expires, prof_expires;
unsigned long long sum_sched_runtime, sched_expires;
Expand All @@ -1017,49 +1004,10 @@ static void check_process_timers(struct task_struct *tsk,
utime = cputime_to_expires(cputime.utime);
ptime = utime + cputime_to_expires(cputime.stime);
sum_sched_runtime = cputime.sum_exec_runtime;
maxfire = 20;
prof_expires = 0;
while (!list_empty(timers)) {
struct cpu_timer_list *tl = list_first_entry(timers,
struct cpu_timer_list,
entry);
if (!--maxfire || ptime < tl->expires) {
prof_expires = tl->expires;
break;
}
tl->firing = 1;
list_move_tail(&tl->entry, firing);
}

++timers;
maxfire = 20;
virt_expires = 0;
while (!list_empty(timers)) {
struct cpu_timer_list *tl = list_first_entry(timers,
struct cpu_timer_list,
entry);
if (!--maxfire || utime < tl->expires) {
virt_expires = tl->expires;
break;
}
tl->firing = 1;
list_move_tail(&tl->entry, firing);
}

++timers;
maxfire = 20;
sched_expires = 0;
while (!list_empty(timers)) {
struct cpu_timer_list *tl = list_first_entry(timers,
struct cpu_timer_list,
entry);
if (!--maxfire || sum_sched_runtime < tl->expires) {
sched_expires = tl->expires;
break;
}
tl->firing = 1;
list_move_tail(&tl->entry, firing);
}
prof_expires = check_timers_list(timers, firing, ptime);
virt_expires = check_timers_list(++timers, firing, utime);
sched_expires = check_timers_list(++timers, firing, sum_sched_runtime);

/*
* Check for the special case process timers.
Expand Down

0 comments on commit 2473f3e

Please sign in to comment.