hrtimer.h 4.9 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
/*
 *  include/linux/hrtimer.h
 *
 *  hrtimers - High-resolution kernel timers
 *
 *   Copyright(C) 2005, Thomas Gleixner <tglx@linutronix.de>
 *   Copyright(C) 2005, Red Hat, Inc., Ingo Molnar
 *
 *  data type definitions, declarations, prototypes
 *
 *  Started by: Thomas Gleixner and Ingo Molnar
 *
 *  For licencing details see kernel-base/COPYING
 */
#ifndef _LINUX_HRTIMER_H
#define _LINUX_HRTIMER_H

#include <linux/rbtree.h>
#include <linux/ktime.h>
#include <linux/init.h>
#include <linux/list.h>
#include <linux/wait.h>

24 25 26
struct hrtimer_clock_base;
struct hrtimer_cpu_base;

27 28 29 30
/*
 * Mode arguments of xxx_hrtimer functions:
 */
enum hrtimer_mode {
31 32
	HRTIMER_MODE_ABS,	/* Time value is absolute */
	HRTIMER_MODE_REL,	/* Time value is relative to now */
33 34
};

35 36 37
/*
 * Return values for the callback function
 */
38
enum hrtimer_restart {
39 40
	HRTIMER_NORESTART,	/* Timer is not restarted */
	HRTIMER_RESTART,	/* Timer must be restarted */
41 42 43 44 45 46 47 48 49 50 51 52 53 54
};

/**
 * struct hrtimer - the basic hrtimer structure
 * @node:	red black tree node for time ordered insertion
 * @expires:	the absolute expiry time in the hrtimers internal
 *		representation. The time is related to the clock on
 *		which the timer is based.
 * @function:	timer expiry callback function
 * @base:	pointer to the timer base (per cpu and per clock)
 *
 * The hrtimer structure must be initialized by init_hrtimer_#CLOCKTYPE()
 */
struct hrtimer {
55 56 57 58
	struct rb_node			node;
	ktime_t				expires;
	enum hrtimer_restart		(*function)(struct hrtimer *);
	struct hrtimer_clock_base	*base;
59 60
};

61 62 63 64 65 66 67 68 69 70 71 72
/**
 * struct hrtimer_sleeper - simple sleeper structure
 * @timer:	embedded timer structure
 * @task:	task to wake up
 *
 * task is set to NULL, when the timer expires.
 */
struct hrtimer_sleeper {
	struct hrtimer timer;
	struct task_struct *task;
};

73 74
/**
 * struct hrtimer_base - the timer base for a specific clock
75 76
 * @index:		clock type index for per_cpu support when moving a
 *			timer to a base on another cpu.
77 78 79 80
 * @active:		red black tree root node for the active timers
 * @first:		pointer to the timer node which expires first
 * @resolution:		the resolution of the clock, in nanoseconds
 * @get_time:		function to retrieve the current time of the clock
81
 * @get_softirq_time:	function to retrieve the current time from the softirq
82
 * @softirq_time:	the time when running the hrtimer queue in the softirq
83
 */
84 85
struct hrtimer_clock_base {
	struct hrtimer_cpu_base	*cpu_base;
86 87
	clockid_t		index;
	struct rb_root		active;
88
	struct rb_node		*first;
89
	ktime_t			resolution;
90
	ktime_t			(*get_time)(void);
91 92
	ktime_t			(*get_softirq_time)(void);
	ktime_t			softirq_time;
93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
};

#define HRTIMER_MAX_CLOCK_BASES 2

/*
 * struct hrtimer_cpu_base - the per cpu clock bases
 * @lock:		lock protecting the base and associated clock bases
 *			and timers
 * @lock_key:		the lock_class_key for use with lockdep
 * @clock_base:		array of clock bases for this cpu
 * @curr_timer:		the timer which is executing a callback right now
 */
struct hrtimer_cpu_base {
	spinlock_t			lock;
	struct lock_class_key		lock_key;
	struct hrtimer_clock_base	clock_base[HRTIMER_MAX_CLOCK_BASES];
	struct hrtimer			*curr_timer;
110 111
};

112 113 114 115 116 117 118
/*
 * clock_was_set() is a NOP for non- high-resolution systems. The
 * time-sorted order guarantees that a timer does not expire early and
 * is expired in the next softirq when the clock was advanced.
 */
#define clock_was_set()		do { } while (0)

119 120 121
/* Exported timer functions: */

/* Initialize timers: */
122 123
extern void hrtimer_init(struct hrtimer *timer, clockid_t which_clock,
			 enum hrtimer_mode mode);
124 125 126 127 128 129 130

/* Basic timer operations: */
extern int hrtimer_start(struct hrtimer *timer, ktime_t tim,
			 const enum hrtimer_mode mode);
extern int hrtimer_cancel(struct hrtimer *timer);
extern int hrtimer_try_to_cancel(struct hrtimer *timer);

131 132 133 134
static inline int hrtimer_restart(struct hrtimer *timer)
{
	return hrtimer_start(timer, timer->expires, HRTIMER_MODE_ABS);
}
135 136 137 138 139

/* Query timers: */
extern ktime_t hrtimer_get_remaining(const struct hrtimer *timer);
extern int hrtimer_get_res(const clockid_t which_clock, struct timespec *tp);

140 141 142 143
#ifdef CONFIG_NO_IDLE_HZ
extern ktime_t hrtimer_get_next_event(void);
#endif

144 145
static inline int hrtimer_active(const struct hrtimer *timer)
{
146
	return rb_parent(&timer->node) != &timer->node;
147 148 149
}

/* Forward a hrtimer so it expires after now: */
150 151
extern unsigned long
hrtimer_forward(struct hrtimer *timer, ktime_t now, ktime_t interval);
152

153 154 155 156 157
/* Precise sleep: */
extern long hrtimer_nanosleep(struct timespec *rqtp,
			      struct timespec __user *rmtp,
			      const enum hrtimer_mode mode,
			      const clockid_t clockid);
158
extern long hrtimer_nanosleep_restart(struct restart_block *restart_block);
159

160 161 162
extern void hrtimer_init_sleeper(struct hrtimer_sleeper *sl,
				 struct task_struct *tsk);

163 164 165
/* Soft interrupt function to run the hrtimer queues: */
extern void hrtimer_run_queues(void);

166 167 168
/* Resume notification */
void hrtimer_notify_resume(void);

169 170 171 172
/* Bootup initialization: */
extern void __init hrtimers_init(void);

#endif