posix-timers.h 4.8 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
#ifndef _linux_POSIX_TIMERS_H
#define _linux_POSIX_TIMERS_H

#include <linux/spinlock.h>
#include <linux/list.h>
#include <linux/sched.h>

union cpu_time_count {
	cputime_t cpu;
	unsigned long long sched;
};

struct cpu_timer_list {
	struct list_head entry;
	union cpu_time_count expires, incr;
	struct task_struct *task;
	int firing;
};

#define CPUCLOCK_PID(clock)		((pid_t) ~((clock) >> 3))
#define CPUCLOCK_PERTHREAD(clock) \
	(((clock) & (clockid_t) CPUCLOCK_PERTHREAD_MASK) != 0)
#define CPUCLOCK_PID_MASK	7
#define CPUCLOCK_PERTHREAD_MASK	4
#define CPUCLOCK_WHICH(clock)	((clock) & (clockid_t) CPUCLOCK_CLOCK_MASK)
#define CPUCLOCK_CLOCK_MASK	3
#define CPUCLOCK_PROF		0
#define CPUCLOCK_VIRT		1
#define CPUCLOCK_SCHED		2
#define CPUCLOCK_MAX		3

#define MAKE_PROCESS_CPUCLOCK(pid, clock) \
	((~(clockid_t) (pid) << 3) | (clockid_t) (clock))
#define MAKE_THREAD_CPUCLOCK(tid, clock) \
	MAKE_PROCESS_CPUCLOCK((tid), (clock) | CPUCLOCK_PERTHREAD_MASK)

/* POSIX.1b interval timer structure. */
struct k_itimer {
	struct list_head list;		/* free/ allocate list */
	spinlock_t it_lock;
	clockid_t it_clock;		/* which timer type */
	timer_t it_id;			/* timer id */
	int it_overrun;			/* overrun on pending signal  */
	int it_overrun_last;		/* overrun on last delivered signal */
45
	int it_requeue_pending;		/* waiting to requeue this timer */
L
Linus Torvalds 已提交
46 47 48 49 50 51 52 53 54
#define REQUEUE_PENDING 1
	int it_sigev_notify;		/* notify word of sigevent struct */
	int it_sigev_signo;		/* signo word of sigevent struct */
	sigval_t it_sigev_value;	/* value word of sigevent struct */
	struct task_struct *it_process;	/* process to send signal to */
	struct sigqueue *sigq;		/* signal queue entry. */
	union {
		struct {
			struct timer_list timer;
55 56 57 58
			/* clock abs_timer_list: */
			struct list_head abs_timer_entry;
			/* wall_to_monotonic used when set: */
			struct timespec wall_to_prev;
L
Linus Torvalds 已提交
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
			unsigned long incr; /* interval in jiffies */
		} real;
		struct cpu_timer_list cpu;
		struct {
			unsigned int clock;
			unsigned int node;
			unsigned long incr;
			unsigned long expires;
		} mmtimer;
	} it;
};

struct k_clock_abs {
	struct list_head list;
	spinlock_t lock;
};
75

L
Linus Torvalds 已提交
76
struct k_clock {
77
	int res;		/* in nanoseconds */
78
	int (*clock_getres) (const clockid_t which_clock, struct timespec *tp);
L
Linus Torvalds 已提交
79
	struct k_clock_abs *abs_struct;
80 81
	int (*clock_set) (const clockid_t which_clock, struct timespec * tp);
	int (*clock_get) (const clockid_t which_clock, struct timespec * tp);
L
Linus Torvalds 已提交
82
	int (*timer_create) (struct k_itimer *timer);
83 84
	int (*nsleep) (const clockid_t which_clock, int flags,
		       struct timespec *);
L
Linus Torvalds 已提交
85 86 87 88 89 90 91 92 93
	int (*timer_set) (struct k_itimer * timr, int flags,
			  struct itimerspec * new_setting,
			  struct itimerspec * old_setting);
	int (*timer_del) (struct k_itimer * timr);
#define TIMER_RETRY 1
	void (*timer_get) (struct k_itimer * timr,
			   struct itimerspec * cur_setting);
};

94
void register_posix_clock(const clockid_t clock_id, struct k_clock *new_clock);
L
Linus Torvalds 已提交
95

96
/* error handlers for timer_create, nanosleep and settime */
L
Linus Torvalds 已提交
97
int do_posix_clock_notimer_create(struct k_itimer *timer);
98 99
int do_posix_clock_nonanosleep(const clockid_t, int flags, struct timespec *);
int do_posix_clock_nosettime(const clockid_t, struct timespec *tp);
L
Linus Torvalds 已提交
100 101 102 103 104 105 106 107

/* function to call to trigger timer event */
int posix_timer_event(struct k_itimer *timr, int si_private);

struct now_struct {
	unsigned long jiffies;
};

108 109 110
#define posix_get_now(now) \
	do { (now)->jiffies = jiffies; } while (0)

L
Linus Torvalds 已提交
111 112 113 114
#define posix_time_before(timer, now) \
                      time_before((timer)->expires, (now)->jiffies)

#define posix_bump_timer(timr, now)					\
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
	do {								\
		long delta, orun;					\
									\
		delta = (now).jiffies - (timr)->it.real.timer.expires;	\
		if (delta >= 0) {					\
			orun = 1 + (delta / (timr)->it.real.incr);	\
			(timr)->it.real.timer.expires +=		\
				orun * (timr)->it.real.incr;		\
			(timr)->it_overrun += orun;			\
		}							\
	} while (0)

int posix_cpu_clock_getres(const clockid_t which_clock, struct timespec *ts);
int posix_cpu_clock_get(const clockid_t which_clock, struct timespec *ts);
int posix_cpu_clock_set(const clockid_t which_clock, const struct timespec *ts);
int posix_cpu_timer_create(struct k_itimer *timer);
int posix_cpu_nsleep(const clockid_t which_clock, int flags,
		     struct timespec *ts);
int posix_cpu_timer_set(struct k_itimer *timer, int flags,
			struct itimerspec *new, struct itimerspec *old);
int posix_cpu_timer_del(struct k_itimer *timer);
void posix_cpu_timer_get(struct k_itimer *timer, struct itimerspec *itp);

void posix_cpu_timer_schedule(struct k_itimer *timer);

void run_posix_cpu_timers(struct task_struct *task);
void posix_cpu_timers_exit(struct task_struct *task);
void posix_cpu_timers_exit_group(struct task_struct *task);

void set_process_cpu_timer(struct task_struct *task, unsigned int clock_idx,
			   cputime_t *newval, cputime_t *oldval);
L
Linus Torvalds 已提交
146 147

#endif