Something went wrong. Try again.
(I'm so sorry!) Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238/* SPDX-License-Identifier: GPL-2.0 */#ifndef _linux_POSIX_TIMERS_H#define _linux_POSIX_TIMERS_H
#include <linux/alarmtimer.h>#include <linux/list.h>#include <linux/mutex.h>#include <linux/pid.h>#include <linux/posix-timers_types.h>#include <linux/rcuref.h>#include <linux/spinlock.h>#include <linux/timerqueue.h>
struct kernel_siginfo;struct task_struct;struct sigqueue;struct k_itimer;
static inline clockid_t make_process_cpuclock(const unsigned int pid, const clockid_t clock){ return ((~pid) << 3) | clock;}static inline clockid_t make_thread_cpuclock(const unsigned int tid, const clockid_t clock){ return make_process_cpuclock(tid, clock | CPUCLOCK_PERTHREAD_MASK);}
static inline clockid_t fd_to_clockid(const int fd){ return make_process_cpuclock((unsigned int) fd, CLOCKFD);}
static inline int clockid_to_fd(const clockid_t clk){ return ~(clk >> 3);}
static inline bool clockid_is_aux_clock(clockid_t id){ return IS_ENABLED(CONFIG_POSIX_AUX_CLOCKS) && id >= CLOCK_AUX && id <= CLOCK_AUX_LAST;}
#ifdef CONFIG_POSIX_TIMERS
#include <linux/signal_types.h>
/** * struct 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 * @pid: Pointer to target task PID * @elist: List head for the expiry list * @firing: Timer is currently firing * @nanosleep: Timer is used for nanosleep and is not a regular posix-timer * @handling: Pointer to the task which handles expiry */struct cpu_timer { struct timerqueue_node node; struct timerqueue_head *head; struct pid *pid; struct list_head elist; bool firing; bool nanosleep; struct task_struct __rcu *handling;};
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;}
void posixtimer_rearm_itimer(struct task_struct *p);bool posixtimer_init_sigqueue(struct sigqueue *q);void posixtimer_send_sigqueue(struct k_itimer *tmr);bool posixtimer_deliver_signal(struct kernel_siginfo *info, struct sigqueue *timer_sigq);void posixtimer_free_timer(struct k_itimer *timer);long posixtimer_create_prctl(unsigned long ctrl);
/* 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), \ },#elsestruct 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) { }static inline void posixtimer_rearm_itimer(struct task_struct *p) { }static inline bool posixtimer_deliver_signal(struct kernel_siginfo *info, struct sigqueue *timer_sigq) { return false; }static inline void posixtimer_free_timer(struct k_itimer *timer) { }static inline long posixtimer_create_prctl(unsigned long ctrl) { return -EINVAL; }#endif
#ifdef CONFIG_POSIX_CPU_TIMERS_TASK_WORKvoid clear_posix_cputimers_work(struct task_struct *p);void posix_cputimers_init_work(void);#elsestatic inline void clear_posix_cputimers_work(struct task_struct *p) { }static inline void posix_cputimers_init_work(void) { }#endif
/** * struct k_itimer - POSIX.1b interval timer structure. * @list: List node for binding the timer to tsk::signal::posix_timers * @ignored_list: List node for tracking ignored timers in tsk::signal::ignored_posix_timers * @t_hash: Entry in the posix timer hash table * @it_lock: Lock protecting the timer * @kclock: Pointer to the k_clock struct handling this timer * @it_clock: The posix timer clock id * @it_id: The posix timer id for identifying the timer * @it_status: The status of the timer * @it_sig_periodic: The periodic status at signal delivery * @it_overrun: The overrun counter for pending signals * @it_overrun_last: The overrun at the time of the last delivered signal * @it_signal_seq: Sequence count to control signal delivery * @it_sigqueue_seq: The sequence count at the point where the signal was queued * @it_sigev_notify: The notify word of sigevent struct for signal delivery * @it_interval: The interval for periodic timers * @it_pid_type: The type of the PID * @it_signal: Pointer to the creators signal struct * @it_pid: The pid of the process/task targeted by the signal * @it_process: The task to wakeup on clock_nanosleep (CPU timers) * @rcuref: Reference count for life time management * @sigq: Embedded sigqueue * @it: Union representing the various posix timer type * internals. * @rcu: RCU head for freeing the timer. */struct k_itimer { /* 1st cacheline contains read-mostly fields */ struct hlist_node t_hash; struct hlist_node list; timer_t it_id; clockid_t it_clock; int it_sigev_notify; enum pid_type it_pid_type; struct signal_struct *it_signal; const struct k_clock *kclock;
/* 2nd cacheline and above contain fields which are modified regularly */ spinlock_t it_lock; int it_status; bool it_sig_periodic; s64 it_overrun; s64 it_overrun_last; unsigned int it_signal_seq; unsigned int it_sigqueue_seq; ktime_t it_interval; struct hlist_node ignored_list; union { struct pid *it_pid; struct task_struct *it_process; }; struct sigqueue sigq; rcuref_t rcuref; union { struct { struct hrtimer timer; } real; struct cpu_timer cpu; struct { struct alarm alarmtimer; } alarm; } it; struct rcu_head rcu;} ____cacheline_aligned_in_smp;
void run_posix_cpu_timers(void);void set_process_cpu_timer(struct task_struct *task, unsigned int clock_idx, u64 *newval, u64 *oldval);
int update_rlimit_cpu(struct task_struct *task, unsigned long rlim_new);
#ifdef CONFIG_POSIX_TIMERSvoid posixtimer_exec(void);void posixtimer_exit(bool group_dead);
static inline void posixtimer_putref(struct k_itimer *tmr){ if (rcuref_put(&tmr->rcuref)) posixtimer_free_timer(tmr);}
static inline void posixtimer_sigqueue_getref(struct sigqueue *q){ struct k_itimer *tmr = container_of(q, struct k_itimer, sigq);
WARN_ON_ONCE(!rcuref_get(&tmr->rcuref));}
static inline void posixtimer_sigqueue_putref(struct sigqueue *q){ struct k_itimer *tmr = container_of(q, struct k_itimer, sigq);
posixtimer_putref(tmr);}
static inline bool posixtimer_valid(const struct k_itimer *timer){ unsigned long val = (unsigned long)timer->it_signal;
return !(val & 0x1UL);}#else /* CONFIG_POSIX_TIMERS */static inline void posixtimer_exec(void) { }static inline void posixtimer_exit(bool group_dead) { }static inline void posixtimer_sigqueue_getref(struct sigqueue *q) { }static inline void posixtimer_sigqueue_putref(struct sigqueue *q) { }#endif /* !CONFIG_POSIX_TIMERS */
#endif