timer.h 8.6 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3 4
#ifndef _LINUX_TIMER_H
#define _LINUX_TIMER_H

#include <linux/list.h>
5
#include <linux/ktime.h>
L
Linus Torvalds 已提交
6
#include <linux/stddef.h>
7
#include <linux/debugobjects.h>
8
#include <linux/stringify.h>
L
Linus Torvalds 已提交
9

10
struct tvec_base;
L
Linus Torvalds 已提交
11 12

struct timer_list {
13 14 15 16
	/*
	 * All fields that change during normal runtime grouped to the
	 * same cacheline
	 */
L
Linus Torvalds 已提交
17 18
	struct list_head entry;
	unsigned long expires;
19
	struct tvec_base *base;
L
Linus Torvalds 已提交
20 21 22 23

	void (*function)(unsigned long);
	unsigned long data;

24 25
	int slack;

26
#ifdef CONFIG_TIMER_STATS
27
	int start_pid;
28 29 30
	void *start_site;
	char start_comm[16];
#endif
31 32 33
#ifdef CONFIG_LOCKDEP
	struct lockdep_map lockdep_map;
#endif
L
Linus Torvalds 已提交
34 35
};

36
extern struct tvec_base boot_tvec_bases;
37

38 39 40 41 42 43 44 45 46 47 48 49 50
#ifdef CONFIG_LOCKDEP
/*
 * NB: because we have to copy the lockdep_map, setting the lockdep_map key
 * (second argument) here is required, otherwise it could be initialised to
 * the copy of the lockdep_map later! We use the pointer to and the string
 * "<file>:<line>" as the key resp. the name of the lockdep_map.
 */
#define __TIMER_LOCKDEP_MAP_INITIALIZER(_kn)				\
	.lockdep_map = STATIC_LOCKDEP_MAP_INIT(_kn, &_kn),
#else
#define __TIMER_LOCKDEP_MAP_INITIALIZER(_kn)
#endif

51 52 53 54 55 56 57 58 59 60 61 62
/*
 * Note that all tvec_bases are 2 byte aligned and lower bit of
 * base in timer_list is guaranteed to be zero. Use the LSB to
 * indicate whether the timer is deferrable.
 *
 * A deferrable timer will work normally when the system is busy, but
 * will not cause a CPU to come out of idle just to service it; instead,
 * the timer will be serviced when the CPU eventually wakes up with a
 * subsequent non-deferrable timer.
 */
#define TBASE_DEFERRABLE_FLAG		(0x1)

L
Linus Torvalds 已提交
63
#define TIMER_INITIALIZER(_function, _expires, _data) {		\
64
		.entry = { .prev = TIMER_ENTRY_STATIC },	\
L
Linus Torvalds 已提交
65 66 67
		.function = (_function),			\
		.expires = (_expires),				\
		.data = (_data),				\
68
		.base = &boot_tvec_bases,			\
69
		.slack = -1,					\
70 71
		__TIMER_LOCKDEP_MAP_INITIALIZER(		\
			__FILE__ ":" __stringify(__LINE__))	\
L
Linus Torvalds 已提交
72 73
	}

74 75 76 77 78 79 80 81 82 83 84 85 86
#define TBASE_MAKE_DEFERRED(ptr) ((struct tvec_base *)		\
		  ((unsigned char *)(ptr) + TBASE_DEFERRABLE_FLAG))

#define TIMER_DEFERRED_INITIALIZER(_function, _expires, _data) {\
		.entry = { .prev = TIMER_ENTRY_STATIC },	\
		.function = (_function),			\
		.expires = (_expires),				\
		.data = (_data),				\
		.base = TBASE_MAKE_DEFERRED(&boot_tvec_bases),	\
		__TIMER_LOCKDEP_MAP_INITIALIZER(		\
			__FILE__ ":" __stringify(__LINE__))	\
	}

87 88 89 90
#define DEFINE_TIMER(_name, _function, _expires, _data)		\
	struct timer_list _name =				\
		TIMER_INITIALIZER(_function, _expires, _data)

91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
void init_timer_key(struct timer_list *timer,
		    const char *name,
		    struct lock_class_key *key);
void init_timer_deferrable_key(struct timer_list *timer,
			       const char *name,
			       struct lock_class_key *key);

