cregit-Linux how code gets into the kernel

Release 4.12 include/linux/hrtimer.h

Directory: include/linux
/*
 *  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/percpu.h>
#include <linux/timer.h>
#include <linux/timerqueue.h>

struct hrtimer_clock_base;
struct hrtimer_cpu_base;

/*
 * Mode arguments of xxx_hrtimer functions:
 */

enum hrtimer_mode {
	
HRTIMER_MODE_ABS = 0x0,		/* Time value is absolute */
	
HRTIMER_MODE_REL = 0x1,		/* Time value is relative to now */
	
HRTIMER_MODE_PINNED = 0x02,	/* Timer is bound to CPU */
	
HRTIMER_MODE_ABS_PINNED = 0x02,
	
HRTIMER_MODE_REL_PINNED = 0x03,
};

/*
 * Return values for the callback function
 */

enum hrtimer_restart {
	
HRTIMER_NORESTART,	/* Timer is not restarted */
	
HRTIMER_RESTART,	/* Timer must be restarted */
};

/*
 * Values to track state of the timer
 *
 * Possible states:
 *
 * 0x00         inactive
 * 0x01         enqueued into rbtree
 *
 * The callback state is not part of the timer->state because clearing it would
 * mean touching the timer after the callback, this makes it impossible to free
 * the timer from the callback function.
 *
 * Therefore we track the callback state in:
 *
 *      timer->base->cpu_base->running == timer
 *
 * On SMP it is possible to have a "callback function running and enqueued"
 * status. It happens for example when a posix timer expired and the callback
 * queued a signal. Between dropping the lock which protects the posix timer
 * and reacquiring the base lock of the hrtimer, another CPU can deliver the
 * signal and rearm the timer.
 *
 * All state transitions are protected by cpu_base->lock.
 */

#define HRTIMER_STATE_INACTIVE	0x00

#define HRTIMER_STATE_ENQUEUED	0x01

/**
 * struct hrtimer - the basic hrtimer structure
 * @node:       timerqueue node, which also manages node.expires,
 *              the absolute expiry time in the hrtimers internal
 *              representation. The time is related to the clock on
 *              which the timer is based. Is setup by adding
 *              slack to the _softexpires value. For non range timers
 *              identical to _softexpires.
 * @_softexpires: the absolute earliest expiry time of the hrtimer.
 *              The time which was given as expiry time when the timer
 *              was armed.
 * @function:   timer expiry callback function
 * @base:       pointer to the timer base (per cpu and per clock)
 * @state:      state information (See bit values above)
 * @is_rel:     Set if the timer was armed relative
 *
 * The hrtimer structure must be initialized by hrtimer_init()
 */

struct hrtimer {
	
struct timerqueue_node		node;
	
ktime_t				_softexpires;
	
enum hrtimer_restart		(*function)(struct hrtimer *);
	
struct hrtimer_clock_base	*base;
	
u8				state;
	
u8				is_rel;
};

/**
 * 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;
};

#ifdef CONFIG_64BIT

# define HRTIMER_CLOCK_BASE_ALIGN	64
#else

# define HRTIMER_CLOCK_BASE_ALIGN	32
#endif

/**
 * struct hrtimer_clock_base - the timer base for a specific clock
 * @cpu_base:           per cpu clock base
 * @index:              clock type index for per_cpu support when moving a
 *                      timer to a base on another cpu.
 * @clockid:            clock id for per_cpu support
 * @active:             red black tree root node for the active timers
 * @get_time:           function to retrieve the current time of the clock
 * @offset:             offset of this clock to the monotonic base
 */

struct hrtimer_clock_base {
	
struct hrtimer_cpu_base	*cpu_base;
	
int			index;
	
clockid_t		clockid;
	
struct timerqueue_head	active;
	
ktime_t			(*get_time)(void);
	
ktime_t			offset;
} __attribute__((__aligned__(HRTIMER_CLOCK_BASE_ALIGN)));


enum  hrtimer_base_type {
	
HRTIMER_BASE_MONOTONIC,
	
HRTIMER_BASE_REALTIME,
	
HRTIMER_BASE_BOOTTIME,
	
HRTIMER_BASE_TAI,
	
HRTIMER_MAX_CLOCK_BASES,
};

