Commit 4d888117 authored by Andrew Morton's avatar Andrew Morton Committed by Dave Jones

[PATCH] timer code cleanup

- Use list_head functions rather than open-coding them

- Use time comparison macros rather than open-coding them

- Hide some ifdefs

- uninline internal_add_timer().  Saves half a kilobyte of text.
parent 0d61cac6
...@@ -53,7 +53,6 @@ typedef struct tvec_root_s { ...@@ -53,7 +53,6 @@ typedef struct tvec_root_s {
struct list_head vec[TVR_SIZE]; struct list_head vec[TVR_SIZE];
} tvec_root_t; } tvec_root_t;
struct tvec_t_base_s { struct tvec_t_base_s {
spinlock_t lock; spinlock_t lock;
unsigned long timer_jiffies; unsigned long timer_jiffies;
...@@ -67,6 +66,14 @@ struct tvec_t_base_s { ...@@ -67,6 +66,14 @@ struct tvec_t_base_s {
typedef struct tvec_t_base_s tvec_base_t; typedef struct tvec_t_base_s tvec_base_t;
static inline void set_running_timer(tvec_base_t *base,
struct timer_list *timer)
{
#ifdef CONFIG_SMP
base->running_timer = timer;
#endif
}
/* Fake initialization */ /* Fake initialization */
static DEFINE_PER_CPU(tvec_base_t, tvec_bases) = { SPIN_LOCK_UNLOCKED }; static DEFINE_PER_CPU(tvec_base_t, tvec_bases) = { SPIN_LOCK_UNLOCKED };
...@@ -94,7 +101,7 @@ static inline void check_timer(struct timer_list *timer) ...@@ -94,7 +101,7 @@ static inline void check_timer(struct timer_list *timer)
check_timer_failed(timer); check_timer_failed(timer);
} }
static inline void internal_add_timer(tvec_base_t *base, struct timer_list *timer) static void internal_add_timer(tvec_base_t *base, struct timer_list *timer)
{ {
unsigned long expires = timer->expires; unsigned long expires = timer->expires;
unsigned long idx = expires - base->timer_jiffies; unsigned long idx = expires - base->timer_jiffies;
...@@ -354,7 +361,7 @@ int del_timer_sync(struct timer_list *timer) ...@@ -354,7 +361,7 @@ int del_timer_sync(struct timer_list *timer)
static int cascade(tvec_base_t *base, tvec_t *tv) static int cascade(tvec_base_t *base, tvec_t *tv)
{ {
/* cascade all the timers from tv up one level */ /* cascade all the timers from tv up one level */
struct list_head *head, *curr, *next; struct list_head *head, *curr;
head = tv->vec + tv->index; head = tv->vec + tv->index;
curr = head->next; curr = head->next;
...@@ -366,11 +373,9 @@ static int cascade(tvec_base_t *base, tvec_t *tv) ...@@ -366,11 +373,9 @@ static int cascade(tvec_base_t *base, tvec_t *tv)
struct timer_list *tmp; struct timer_list *tmp;
tmp = list_entry(curr, struct timer_list, entry); tmp = list_entry(curr, struct timer_list, entry);
if (tmp->base != base) BUG_ON(tmp->base != base);
BUG(); curr = curr->next;
next = curr->next;
internal_add_timer(base, tmp); internal_add_timer(base, tmp);
curr = next;
} }
INIT_LIST_HEAD(head); INIT_LIST_HEAD(head);
...@@ -387,8 +392,8 @@ static int cascade(tvec_base_t *base, tvec_t *tv) ...@@ -387,8 +392,8 @@ static int cascade(tvec_base_t *base, tvec_t *tv)
static inline void __run_timers(tvec_base_t *base) static inline void __run_timers(tvec_base_t *base)
{ {
spin_lock_irq(&base->lock); spin_lock_irq(&base->lock);
while ((long)(jiffies - base->timer_jiffies) >= 0) { while (time_after_eq(jiffies, base->timer_jiffies)) {
struct list_head *head, *curr; struct list_head *head;
/* /*
* Cascade timers: * Cascade timers:
...@@ -400,35 +405,27 @@ static inline void __run_timers(tvec_base_t *base) ...@@ -400,35 +405,27 @@ static inline void __run_timers(tvec_base_t *base)
cascade(base, &base->tv5); cascade(base, &base->tv5);
repeat: repeat:
head = base->tv1.vec + base->tv1.index; head = base->tv1.vec + base->tv1.index;
curr = head->next; if (!list_empty(head)) {
if (curr != head) {
void (*fn)(unsigned long); void (*fn)(unsigned long);
unsigned long data; unsigned long data;
struct timer_list *timer; struct timer_list *timer;
timer = list_entry(curr, struct timer_list, entry); timer = list_entry(head->next,struct timer_list,entry);
fn = timer->function; fn = timer->function;
data = timer->data; data = timer->data;
list_del(&timer->entry); list_del(&timer->entry);
timer->base = NULL; timer->base = NULL;
#if CONFIG_SMP set_running_timer(base, timer);
base->running_timer = timer;
#endif
spin_unlock_irq(&base->lock); spin_unlock_irq(&base->lock);
if (!fn) fn(data);
printk("Bad: timer %p has NULL fn. (data: %08lx)\n", timer, data);
else
fn(data);
spin_lock_irq(&base->lock); spin_lock_irq(&base->lock);
goto repeat; goto repeat;
} }
++base->timer_jiffies; ++base->timer_jiffies;
base->tv1.index = (base->tv1.index + 1) & TVR_MASK; base->tv1.index = (base->tv1.index + 1) & TVR_MASK;
} }
#if CONFIG_SMP set_running_timer(base, NULL);
base->running_timer = NULL;
#endif
spin_unlock_irq(&base->lock); spin_unlock_irq(&base->lock);
} }
...@@ -775,7 +772,7 @@ static void run_timer_softirq(struct softirq_action *h) ...@@ -775,7 +772,7 @@ static void run_timer_softirq(struct softirq_action *h)
{ {
tvec_base_t *base = &per_cpu(tvec_bases, smp_processor_id()); tvec_base_t *base = &per_cpu(tvec_bases, smp_processor_id());
if ((long)(jiffies - base->timer_jiffies) >= 0) if (time_after_eq(jiffies, base->timer_jiffies))
__run_timers(base); __run_timers(base);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment