list_add(&timer->inactive, &per_cpu(timers, timer->cpu).inactive);
}
-static inline void timer_lock(struct timer *timer)
+static inline bool_t timer_lock(struct timer *timer)
{
unsigned int cpu;
for ( ; ; )
{
cpu = timer->cpu;
+ if ( unlikely(timer->status == TIMER_STATUS_killed) )
+ return 0;
ASSERT(cpu_isset(cpu, timer_valid_cpumask));
spin_lock(&per_cpu(timers, cpu).lock);
- if ( likely(timer->cpu == cpu) )
+ if ( likely(timer->cpu == cpu) &&
+ likely(timer->status != TIMER_STATUS_killed) )
break;
spin_unlock(&per_cpu(timers, cpu).lock);
}
+
+ return 1;
}
-#define timer_lock_irq(t) \
- do { local_irq_disable(); timer_lock(t); } while ( 0 )
-#define timer_lock_irqsave(t, flags) \
- do { local_irq_save(flags); timer_lock(t); } while ( 0 )
+#define timer_lock_irqsave(t, flags) ({ \
+ bool_t __x; \
+ local_irq_save(flags); \
+ if ( !(__x = timer_lock(t)) ) \
+ local_irq_restore(flags); \
+ __x; \
+})
static inline void timer_unlock(struct timer *timer)
{
spin_unlock(&per_cpu(timers, timer->cpu).lock);
}
-#define timer_unlock_irq(t) \
- do { timer_unlock(t); local_irq_enable(); } while ( 0 )
-#define timer_unlock_irqrestore(t, flags) \
- do { timer_unlock(t); local_irq_restore(flags); } while ( 0 )
+#define timer_unlock_irqrestore(t, flags) ({ \
+ timer_unlock(t); \
+ local_irq_restore(flags); \
+})
static bool_t active_timer(struct timer *timer)
timer->data = data;
timer->cpu = cpu;
timer->status = TIMER_STATUS_inactive;
- timer_lock_irqsave(timer, flags);
+ if ( !timer_lock_irqsave(timer, flags) )
+ BUG();
list_add(&timer->inactive, &per_cpu(timers, cpu).inactive);
timer_unlock_irqrestore(timer, flags);
}
{
unsigned long flags;
- timer_lock_irqsave(timer, flags);
+ if ( !timer_lock_irqsave(timer, flags) )
+ return;
if ( active_timer(timer) )
deactivate_timer(timer);
timer->expires = expires;
timer->expires_end = expires + timer_slop;
- if ( likely(timer->status != TIMER_STATUS_killed) )
- activate_timer(timer);
+ activate_timer(timer);
timer_unlock_irqrestore(timer, flags);
}
{
unsigned long flags;
- timer_lock_irqsave(timer, flags);
+ if ( !timer_lock_irqsave(timer, flags) )
+ return;
if ( active_timer(timer) )
deactivate_timer(timer);
for ( ; ; )
{
- if ( (old_cpu = timer->cpu) == new_cpu )
+ if ( ((old_cpu = timer->cpu) == new_cpu) ||
+ unlikely(timer->status == TIMER_STATUS_killed) )
return;
ASSERT(cpu_isset(old_cpu, timer_valid_cpumask));
spin_lock(&per_cpu(timers, old_cpu).lock);
}
- if ( likely(timer->cpu == old_cpu) )
+ if ( likely(timer->cpu == old_cpu) &&
+ likely(timer->status != TIMER_STATUS_killed) )
break;
spin_unlock(&per_cpu(timers, old_cpu).lock);
BUG_ON(this_cpu(timers).running == timer);
- timer_lock_irqsave(timer, flags);
+ if ( !timer_lock_irqsave(timer, flags) )
+ return;
if ( active_timer(timer) )
deactivate_timer(timer);