/*
 * struct hrtimer_cpu_base - the per cpu clock bases
 * @lock:               lock protecting the base and associated clock bases
 *                      and timers
 * @seq:                seqcount around __run_hrtimer
 * @running:            pointer to the currently running hrtimer
 * @cpu:                cpu number
 * @active_bases:       Bitfield to mark bases with active timers
 * @clock_was_set_seq:  Sequence counter of clock was set events
 * @migration_enabled:  The migration of hrtimers to other cpus is enabled
 * @nohz_active:        The nohz functionality is enabled
 * @expires_next:       absolute time of the next event which was scheduled
 *                      via clock_set_next_event()
 * @next_timer:         Pointer to the first expiring timer
 * @in_hrtirq:          hrtimer_interrupt() is currently executing
 * @hres_active:        State of high resolution mode
 * @hang_detected:      The last hrtimer interrupt detected a hang
 * @nr_events:          Total number of hrtimer interrupt events
 * @nr_retries:         Total number of hrtimer interrupt retries
 * @nr_hangs:           Total number of hrtimer interrupt hangs
 * @max_hang_time:      Maximum time spent in hrtimer_interrupt
 * @clock_base:         array of clock bases for this cpu
 *
 * Note: next_timer is just an optimization for __remove_hrtimer().
 *       Do not dereference the pointer because it is not reliable on
 *       cross cpu removals.
 */

struct hrtimer_cpu_base {
	
raw_spinlock_t			lock;
	
seqcount_t			seq;
	
struct hrtimer			*running;
	
unsigned int			cpu;
	
unsigned int			active_bases;
	
unsigned int			clock_was_set_seq;
	
bool				migration_enabled;
	
bool				nohz_active;
#ifdef CONFIG_HIGH_RES_TIMERS
	
unsigned int			in_hrtirq	: 1,
					
hres_active	: 1,
					
hang_detected	: 1;
	
ktime_t				expires_next;
	
struct hrtimer			*next_timer;
	
unsigned int			nr_events;
	
unsigned int			nr_retries;
	
unsigned int			nr_hangs;
	
unsigned int			max_hang_time;
#endif
	
struct hrtimer_clock_base	clock_base[HRTIMER_MAX_CLOCK_BASES];

} ____cacheline_aligned;


static inline void hrtimer_set_expires(struct hrtimer *timer, ktime_t time) { BUILD_BUG_ON(sizeof(struct hrtimer_clock_base) > HRTIMER_CLOCK_BASE_ALIGN); timer->node.expires = time; timer->_softexpires = time; }

Contributors

PersonTokensPropCommitsCommitProp
Arjan van de Ven2665.00%250.00%
Thomas Gleixner1127.50%125.00%
John Stultz37.50%125.00%
Total40100.00%4100.00%


static inline void hrtimer_set_expires_range(struct hrtimer *timer, ktime_t time, ktime_t delta) { timer->_softexpires = time; timer->node.expires = ktime_add_safe(time, delta); }

Contributors

PersonTokensPropCommitsCommitProp
Arjan van de Ven3491.89%150.00%
John Stultz38.11%150.00%
Total37100.00%2100.00%


static inline void hrtimer_set_expires_range_ns(struct hrtimer *timer, ktime_t time, u64 delta) { timer->_softexpires = time; timer->node.expires = ktime_add_safe(time, ns_to_ktime(delta)); }

Contributors

PersonTokensPropCommitsCommitProp
Arjan van de Ven3690.00%250.00%
John Stultz410.00%250.00%
Total40100.00%4100.00%


static inline void hrtimer_set_expires_tv64(struct hrtimer *timer, s64 tv64) { timer->node.expires = tv64; timer->_softexpires = tv64; }

Contributors

PersonTokensPropCommitsCommitProp
Arjan van de Ven2689.66%266.67%
John Stultz310.34%133.33%
Total29100.00%3100.00%


static inline void hrtimer_add_expires(struct hrtimer *timer, ktime_t time) { timer->node.expires = ktime_add_safe(timer->node.expires, time); timer->_softexpires = ktime_add_safe(timer->_softexpires, time); }

Contributors

