提交 9fd87545 编写于 作者: I Ingo Molnar

Merge branch 'master' of...

Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/arjan/linux-2.6-hrtimer into timers/range-hrtimers
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include <linux/cpu.h> #include <linux/cpu.h>
#include <linux/cpuidle.h> #include <linux/cpuidle.h>
#include <linux/ktime.h> #include <linux/ktime.h>
#include <linux/hrtimer.h>
#include "cpuidle.h" #include "cpuidle.h"
...@@ -60,6 +61,12 @@ static void cpuidle_idle_call(void) ...@@ -60,6 +61,12 @@ static void cpuidle_idle_call(void)
return; return;
} }
/*
* run any timers that can be run now, at this point
* before calculating the idle duration etc.
*/
hrtimer_peek_ahead_timers();
/* ask the governor for the next state */ /* ask the governor for the next state */
next_state = cpuidle_curr_governor->select(dev); next_state = cpuidle_curr_governor->select(dev);
if (need_resched()) if (need_resched())
......
...@@ -283,6 +283,8 @@ static inline int hrtimer_is_hres_active(struct hrtimer *timer) ...@@ -283,6 +283,8 @@ static inline int hrtimer_is_hres_active(struct hrtimer *timer)
return timer->base->cpu_base->hres_active; return timer->base->cpu_base->hres_active;
} }
extern void hrtimer_peek_ahead_timers(void);
/* /*
* The resolution of the clocks. The resolution value is returned in * The resolution of the clocks. The resolution value is returned in
* the clock_getres() system call to give application programmers an * the clock_getres() system call to give application programmers an
...@@ -305,6 +307,7 @@ static inline int hrtimer_is_hres_active(struct hrtimer *timer) ...@@ -305,6 +307,7 @@ static inline int hrtimer_is_hres_active(struct hrtimer *timer)
* is expired in the next softirq when the clock was advanced. * is expired in the next softirq when the clock was advanced.
*/ */
static inline void clock_was_set(void) { } static inline void clock_was_set(void) { }
static inline void hrtimer_peek_ahead_timers(void) { }
static inline void hres_timers_resume(void) { } static inline void hres_timers_resume(void) { }
...@@ -326,6 +329,10 @@ static inline int hrtimer_is_hres_active(struct hrtimer *timer) ...@@ -326,6 +329,10 @@ static inline int hrtimer_is_hres_active(struct hrtimer *timer)
extern ktime_t ktime_get(void); extern ktime_t ktime_get(void);
extern ktime_t ktime_get_real(void); extern ktime_t ktime_get_real(void);
DECLARE_PER_CPU(struct tick_device, tick_cpu_device);
/* Exported timer functions: */ /* Exported timer functions: */
/* Initialize timers: */ /* Initialize timers: */
......
...@@ -1296,10 +1296,14 @@ static int futex_wait(u32 __user *uaddr, struct rw_semaphore *fshared, ...@@ -1296,10 +1296,14 @@ static int futex_wait(u32 __user *uaddr, struct rw_semaphore *fshared,
if (!abs_time) if (!abs_time)
schedule(); schedule();
else { else {
unsigned long slack;
slack = current->timer_slack_ns;
if (rt_task(current))
slack = 0;
hrtimer_init_on_stack(&t.timer, CLOCK_MONOTONIC, hrtimer_init_on_stack(&t.timer, CLOCK_MONOTONIC,
HRTIMER_MODE_ABS); HRTIMER_MODE_ABS);
hrtimer_init_sleeper(&t, current); hrtimer_init_sleeper(&t, current);
hrtimer_set_expires(&t.timer, *abs_time); hrtimer_set_expires_range_ns(&t.timer, *abs_time, slack);
hrtimer_start_expires(&t.timer, HRTIMER_MODE_ABS); hrtimer_start_expires(&t.timer, HRTIMER_MODE_ABS);
if (!hrtimer_active(&t.timer)) if (!hrtimer_active(&t.timer))
......
...@@ -1381,6 +1381,36 @@ void hrtimer_interrupt(struct clock_event_device *dev) ...@@ -1381,6 +1381,36 @@ void hrtimer_interrupt(struct clock_event_device *dev)
raise_softirq(HRTIMER_SOFTIRQ); raise_softirq(HRTIMER_SOFTIRQ);
} }
/**
* hrtimer_peek_ahead_timers -- run soft-expired timers now
*
* hrtimer_peek_ahead_timers will peek at the timer queue of
* the current cpu and check if there are any timers for which
* the soft expires time has passed. If any such timers exist,
* they are run immediately and then removed from the timer queue.
*
*/
void hrtimer_peek_ahead_timers(void)
{
unsigned long flags;
struct tick_device *td;
struct clock_event_device *dev;
if (hrtimer_hres_active())
return;
local_irq_save(flags);
td = &__get_cpu_var(tick_cpu_device);
if (!td)
goto out;
dev = td->evtdev;
if (!dev)
goto out;
hrtimer_interrupt(dev);
out:
local_irq_restore(flags);
}
static void run_hrtimer_softirq(struct softirq_action *h) static void run_hrtimer_softirq(struct softirq_action *h)
{ {
run_hrtimer_pending(&__get_cpu_var(hrtimer_bases)); run_hrtimer_pending(&__get_cpu_var(hrtimer_bases));
...@@ -1563,9 +1593,14 @@ long hrtimer_nanosleep(struct timespec *rqtp, struct timespec __user *rmtp, ...@@ -1563,9 +1593,14 @@ long hrtimer_nanosleep(struct timespec *rqtp, struct timespec __user *rmtp,
struct restart_block *restart; struct restart_block *restart;
struct hrtimer_sleeper t; struct hrtimer_sleeper t;
int ret = 0; int ret = 0;
unsigned long slack;
slack = current->timer_slack_ns;
if (rt_task(current))
slack = 0;
hrtimer_init_on_stack(&t.timer, clockid, mode); hrtimer_init_on_stack(&t.timer, clockid, mode);
hrtimer_set_expires(&t.timer, timespec_to_ktime(*rqtp)); hrtimer_set_expires_range_ns(&t.timer, timespec_to_ktime(*rqtp), slack);
if (do_nanosleep(&t, mode)) if (do_nanosleep(&t, mode))
goto out; goto out;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册