79bf2bb335
With Ingo Molnar <mingo@elte.hu> Add functions to provide dynamic ticks and high resolution timers. The code which keeps track of jiffies and handles the long idle periods is shared between tick based and high resolution timer based dynticks. The dyntick functionality can be disabled on the kernel commandline. Provide also the infrastructure to support high resolution timers. Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Ingo Molnar <mingo@elte.hu> Cc: john stultz <johnstul@us.ibm.com> Cc: Roman Zippel <zippel@linux-m68k.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
111 lines
3.5 KiB
C
111 lines
3.5 KiB
C
/*
|
|
* tick internal variable and functions used by low/high res code
|
|
*/
|
|
DECLARE_PER_CPU(struct tick_device, tick_cpu_device);
|
|
extern spinlock_t tick_device_lock;
|
|
extern ktime_t tick_next_period;
|
|
extern ktime_t tick_period;
|
|
|
|
extern void tick_setup_periodic(struct clock_event_device *dev, int broadcast);
|
|
extern void tick_handle_periodic(struct clock_event_device *dev);
|
|
|
|
/*
|
|
* NO_HZ / high resolution timer shared code
|
|
*/
|
|
#ifdef CONFIG_TICK_ONESHOT
|
|
extern void tick_setup_oneshot(struct clock_event_device *newdev,
|
|
void (*handler)(struct clock_event_device *),
|
|
ktime_t nextevt);
|
|
extern int tick_program_event(ktime_t expires, int force);
|
|
extern void tick_oneshot_notify(void);
|
|
extern int tick_switch_to_oneshot(void (*handler)(struct clock_event_device *));
|
|
|
|
# ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
|
|
extern void tick_broadcast_setup_oneshot(struct clock_event_device *bc);
|
|
extern void tick_broadcast_oneshot_control(unsigned long reason);
|
|
extern void tick_broadcast_switch_to_oneshot(void);
|
|
extern void tick_shutdown_broadcast_oneshot(unsigned int *cpup);
|
|
# else /* BROADCAST */
|
|
static inline void tick_broadcast_setup_oneshot(struct clock_event_device *bc)
|
|
{
|
|
BUG();
|
|
}
|
|
static inline void tick_broadcast_oneshot_control(unsigned long reason) { }
|
|
static inline void tick_broadcast_switch_to_oneshot(void) { }
|
|
static inline void tick_shutdown_broadcast_oneshot(unsigned int *cpup) { }
|
|
# endif /* !BROADCAST */
|
|
|
|
#else /* !ONESHOT */
|
|
static inline
|
|
void tick_setup_oneshot(struct clock_event_device *newdev,
|
|
void (*handler)(struct clock_event_device *),
|
|
ktime_t nextevt)
|
|
{
|
|
BUG();
|
|
}
|
|
static inline int tick_program_event(ktime_t expires, int force)
|
|
{
|
|
return 0;
|
|
}
|
|
static inline void tick_oneshot_notify(void) { }
|
|
static inline void tick_broadcast_setup_oneshot(struct clock_event_device *bc)
|
|
{
|
|
BUG();
|
|
}
|
|
static inline void tick_broadcast_oneshot_control(unsigned long reason) { }
|
|
static inline void tick_shutdown_broadcast_oneshot(unsigned int *cpup) { }
|
|
#endif /* !TICK_ONESHOT */
|
|
|
|
/*
|
|
* Broadcasting support
|
|
*/
|
|
#ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
|
|
extern int tick_do_broadcast(cpumask_t mask);
|
|
|
|
extern int tick_device_uses_broadcast(struct clock_event_device *dev, int cpu);
|
|
extern int tick_check_broadcast_device(struct clock_event_device *dev);
|
|
extern int tick_is_broadcast_device(struct clock_event_device *dev);
|
|
extern void tick_broadcast_on_off(unsigned long reason, int *oncpu);
|
|
extern void tick_shutdown_broadcast(unsigned int *cpup);
|
|
|
|
extern void
|
|
tick_set_periodic_handler(struct clock_event_device *dev, int broadcast);
|
|
|
|
#else /* !BROADCAST */
|
|
|
|
static inline int tick_check_broadcast_device(struct clock_event_device *dev)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
static inline int tick_is_broadcast_device(struct clock_event_device *dev)
|
|
{
|
|
return 0;
|
|
}
|
|
static inline int tick_device_uses_broadcast(struct clock_event_device *dev,
|
|
int cpu)
|
|
{
|
|
return 0;
|
|
}
|
|
static inline void tick_do_periodic_broadcast(struct clock_event_device *d) { }
|
|
static inline void tick_broadcast_on_off(unsigned long reason, int *oncpu) { }
|
|
static inline void tick_shutdown_broadcast(unsigned int *cpup) { }
|
|
|
|
/*
|
|
* Set the periodic handler in non broadcast mode
|
|
*/
|
|
static inline void tick_set_periodic_handler(struct clock_event_device *dev,
|
|
int broadcast)
|
|
{
|
|
dev->event_handler = tick_handle_periodic;
|
|
}
|
|
#endif /* !BROADCAST */
|
|
|
|
/*
|
|
* Check, if the device is functional or a dummy for broadcast
|
|
*/
|
|
static inline int tick_device_is_functional(struct clock_event_device *dev)
|
|
{
|
|
return !(dev->features & CLOCK_EVT_FEAT_DUMMY);
|
|
}
|