PersonTokensPropCommitsCommitProp
Arjan van de Ven3986.67%266.67%
John Stultz613.33%133.33%
Total45100.00%3100.00%


static inline void hrtimer_add_expires_ns(struct hrtimer *timer, u64 ns) { timer->node.expires = ktime_add_ns(timer->node.expires, ns); timer->_softexpires = ktime_add_ns(timer->_softexpires, ns); }

Contributors

PersonTokensPropCommitsCommitProp
Arjan van de Ven3884.44%250.00%
John Stultz613.33%125.00%
David Howells12.22%125.00%
Total45100.00%4100.00%


static inline ktime_t hrtimer_get_expires(const struct hrtimer *timer) { return timer->node.expires; }

Contributors

PersonTokensPropCommitsCommitProp
Arjan van de Ven1785.00%150.00%
John Stultz315.00%150.00%
Total20100.00%2100.00%


static inline ktime_t hrtimer_get_softexpires(const struct hrtimer *timer) { return timer->_softexpires; }

Contributors

PersonTokensPropCommitsCommitProp
Arjan van de Ven18100.00%1100.00%
Total18100.00%1100.00%


static inline s64 hrtimer_get_expires_tv64(const struct hrtimer *timer) { return timer->node.expires; }

Contributors

PersonTokensPropCommitsCommitProp
Arjan van de Ven1785.00%150.00%
John Stultz315.00%150.00%
Total20100.00%2100.00%


static inline s64 hrtimer_get_softexpires_tv64(const struct hrtimer *timer) { return timer->_softexpires; }

Contributors

PersonTokensPropCommitsCommitProp
Arjan van de Ven18100.00%1100.00%
Total18100.00%1100.00%


static inline s64 hrtimer_get_expires_ns(const struct hrtimer *timer) { return ktime_to_ns(timer->node.expires); }

Contributors

PersonTokensPropCommitsCommitProp
Arjan van de Ven2086.96%150.00%
John Stultz313.04%150.00%
Total23100.00%2100.00%


static inline ktime_t hrtimer_expires_remaining(const struct hrtimer *timer) { return ktime_sub(timer->node.expires, timer->base->get_time()); }

Contributors

PersonTokensPropCommitsCommitProp
Arjan van de Ven2790.00%150.00%
John Stultz310.00%150.00%
Total30100.00%2100.00%


static inline ktime_t hrtimer_cb_get_time(struct hrtimer *timer) { return timer->base->get_time(); }

Contributors

PersonTokensPropCommitsCommitProp
Thomas Gleixner20100.00%1100.00%
Total20100.00%1100.00%

#ifdef CONFIG_HIGH_RES_TIMERS struct clock_event_device; extern void hrtimer_interrupt(struct clock_event_device *dev);
static inline int hrtimer_is_hres_active(struct hrtimer *timer) { return timer->base->cpu_base->hres_active; }

Contributors

PersonTokensPropCommitsCommitProp
Peter Zijlstra21100.00%1100.00%
Total21100.00%1100.00%

