aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/time/alarmtimer.c
diff options
context:
space:
mode:
authorJohn Stultz <john.stultz@linaro.org>2011-08-10 15:30:21 -0400
committerJohn Stultz <john.stultz@linaro.org>2011-08-10 17:55:27 -0400
commita28cde81ab13cc251748a4c4ef06883dd09a10ea (patch)
treeb38ce180912957731cfe736d1d3f978342d099e1 /kernel/time/alarmtimer.c
parent9e26476243e438f4534a562660c1296a15a9e202 (diff)
alarmtimers: Add more refined alarm state tracking
In order to allow for functionality like try_to_cancel, add more refined state tracking (similar to hrtimers). CC: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: John Stultz <john.stultz@linaro.org>
Diffstat (limited to 'kernel/time/alarmtimer.c')
-rw-r--r--kernel/time/alarmtimer.c21
1 files changed, 14 insertions, 7 deletions
diff --git a/kernel/time/alarmtimer.c b/kernel/time/alarmtimer.c
index 90935591dd44..5b14cc29b6a6 100644
--- a/kernel/time/alarmtimer.c
+++ b/kernel/time/alarmtimer.c
@@ -126,6 +126,8 @@ static struct rtc_device *alarmtimer_get_rtcdev(void)
126static void alarmtimer_enqueue(struct alarm_base *base, struct alarm *alarm) 126static void alarmtimer_enqueue(struct alarm_base *base, struct alarm *alarm)
127{ 127{
128 timerqueue_add(&base->timerqueue, &alarm->node); 128 timerqueue_add(&base->timerqueue, &alarm->node);
129 alarm->state |= ALARMTIMER_STATE_ENQUEUED;
130
129 if (&alarm->node == timerqueue_getnext(&base->timerqueue)) { 131 if (&alarm->node == timerqueue_getnext(&base->timerqueue)) {
130 hrtimer_try_to_cancel(&base->timer); 132 hrtimer_try_to_cancel(&base->timer);
131 hrtimer_start(&base->timer, alarm->node.expires, 133 hrtimer_start(&base->timer, alarm->node.expires,
@@ -147,7 +149,12 @@ static void alarmtimer_remove(struct alarm_base *base, struct alarm *alarm)
147{ 149{
148 struct timerqueue_node *next = timerqueue_getnext(&base->timerqueue); 150 struct timerqueue_node *next = timerqueue_getnext(&base->timerqueue);
149 151
152 if (!(alarm->state & ALARMTIMER_STATE_ENQUEUED))
153 return;
154
150 timerqueue_del(&base->timerqueue, &alarm->node); 155 timerqueue_del(&base->timerqueue, &alarm->node);
156 alarm->state &= ~ALARMTIMER_STATE_ENQUEUED;
157
151 if (next == &alarm->node) { 158 if (next == &alarm->node) {
152 hrtimer_try_to_cancel(&base->timer); 159 hrtimer_try_to_cancel(&base->timer);
153 next = timerqueue_getnext(&base->timerqueue); 160 next = timerqueue_getnext(&base->timerqueue);
@@ -188,16 +195,18 @@ static enum hrtimer_restart alarmtimer_fired(struct hrtimer *timer)
188 alarm = container_of(next, struct alarm, node); 195 alarm = container_of(next, struct alarm, node);
189 196
190 timerqueue_del(&base->timerqueue, &alarm->node); 197 timerqueue_del(&base->timerqueue, &alarm->node);
191 alarm->enabled = 0; 198 alarm->state &= ~ALARMTIMER_STATE_ENQUEUED;
192 199
200 alarm->state |= ALARMTIMER_STATE_CALLBACK;
193 spin_unlock_irqrestore(&base->lock, flags); 201 spin_unlock_irqrestore(&base->lock, flags);
194 if (alarm->function) 202 if (alarm->function)
195 restart = alarm->function(alarm, now); 203 restart = alarm->function(alarm, now);
196 spin_lock_irqsave(&base->lock, flags); 204 spin_lock_irqsave(&base->lock, flags);
205 alarm->state &= ~ALARMTIMER_STATE_CALLBACK;
197 206
198 if (restart != ALARMTIMER_NORESTART) { 207 if (restart != ALARMTIMER_NORESTART) {
199 timerqueue_add(&base->timerqueue, &alarm->node); 208 timerqueue_add(&base->timerqueue, &alarm->node);
200 alarm->enabled = 1; 209 alarm->state |= ALARMTIMER_STATE_ENQUEUED;
201 } 210 }
202 } 211 }
203 212
@@ -305,7 +314,7 @@ void alarm_init(struct alarm *alarm, enum alarmtimer_type type,
305 timerqueue_init(&alarm->node); 314 timerqueue_init(&alarm->node);
306 alarm->function = function; 315 alarm->function = function;
307 alarm->type = type; 316 alarm->type = type;
308 alarm->enabled = 0; 317 alarm->state = ALARMTIMER_STATE_INACTIVE;
309} 318}
310 319
311/** 320/**
@@ -319,11 +328,10 @@ void alarm_start(struct alarm *alarm, ktime_t start)
319 unsigned long flags; 328 unsigned long flags;
320 329
321 spin_lock_irqsave(&base->lock, flags); 330 spin_lock_irqsave(&base->lock, flags);
322 if (alarm->enabled) 331 if (alarmtimer_active(alarm))
323 alarmtimer_remove(base, alarm); 332 alarmtimer_remove(base, alarm);
324 alarm->node.expires = start; 333 alarm->node.expires = start;
325 alarmtimer_enqueue(base, alarm); 334 alarmtimer_enqueue(base, alarm);
326 alarm->enabled = 1;
327 spin_unlock_irqrestore(&base->lock, flags); 335 spin_unlock_irqrestore(&base->lock, flags);
328} 336}
329 337
@@ -337,9 +345,8 @@ void alarm_cancel(struct alarm *alarm)
337 unsigned long flags; 345 unsigned long flags;
338 346
339 spin_lock_irqsave(&base->lock, flags); 347 spin_lock_irqsave(&base->lock, flags);
340 if (alarm->enabled) 348 if (alarmtimer_is_queued(alarm))
341 alarmtimer_remove(base, alarm); 349 alarmtimer_remove(base, alarm);
342 alarm->enabled = 0;
343 spin_unlock_irqrestore(&base->lock, flags); 350 spin_unlock_irqrestore(&base->lock, flags);
344} 351}
345 352