aboutsummaryrefslogtreecommitdiffstats
path: root/xen/common/timer.c
diff options
context:
space:
mode:
authorKeir Fraser <keir.fraser@citrix.com>2010-08-18 14:56:01 +0100
committerKeir Fraser <keir.fraser@citrix.com>2010-08-18 14:56:01 +0100
commit116d62ddfd1157364e2e5a2a44ef89573da37595 (patch)
tree137eba64fb80d0c04b52765a5a280ac8399bc0a2 /xen/common/timer.c
parent6d91c142bca75bbac5bbc4ecea5da47967b6797b (diff)
downloadxen-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.c63
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);