/* * The resolution of the clocks. The resolution value is returned in * the clock_getres() system call to give application programmers an * idea of the (in)accuracy of timers. Timer values are rounded up to * this resolution values. */ # define HIGH_RES_NSEC 1 # define KTIME_HIGH_RES (HIGH_RES_NSEC) # define MONOTONIC_RES_NSEC HIGH_RES_NSEC # define KTIME_MONOTONIC_RES KTIME_HIGH_RES extern void clock_was_set_delayed(void); extern unsigned int hrtimer_resolution; #else # define MONOTONIC_RES_NSEC LOW_RES_NSEC # define KTIME_MONOTONIC_RES KTIME_LOW_RES #define hrtimer_resolution (unsigned int)LOW_RES_NSEC
static inline int hrtimer_is_hres_active(struct hrtimer *timer) { return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Peter Zijlstra15100.00%1100.00%
Total15100.00%1100.00%


static inline void clock_was_set_delayed(void) { }

Contributors

PersonTokensPropCommitsCommitProp
John Stultz8100.00%1100.00%
Total8100.00%1100.00%

#endif
static inline ktime_t __hrtimer_expires_remaining_adjusted(const struct hrtimer *timer, ktime_t now) { ktime_t rem = ktime_sub(timer->node.expires, now); /* * Adjust relative timers for the extra we added in * hrtimer_start_range_ns() to prevent short timeouts. */ if (IS_ENABLED(CONFIG_TIME_LOW_RES) && timer->is_rel) rem -= hrtimer_resolution; return rem; }

Contributors

PersonTokensPropCommitsCommitProp
Thomas Gleixner49100.00%1100.00%
Total49100.00%1100.00%


static inline ktime_t hrtimer_expires_remaining_adjusted(const struct hrtimer *timer) { return __hrtimer_expires_remaining_adjusted(timer, timer->base->get_time()); }

Contributors

PersonTokensPropCommitsCommitProp
Thomas Gleixner26100.00%1100.00%
Total26100.00%1100.00%

extern void clock_was_set(void); #ifdef CONFIG_TIMERFD extern void timerfd_clock_was_set(void); #else
static inline void timerfd_clock_was_set(void) { }

Contributors

PersonTokensPropCommitsCommitProp
Thomas Gleixner8100.00%1100.00%
Total8100.00%1100.00%

#endif extern void hrtimers_resume(void); DECLARE_PER_CPU(struct tick_device, tick_cpu_device); /* Exported timer functions: */ /* Initialize timers: */ extern void hrtimer_init(struct hrtimer *timer, clockid_t which_clock, enum hrtimer_mode mode); #ifdef CONFIG_DEBUG_OBJECTS_TIMERS extern void hrtimer_init_on_stack(struct hrtimer *timer, clockid_t which_clock, enum hrtimer_mode mode); extern void destroy_hrtimer_on_stack(struct hrtimer *timer); #else
static inline void hrtimer_init_on_stack(struct hrtimer *timer, clockid_t which_clock, enum hrtimer_mode mode) { hrtimer_init(timer, which_clock, mode); }

Contributors

PersonTokensPropCommitsCommitProp
Thomas Gleixner28100.00%1100.00%
Total28100.00%1100.00%


static inline void destroy_hrtimer_on_stack(struct hrtimer *timer) { }

Contributors

PersonTokensPropCommitsCommitProp
Thomas Gleixner11100.00%1100.00%
Total11100.00%1100.00%

#endif /* Basic timer operations: */ extern void hrtimer_start_range_ns(struct hrtimer *timer, ktime_t tim, u64 range_ns, const enum hrtimer_mode mode); /** * hrtimer_start - (re)start an hrtimer on the current CPU * @timer: the timer to be added * @tim: expiry time * @mode: expiry mode: absolute (HRTIMER_MODE_ABS) or * relative (HRTIMER_MODE_REL) */
static inline void hrtimer_start(struct hrtimer *timer, ktime_t tim, const enum hrtimer_mode mode) { hrtimer_start_range_ns(timer, tim, 0, mode); }

Contributors

PersonTokensPropCommitsCommitProp
Thomas Gleixner1754.84%266.67%
Arjan van de Ven1445.16%133.33%
Total31100.00%3100.00%

extern int hrtimer_cancel(struct hrtimer *timer); extern int hrtimer_try_to_cancel(struct hrtimer *timer);
static inline void hrtimer_start_expires(struct hrtimer *timer, enum hrtimer_mode mode) { u64 delta; ktime_t soft, hard; soft = hrtimer_get_softexpires(timer); hard = hrtimer_get_expires(timer); delta = ktime_to_ns(ktime_sub(hard, soft)); hrtimer_start_range_ns(timer, soft, delta, mode); }

Contributors

PersonTokensPropCommitsCommitProp
Arjan van de Ven4675.41%342.86%
Thomas Gleixner1422.95%342.86%
John Stultz11.64%114.29%
Total61100.00%7100.00%


static inline void hrtimer_restart(struct hrtimer *timer) { hrtimer_start_expires(timer, HRTIMER_MODE_ABS); }

Contributors

PersonTokensPropCommitsCommitProp
Thomas Gleixner1894.74%375.00%
Arjan van de Ven15.26%125.00%
Total19100.00%4100.00%

/* Query timers: */ extern ktime_t __hrtimer_get_remaining(const struct hrtimer *timer, bool adjust);
static inline ktime_t hrtimer_get_remaining(const struct hrtimer *timer) { return __hrtimer_get_remaining(timer, false); }

Contributors

PersonTokensPropCommitsCommitProp
Thomas Gleixner21100.00%1100.00%
Total21100.00%1100.00%

extern u64 hrtimer_get_next_event(void); extern bool hrtimer_active(const struct hrtimer *timer); /* * Helper function to check, whether the timer is on one of the queues */
static inline int hrtimer_is_queued(struct hrtimer *timer) { return timer->state & HRTIMER_STATE_ENQUEUED; }

Contributors

PersonTokensPropCommitsCommitProp
Thomas Gleixner19100.00%1100.00%
Total19100.00%1100.00%

/* * Helper function to check, whether the timer is running the callback * function */
static inline int hrtimer_callback_running(struct hrtimer *timer) { return timer->base->cpu_base->running == timer; }

Contributors

PersonTokensPropCommitsCommitProp
Oliver Hartkopp1669.57%150.00%
Peter Zijlstra730.43%150.00%
Total23100.00%2100.00%

/* Forward a hrtimer so it expires after now: */ extern u64 hrtimer_forward(struct hrtimer *timer, ktime_t now, ktime_t interval); /** * hrtimer_forward_now - forward the timer expiry so it expires after now * @timer: hrtimer to forward * @interval: the interval to forward * * Forward the timer expiry so it will expire after the current time * of the hrtimer clock base. Returns the number of overruns. * * Can be safely called from the callback function of @timer. If * called from other contexts @timer must neither be enqueued nor * running the callback and the caller needs to take care of * serialization. * * Note: This only updates the timer expiry value and does not requeue * the timer. */
static inline u64 hrtimer_forward_now(struct hrtimer *timer, ktime_t interval) { return hrtimer_forward(timer, timer->base->get_time(), interval); }

Contributors

PersonTokensPropCommitsCommitProp
Davide Libenzi30100.00%2100.00%
Total30100.00%2100.00%

/* Precise sleep: */ extern long hrtimer_nanosleep(struct timespec64 *rqtp, struct timespec __user *rmtp, const enum hrtimer_mode mode, const clockid_t clockid); extern long hrtimer_nanosleep_restart(struct restart_block *restart_block); extern void hrtimer_init_sleeper(struct hrtimer_sleeper *sl, struct task_struct *tsk); extern int schedule_hrtimeout_range(ktime_t *expires, u64 delta, const enum hrtimer_mode mode); extern int schedule_hrtimeout_range_clock(ktime_t *expires, u64 delta, const enum hrtimer_mode mode, int clock); extern int schedule_hrtimeout(ktime_t *expires, const enum hrtimer_mode mode); /* Soft interrupt function to run the hrtimer queues: */ extern void hrtimer_run_queues(void); /* Bootup initialization: */ extern void __init hrtimers_init(void); /* Show pending timers: */ extern void sysrq_timer_list_show(void); int hrtimers_prepare_cpu(unsigned int cpu); #ifdef CONFIG_HOTPLUG_CPU int hrtimers_dead_cpu(unsigned int cpu); #else #define hrtimers_dead_cpu NULL #endif #endif

Overall Contributors

PersonTokensPropCommitsCommitProp
Thomas Gleixner75752.28%3550.00%
Arjan van de Ven41928.94%68.57%
John Stultz765.25%68.57%
Peter Zijlstra553.80%22.86%
Davide Libenzi312.14%22.86%
Carsten Emde191.31%11.43%
Oliver Hartkopp171.17%11.43%
Arun R Bharadwaj171.17%11.43%
Tony Breeds120.83%11.43%
Toyo Abe100.69%11.43%
Ingo Molnar80.55%11.43%
Roman Zippel50.35%22.86%
Tony Lindgren50.35%11.43%
Viresh Kumar40.28%11.43%
George Anzinger30.21%11.43%
Heiko Carstens30.21%11.43%
David Howells10.07%11.43%
Stephen Rothwell10.07%11.43%
Borislav Petkov10.07%11.43%
Kees Cook10.07%11.43%
Randy Dunlap10.07%11.43%
Oleg Nesterov10.07%11.43%
Deepa Dinamani10.07%11.43%
Total1448100.00%70100.00%
Directory: include/linux
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with cregit.