diff options
author | Keir Fraser <keir.fraser@citrix.com> | 2010-08-18 14:56:01 +0100 |
---|---|---|
committer | Keir Fraser <keir.fraser@citrix.com> | 2010-08-18 14:56:01 +0100 |
commit | 116d62ddfd1157364e2e5a2a44ef89573da37595 (patch) | |
tree | 137eba64fb80d0c04b52765a5a280ac8399bc0a2 /xen/common/timer.c | |
parent | 6d91c142bca75bbac5bbc4ecea5da47967b6797b (diff) | |
download | xen-116d62ddfd1157364e2e5a2a44ef89573da37595.tar.gz xen-116d62ddfd1157364e2e5a2a44ef89573da37595.tar.bz2 xen-116d62ddfd1157364e2e5a2a44ef89573da37595.zip |
timers: Simplify implementation logic.
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
Diffstat (limited to 'xen/common/timer.c')
-rw-r--r-- | xen/common/timer.c | 63 |
1 files changed, 13 insertions, 50 deletions
diff --git a/xen/common/timer.c b/xen/common/timer.c index 52283cfad0..648f299dfd 100644 --- a/xen/common/timer.c +++ b/xen/common/timer.c @@ -23,16 +23,12 @@ #include <asm/system.h> #include <asm/desc.h> -/* - * We pull handlers off the timer list this far in future, - * rather than reprogramming the time hardware. - */ +/* We program the time hardware this far behind the closest deadline. */ static unsigned int timer_slop __read_mostly = 50000; /* 50 us */ integer_param("timer_slop", timer_slop); struct timers { spinlock_t lock; - bool_t overflow; struct timer **heap; struct timer *list; struct timer *running; @@ -43,8 +39,7 @@ static DEFINE_PER_CPU(struct timers, timers); static cpumask_t timer_valid_cpumask; -DEFINE_PER_CPU(s_time_t, timer_deadline_start); -DEFINE_PER_CPU(s_time_t, timer_deadline_end); +DEFINE_PER_CPU(s_time_t, timer_deadline); /**************************************************************************** * HEAP OPERATIONS. @@ -210,7 +205,6 @@ static int add_entry(struct timer *t) return rc; /* Fall back to adding to the slower linked list. */ - timers->overflow = 1; t->status = TIMER_STATUS_in_list; return add_to_list(&timers->list, t); } @@ -311,7 +305,6 @@ void set_timer(struct timer *timer, s_time_t expires) deactivate_timer(timer); timer->expires = expires; - timer->expires_end = expires + timer_slop; activate_timer(timer); @@ -427,13 +420,13 @@ static void timer_softirq_action(void) { struct timer *t, **heap, *next; struct timers *ts; - s_time_t now; + s_time_t now, deadline; ts = &this_cpu(timers); heap = ts->heap; /* If we overflowed the heap, try to allocate a larger heap. */ - if ( unlikely(ts->overflow) ) + if ( unlikely(ts->list != NULL) ) { /* old_limit == (2^n)-1; new_limit == (2^(n+4))-1 */ int old_limit = GET_HEAP_LIMIT(heap); @@ -481,46 +474,16 @@ static void timer_softirq_action(void) add_entry(t); } - ts->overflow = (ts->list != NULL); - if ( unlikely(ts->overflow) ) - { - /* Find earliest deadline at head of list or top of heap. */ - this_cpu(timer_deadline_start) = ts->list->expires; - if ( (GET_HEAP_SIZE(heap) != 0) && - ((t = heap[1])->expires < this_cpu(timer_deadline_start)) ) - this_cpu(timer_deadline_start) = t->expires; - this_cpu(timer_deadline_end) = this_cpu(timer_deadline_start); - } - else - { - /* - * Find the earliest deadline that encompasses largest number of timers - * on the heap. To do this we take timers from the heap while their - * valid deadline ranges continue to intersect. - */ - s_time_t start = 0, end = STIME_MAX; - struct timer **list_tail = &ts->list; - - while ( (GET_HEAP_SIZE(heap) != 0) && - ((t = heap[1])->expires <= end) ) - { - remove_entry(t); - - t->status = TIMER_STATUS_in_list; - t->list_next = NULL; - *list_tail = t; - list_tail = &t->list_next; - - start = t->expires; - if ( end > t->expires_end ) - end = t->expires_end; - } - - this_cpu(timer_deadline_start) = start; - this_cpu(timer_deadline_end) = end; - } + /* Find earliest deadline from head of linked list and top of heap. */ + deadline = STIME_MAX; + if ( GET_HEAP_SIZE(heap) != 0 ) + deadline = heap[1]->expires; + if ( (ts->list != NULL) && (ts->list->expires < deadline) ) + deadline = ts->list->expires; + this_cpu(timer_deadline) = + (deadline == STIME_MAX) ? 0 : deadline + timer_slop; - if ( !reprogram_timer(this_cpu(timer_deadline_start)) ) + if ( !reprogram_timer(this_cpu(timer_deadline)) ) raise_softirq(TIMER_SOFTIRQ); spin_unlock_irq(&ts->lock); |