#ifdef CONFIG_LOCKDEP
#define init_timer(timer)						\
	do {								\
		static struct lock_class_key __key;			\
		init_timer_key((timer), #timer, &__key);		\
	} while (0)

#define init_timer_deferrable(timer)					\
	do {								\
		static struct lock_class_key __key;			\
		init_timer_deferrable_key((timer), #timer, &__key);	\
	} while (0)

#define init_timer_on_stack(timer)					\
	do {								\
		static struct lock_class_key __key;			\
		init_timer_on_stack_key((timer), #timer, &__key);	\
	} while (0)

#define setup_timer(timer, fn, data)					\
	do {								\
		static struct lock_class_key __key;			\
		setup_timer_key((timer), #timer, &__key, (fn), (data));\
	} while (0)

#define setup_timer_on_stack(timer, fn, data)				\
	do {								\
		static struct lock_class_key __key;			\
		setup_timer_on_stack_key((timer), #timer, &__key,	\
					 (fn), (data));			\
	} while (0)
129 130 131 132 133 134 135
#define setup_deferrable_timer_on_stack(timer, fn, data)		\
	do {								\
		static struct lock_class_key __key;			\
		setup_deferrable_timer_on_stack_key((timer), #timer,	\
						    &__key, (fn),	\
						    (data));		\
	} while (0)
136 137 138 139 140 141 142 143 144 145 146
#else
#define init_timer(timer)\
	init_timer_key((timer), NULL, NULL)
#define init_timer_deferrable(timer)\
	init_timer_deferrable_key((timer), NULL, NULL)
#define init_timer_on_stack(timer)\
	init_timer_on_stack_key((timer), NULL, NULL)
#define setup_timer(timer, fn, data)\
	setup_timer_key((timer), NULL, NULL, (fn), (data))
#define setup_timer_on_stack(timer, fn, data)\
	setup_timer_on_stack_key((timer), NULL, NULL, (fn), (data))
147 148
#define setup_deferrable_timer_on_stack(timer, fn, data)\
	setup_deferrable_timer_on_stack_key((timer), NULL, NULL, (fn), (data))
149
#endif
L
Linus Torvalds 已提交
150

151
#ifdef CONFIG_DEBUG_OBJECTS_TIMERS
152 153 154
extern void init_timer_on_stack_key(struct timer_list *timer,
				    const char *name,
				    struct lock_class_key *key);
155 156 157
extern void destroy_timer_on_stack(struct timer_list *timer);
#else
static inline void destroy_timer_on_stack(struct timer_list *timer) { }
158 159 160
static inline void init_timer_on_stack_key(struct timer_list *timer,
					   const char *name,
					   struct lock_class_key *key)
161
{
162
	init_timer_key(timer, name, key);
163 164 165
}
#endif

166 167 168
static inline void setup_timer_key(struct timer_list * timer,
				const char *name,
				struct lock_class_key *key,
169 170 171 172 173
				void (*function)(unsigned long),
				unsigned long data)
{
	timer->function = function;
	timer->data = data;
174
	init_timer_key(timer, name, key);
175 176
}

177 178 179
static inline void setup_timer_on_stack_key(struct timer_list *timer,
					const char *name,
					struct lock_class_key *key,
180 181 182 183 184
					void (*function)(unsigned long),
					unsigned long data)
{
	timer->function = function;
	timer->data = data;
185
	init_timer_on_stack_key(timer, name, key);
186 187
}

188 189 190 191 192 193
extern void setup_deferrable_timer_on_stack_key(struct timer_list *timer,
						const char *name,
						struct lock_class_key *key,
						void (*function)(unsigned long),
						unsigned long data);

194
/**
L
Linus Torvalds 已提交
195 196 197 198 199 200 201 202 203 204 205
 * 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)
{
206
	return timer->entry.next != NULL;
L
Linus Torvalds 已提交
207 208 209 210 211
}

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);
I
Ingo Molnar 已提交
212
extern int mod_timer_pending(struct timer_list *timer, unsigned long expires);
213
extern int mod_timer_pinned(struct timer_list *timer, unsigned long expires);
L
Linus Torvalds 已提交
214

215 216
extern void set_timer_slack(struct timer_list *time, int slack_hz);

217 218
#define TIMER_NOT_PINNED	0
#define TIMER_PINNED		1
219 220 221 222 223 224
/*
 * The jiffies value which is added to now, when there is no timer
 * in the timer wheel:
 */
#define NEXT_TIMER_MAX_DELTA	((1UL << 30) - 1)

225 226 227 228 229 230
/*
 * 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);
L
Linus Torvalds 已提交
231

232 233 234 235 236
/*
 * Timer-statistics info:
 */
#ifdef CONFIG_TIMER_STATS

237 238
extern int timer_stats_active;

239 240
#define TIMER_STATS_FLAG_DEFERRABLE	0x1

241 242 243
extern void init_timer_stats(void);

extern void timer_stats_update_stats(void *timer, pid_t pid, void *startf,
244 245
				     void *timerf, char *comm,
				     unsigned int timer_flag);
246 247 248 249 250 251

extern void __timer_stats_timer_set_start_info(struct timer_list *timer,
					       void *addr);

static inline void timer_stats_timer_set_start_info(struct timer_list *timer)
{
252 253
	if (likely(!timer_stats_active))
		return;
254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274
	__timer_stats_timer_set_start_info(timer, __builtin_return_address(0));
}

static inline void timer_stats_timer_clear_start_info(struct timer_list *timer)
{
	timer->start_site = NULL;
}
#else
static inline void init_timer_stats(void)
{
}

static inline void timer_stats_timer_set_start_info(struct timer_list *timer)
{
}

static inline void timer_stats_timer_clear_start_info(struct timer_list *timer)
{
}
#endif

I
Ingo Molnar 已提交
275
extern void add_timer(struct timer_list *timer);
L
Linus Torvalds 已提交
276

277 278
extern int try_to_del_timer_sync(struct timer_list *timer);

L
Linus Torvalds 已提交
279 280 281
#ifdef CONFIG_SMP
  extern int del_timer_sync(struct timer_list *timer);
#else
282
# define del_timer_sync(t)		del_timer(t)
L
Linus Torvalds 已提交
283 284
#endif

285 286
#define del_singleshot_timer_sync(t) del_timer_sync(t)

L
Linus Torvalds 已提交
287 288
extern void init_timers(void);
extern void run_local_timers(void);
289
struct hrtimer;
290
extern enum hrtimer_restart it_real_fn(struct hrtimer *);
L
Linus Torvalds 已提交
291

292 293 294 295 296
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);

297 298 299 300 301
unsigned long __round_jiffies_up(unsigned long j, int cpu);
unsigned long __round_jiffies_up_relative(unsigned long j, int cpu);
unsigned long round_jiffies_up(unsigned long j);
unsigned long round_jiffies_up_relative(unsigned long j);

L
Linus Torvalds 已提交
302
#endif