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
/*
 * 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.
 */
61 62 63
#define TIMER_DEFERRABLE		0x1LU

#define TIMER_FLAG_MASK			0x1LU
64

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

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

#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__))	\
	}

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

93 94 95 96 97 98 99
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);

100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
#ifdef CONFIG_DEBUG_OBJECTS_TIMERS
extern void init_timer_on_stack_key(struct timer_list *timer,
				    const char *name,
				    struct lock_class_key *key);
extern void destroy_timer_on_stack(struct timer_list *timer);
#else
static inline void destroy_timer_on_stack(struct timer_list *timer) { }
static inline void init_timer_on_stack_key(struct timer_list *timer,
					   const char *name,
					   struct lock_class_key *key)
{
	init_timer_key(timer, name, key);
}
#endif

115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
#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)
146 147 148 149 150 151 152
#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)
153 154 155 156 157 158 159 160 161 162 163
#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))
164 165
#define setup_deferrable_timer_on_stack(timer, fn, data)\
	setup_deferrable_timer_on_stack_key((timer), NULL, NULL, (fn), (data))
166
#endif
L
Linus Torvalds 已提交
167

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

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

190 191 192 193 194 195
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);

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

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

217 218
extern void set_timer_slack(struct timer_list *time, int slack_hz);

219 220
#define TIMER_NOT_PINNED	0
#define TIMER_PINNED		1
221 222 223 224 225 226
/*
 * 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)

227 228 229 230 231 232
/*
 * 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 已提交
233

234 235 236 237 238
/*
 * Timer-statistics info:
 */
#ifdef CONFIG_TIMER_STATS

239 240
extern int timer_stats_active;

241 242
#define TIMER_STATS_FLAG_DEFERRABLE	0x1

243 244 245
extern void init_timer_stats(void);

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

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)
{
254 255
	if (likely(!timer_stats_active))
		return;
256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276
	__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 已提交
277
extern void add_timer(struct timer_list *timer);
L
Linus Torvalds 已提交
278

279 280
extern int try_to_del_timer_sync(struct timer_list *timer);

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

287 288
#define del_singleshot_timer_sync(t) del_timer_sync(t)

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

294 295 296 297 298
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);

299 300 301 302 303
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 已提交
304
#endif