diff options
Diffstat (limited to 'include/linux/posix-timers.h')
| -rw-r--r-- | include/linux/posix-timers.h | 131 | 
1 files changed, 117 insertions, 14 deletions
diff --git a/include/linux/posix-timers.h b/include/linux/posix-timers.h index b20798fc5191..3d10c84a97a9 100644 --- a/include/linux/posix-timers.h +++ b/include/linux/posix-timers.h @@ -4,18 +4,11 @@  #include <linux/spinlock.h>  #include <linux/list.h> -#include <linux/sched.h> -#include <linux/timex.h>  #include <linux/alarmtimer.h> +#include <linux/timerqueue.h> -struct siginfo; - -struct cpu_timer_list { -	struct list_head entry; -	u64 expires; -	struct task_struct *task; -	int firing; -}; +struct kernel_siginfo; +struct task_struct;  /*   * Bit fields within a clockid: @@ -63,6 +56,115 @@ static inline int clockid_to_fd(const clockid_t clk)  	return ~(clk >> 3);  } +#ifdef CONFIG_POSIX_TIMERS + +/** + * cpu_timer - Posix CPU timer representation for k_itimer + * @node:	timerqueue node to queue in the task/sig + * @head:	timerqueue head on which this timer is queued + * @task:	Pointer to target task + * @elist:	List head for the expiry list + * @firing:	Timer is currently firing + */ +struct cpu_timer { +	struct timerqueue_node	node; +	struct timerqueue_head	*head; +	struct task_struct	*task; +	struct list_head	elist; +	int			firing; +}; + +static inline bool cpu_timer_enqueue(struct timerqueue_head *head, +				     struct cpu_timer *ctmr) +{ +	ctmr->head = head; +	return timerqueue_add(head, &ctmr->node); +} + +static inline void cpu_timer_dequeue(struct cpu_timer *ctmr) +{ +	if (ctmr->head) { +		timerqueue_del(ctmr->head, &ctmr->node); +		ctmr->head = NULL; +	} +} + +static inline u64 cpu_timer_getexpires(struct cpu_timer *ctmr) +{ +	return ctmr->node.expires; +} + +static inline void cpu_timer_setexpires(struct cpu_timer *ctmr, u64 exp) +{ +	ctmr->node.expires = exp; +} + +/** + * posix_cputimer_base - Container per posix CPU clock + * @nextevt:		Earliest-expiration cache + * @tqhead:		timerqueue head for cpu_timers + */ +struct posix_cputimer_base { +	u64			nextevt; +	struct timerqueue_head	tqhead; +}; + +/** + * posix_cputimers - Container for posix CPU timer related data + * @bases:		Base container for posix CPU clocks + * @timers_active:	Timers are queued. + * @expiry_active:	Timer expiry is active. Used for + *			process wide timers to avoid multiple + *			task trying to handle expiry concurrently + * + * Used in task_struct and signal_struct + */ +struct posix_cputimers { +	struct posix_cputimer_base	bases[CPUCLOCK_MAX]; +	unsigned int			timers_active; +	unsigned int			expiry_active; +}; + +static inline void posix_cputimers_init(struct posix_cputimers *pct) +{ +	memset(pct, 0, sizeof(*pct)); +	pct->bases[0].nextevt = U64_MAX; +	pct->bases[1].nextevt = U64_MAX; +	pct->bases[2].nextevt = U64_MAX; +} + +void posix_cputimers_group_init(struct posix_cputimers *pct, u64 cpu_limit); + +static inline void posix_cputimers_rt_watchdog(struct posix_cputimers *pct, +					       u64 runtime) +{ +	pct->bases[CPUCLOCK_SCHED].nextevt = runtime; +} + +/* Init task static initializer */ +#define INIT_CPU_TIMERBASE(b) {						\ +	.nextevt	= U64_MAX,					\ +} + +#define INIT_CPU_TIMERBASES(b) {					\ +	INIT_CPU_TIMERBASE(b[0]),					\ +	INIT_CPU_TIMERBASE(b[1]),					\ +	INIT_CPU_TIMERBASE(b[2]),					\ +} + +#define INIT_CPU_TIMERS(s)						\ +	.posix_cputimers = {						\ +		.bases = INIT_CPU_TIMERBASES(s.posix_cputimers.bases),	\ +	}, +#else +struct posix_cputimers { }; +struct cpu_timer { }; +#define INIT_CPU_TIMERS(s) +static inline void posix_cputimers_init(struct posix_cputimers *pct) { } +static inline void posix_cputimers_group_init(struct posix_cputimers *pct, +					      u64 cpu_limit) { } +#endif +  #define REQUEUE_PENDING 1  /** @@ -85,7 +187,8 @@ static inline int clockid_to_fd(const clockid_t clk)   * @it_process:		The task to wakeup on clock_nanosleep (CPU timers)   * @sigq:		Pointer to preallocated sigqueue   * @it:			Union representing the various posix timer type - *			internals. Also used for rcu freeing the timer. + *			internals. + * @rcu:		RCU head for freeing the timer.   */  struct k_itimer {  	struct list_head	list; @@ -110,15 +213,15 @@ struct k_itimer {  		struct {  			struct hrtimer	timer;  		} real; -		struct cpu_timer_list	cpu; +		struct cpu_timer	cpu;  		struct {  			struct alarm	alarmtimer;  		} alarm; -		struct rcu_head		rcu;  	} it; +	struct rcu_head		rcu;  }; -void run_posix_cpu_timers(struct task_struct *task); +void run_posix_cpu_timers(void);  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,  |