![Thomas Gleixner](/assets/img/avatar_default.png)
For CONFIG_NO_HZ we need to calculate the next timer wheel event based on a given jiffie value. Extend the existing code to allow the extra 'now' argument. Provide a compability function for the existing implementations to call the function with now == jiffies. (This also solves the racyness of the original code vs. jiffies changing during the iteration.) No functional changes to existing users of this infrastructure. [ remove WARN_ON() that triggered on s390, by Carsten Otte <cotte@de.ibm.com> ] [ made new helper static, Adrian Bunk <bunk@stusta.de> ] Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Ingo Molnar <mingo@elte.hu> Cc: john stultz <johnstul@us.ibm.com> Cc: Roman Zippel <zippel@linux-m68k.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
118 lines
3.2 KiB
C
118 lines
3.2 KiB
C
#ifndef _LINUX_TIMER_H
|
|
#define _LINUX_TIMER_H
|
|
|
|
#include <linux/list.h>
|
|
#include <linux/spinlock.h>
|
|
#include <linux/stddef.h>
|
|
|
|
struct tvec_t_base_s;
|
|
|
|
struct timer_list {
|
|
struct list_head entry;
|
|
unsigned long expires;
|
|
|
|
void (*function)(unsigned long);
|
|
unsigned long data;
|
|
|
|
struct tvec_t_base_s *base;
|
|
};
|
|
|
|
extern struct tvec_t_base_s boot_tvec_bases;
|
|
|
|
#define TIMER_INITIALIZER(_function, _expires, _data) { \
|
|
.function = (_function), \
|
|
.expires = (_expires), \
|
|
.data = (_data), \
|
|
.base = &boot_tvec_bases, \
|
|
}
|
|
|
|
#define DEFINE_TIMER(_name, _function, _expires, _data) \
|
|
struct timer_list _name = \
|
|
TIMER_INITIALIZER(_function, _expires, _data)
|
|
|
|
void fastcall init_timer(struct timer_list * timer);
|
|
|
|
static inline void setup_timer(struct timer_list * timer,
|
|
void (*function)(unsigned long),
|
|
unsigned long data)
|
|
{
|
|
timer->function = function;
|
|
timer->data = data;
|
|
init_timer(timer);
|
|
}
|
|
|
|
/**
|
|
* timer_pending - is a timer pending?
|
|
* @timer: the timer in question
|
|
*
|
|
* timer_pending will tell whether a given timer is currently pending,
|
|
* or not. Callers must ensure serialization wrt. other operations done
|
|
* to this timer, eg. interrupt contexts, or other CPUs on SMP.
|
|
*
|
|
* return value: 1 if the timer is pending, 0 if not.
|
|
*/
|
|
static inline int timer_pending(const struct timer_list * timer)
|
|
{
|
|
return timer->entry.next != NULL;
|
|
}
|
|
|
|
extern void add_timer_on(struct timer_list *timer, int cpu);
|
|
extern int del_timer(struct timer_list * timer);
|
|
extern int __mod_timer(struct timer_list *timer, unsigned long expires);
|
|
extern int mod_timer(struct timer_list *timer, unsigned long expires);
|
|
|
|
/*
|
|
* Return when the next timer-wheel timeout occurs (in absolute jiffies),
|
|
* locks the timer base:
|
|
*/
|
|
extern unsigned long next_timer_interrupt(void);
|
|
/*
|
|
* Return when the next timer-wheel timeout occurs (in absolute jiffies),
|
|
* locks the timer base and does the comparison against the given
|
|
* jiffie.
|
|
*/
|
|
extern unsigned long get_next_timer_interrupt(unsigned long now);
|
|
|
|
/**
|
|
* add_timer - start a timer
|
|
* @timer: the timer to be added
|
|
*
|
|
* The kernel will do a ->function(->data) callback from the
|
|
* timer interrupt at the ->expires point in the future. The
|
|
* current time is 'jiffies'.
|
|
*
|
|
* The timer's ->expires, ->function (and if the handler uses it, ->data)
|
|
* fields must be set prior calling this function.
|
|
*
|
|
* Timers with an ->expires field in the past will be executed in the next
|
|
* timer tick.
|
|
*/
|
|
static inline void add_timer(struct timer_list *timer)
|
|
{
|
|
BUG_ON(timer_pending(timer));
|
|
__mod_timer(timer, timer->expires);
|
|
}
|
|
|
|
#ifdef CONFIG_SMP
|
|
extern int try_to_del_timer_sync(struct timer_list *timer);
|
|
extern int del_timer_sync(struct timer_list *timer);
|
|
#else
|
|
# define try_to_del_timer_sync(t) del_timer(t)
|
|
# define del_timer_sync(t) del_timer(t)
|
|
#endif
|
|
|
|
#define del_singleshot_timer_sync(t) del_timer_sync(t)
|
|
|
|
extern void init_timers(void);
|
|
extern void run_local_timers(void);
|
|
struct hrtimer;
|
|
extern int it_real_fn(struct hrtimer *);
|
|
|
|
unsigned long __round_jiffies(unsigned long j, int cpu);
|
|
unsigned long __round_jiffies_relative(unsigned long j, int cpu);
|
|
unsigned long round_jiffies(unsigned long j);
|
|
unsigned long round_jiffies_relative(unsigned long j);
|
|
|
|
|
|
#endif
|