Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 333867
b: refs/heads/master
c: dae373b
h: refs/heads/master
i:
  333865: 0e55348
  333863: dbab111
v: v3
  • Loading branch information
John Stultz committed Sep 24, 2012
1 parent d481789 commit 786c8c4
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 69 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 59a93c27c4892f04dfd8f91f8b64d0d6eae43e6e
refs/heads/master: dae373be9fec6f850159a05af3a1c36236a70d43
3 changes: 2 additions & 1 deletion trunk/include/linux/alarmtimer.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ enum alarmtimer_restart {
*/
struct alarm {
struct timerqueue_node node;
struct hrtimer timer;
enum alarmtimer_restart (*function)(struct alarm *, ktime_t now);
enum alarmtimer_type type;
int state;
Expand All @@ -43,7 +44,7 @@ struct alarm {

void alarm_init(struct alarm *alarm, enum alarmtimer_type type,
enum alarmtimer_restart (*function)(struct alarm *, ktime_t));
void alarm_start(struct alarm *alarm, ktime_t start);
int alarm_start(struct alarm *alarm, ktime_t start);
int alarm_try_to_cancel(struct alarm *alarm);
int alarm_cancel(struct alarm *alarm);

Expand Down
94 changes: 27 additions & 67 deletions trunk/kernel/time/alarmtimer.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@
static struct alarm_base {
spinlock_t lock;
struct timerqueue_head timerqueue;
struct hrtimer timer;
ktime_t (*gettime)(void);
clockid_t base_clockid;
} alarm_bases[ALARM_NUMTYPE];
Expand Down Expand Up @@ -132,50 +131,35 @@ static inline void alarmtimer_rtc_timer_init(void) { }
* @base: pointer to the base where the timer is being run
* @alarm: pointer to alarm being enqueued.
*
* Adds alarm to a alarm_base timerqueue and if necessary sets
* an hrtimer to run.
* Adds alarm to a alarm_base timerqueue
*
* Must hold base->lock when calling.
*/
static void alarmtimer_enqueue(struct alarm_base *base, struct alarm *alarm)
{
if (alarm->state & ALARMTIMER_STATE_ENQUEUED)
timerqueue_del(&base->timerqueue, &alarm->node);

timerqueue_add(&base->timerqueue, &alarm->node);
alarm->state |= ALARMTIMER_STATE_ENQUEUED;

if (&alarm->node == timerqueue_getnext(&base->timerqueue)) {
hrtimer_try_to_cancel(&base->timer);
hrtimer_start(&base->timer, alarm->node.expires,
HRTIMER_MODE_ABS);
}
}

/**
* alarmtimer_remove - Removes an alarm timer from an alarm_base timerqueue
* @base: pointer to the base where the timer is running
* @alarm: pointer to alarm being removed
*
* Removes alarm to a alarm_base timerqueue and if necessary sets
* a new timer to run.
* Removes alarm to a alarm_base timerqueue
*
* Must hold base->lock when calling.
*/
static void alarmtimer_remove(struct alarm_base *base, struct alarm *alarm)
{
struct timerqueue_node *next = timerqueue_getnext(&base->timerqueue);

if (!(alarm->state & ALARMTIMER_STATE_ENQUEUED))
return;

timerqueue_del(&base->timerqueue, &alarm->node);
alarm->state &= ~ALARMTIMER_STATE_ENQUEUED;

if (next == &alarm->node) {
hrtimer_try_to_cancel(&base->timer);
next = timerqueue_getnext(&base->timerqueue);
if (!next)
return;
hrtimer_start(&base->timer, next->expires, HRTIMER_MODE_ABS);
}
}


Expand All @@ -190,42 +174,23 @@ static void alarmtimer_remove(struct alarm_base *base, struct alarm *alarm)
*/
static enum hrtimer_restart alarmtimer_fired(struct hrtimer *timer)
{
struct alarm_base *base = container_of(timer, struct alarm_base, timer);
struct timerqueue_node *next;
struct alarm *alarm = container_of(timer, struct alarm, timer);
struct alarm_base *base = &alarm_bases[alarm->type];
unsigned long flags;
ktime_t now;
int ret = HRTIMER_NORESTART;
int restart = ALARMTIMER_NORESTART;

spin_lock_irqsave(&base->lock, flags);
now = base->gettime();
while ((next = timerqueue_getnext(&base->timerqueue))) {
struct alarm *alarm;
ktime_t expired = next->expires;

if (expired.tv64 > now.tv64)
break;

alarm = container_of(next, struct alarm, node);

timerqueue_del(&base->timerqueue, &alarm->node);
alarm->state &= ~ALARMTIMER_STATE_ENQUEUED;

alarm->state |= ALARMTIMER_STATE_CALLBACK;
spin_unlock_irqrestore(&base->lock, flags);
if (alarm->function)
restart = alarm->function(alarm, now);
spin_lock_irqsave(&base->lock, flags);
alarm->state &= ~ALARMTIMER_STATE_CALLBACK;
alarmtimer_remove(base, alarm);
spin_unlock_irqrestore(&base->lock, flags);

if (restart != ALARMTIMER_NORESTART) {
timerqueue_add(&base->timerqueue, &alarm->node);
alarm->state |= ALARMTIMER_STATE_ENQUEUED;
}
}
if (alarm->function)
restart = alarm->function(alarm, base->gettime());

if (next) {
hrtimer_set_expires(&base->timer, next->expires);
spin_lock_irqsave(&base->lock, flags);
if (restart != ALARMTIMER_NORESTART) {
hrtimer_set_expires(&alarm->timer, alarm->node.expires);
alarmtimer_enqueue(base, alarm);
ret = HRTIMER_RESTART;
}
spin_unlock_irqrestore(&base->lock, flags);
Expand Down Expand Up @@ -331,6 +296,9 @@ void alarm_init(struct alarm *alarm, enum alarmtimer_type type,
enum alarmtimer_restart (*function)(struct alarm *, ktime_t))
{
timerqueue_init(&alarm->node);
hrtimer_init(&alarm->timer, alarm_bases[type].base_clockid,
HRTIMER_MODE_ABS);
alarm->timer.function = alarmtimer_fired;
alarm->function = function;
alarm->type = type;
alarm->state = ALARMTIMER_STATE_INACTIVE;
Expand All @@ -341,17 +309,19 @@ void alarm_init(struct alarm *alarm, enum alarmtimer_type type,
* @alarm: ptr to alarm to set
* @start: time to run the alarm
*/
void alarm_start(struct alarm *alarm, ktime_t start)
int alarm_start(struct alarm *alarm, ktime_t start)
{
struct alarm_base *base = &alarm_bases[alarm->type];
unsigned long flags;
int ret;

spin_lock_irqsave(&base->lock, flags);
if (alarmtimer_active(alarm))
alarmtimer_remove(base, alarm);
alarm->node.expires = start;
alarmtimer_enqueue(base, alarm);
ret = hrtimer_start(&alarm->timer, alarm->node.expires,
HRTIMER_MODE_ABS);
spin_unlock_irqrestore(&base->lock, flags);
return ret;
}

/**
Expand All @@ -365,18 +335,12 @@ int alarm_try_to_cancel(struct alarm *alarm)
{
struct alarm_base *base = &alarm_bases[alarm->type];
unsigned long flags;
int ret = -1;
spin_lock_irqsave(&base->lock, flags);

if (alarmtimer_callback_running(alarm))
goto out;
int ret;

if (alarmtimer_is_queued(alarm)) {
spin_lock_irqsave(&base->lock, flags);
ret = hrtimer_try_to_cancel(&alarm->timer);
if (ret >= 0)
alarmtimer_remove(base, alarm);
ret = 1;
} else
ret = 0;
out:
spin_unlock_irqrestore(&base->lock, flags);
return ret;
}
Expand Down Expand Up @@ -809,10 +773,6 @@ static int __init alarmtimer_init(void)
for (i = 0; i < ALARM_NUMTYPE; i++) {
timerqueue_init_head(&alarm_bases[i].timerqueue);
spin_lock_init(&alarm_bases[i].lock);
hrtimer_init(&alarm_bases[i].timer,
alarm_bases[i].base_clockid,
HRTIMER_MODE_ABS);
alarm_bases[i].timer.function = alarmtimer_fired;
}

error = alarmtimer_rtc_interface_setup();
Expand Down

0 comments on commit 786c8c4

Please sign in to comment.