summaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
authorCon Kolivas <kernel@kolivas.org>2016-11-01 12:54:20 +1100
committerCon Kolivas <kernel@kolivas.org>2016-11-01 12:54:54 +1100
commitda7832bb05a0819f0a056657b1eead8e501e00ff (patch)
treeff4930189c2c3f80b6f5ba964532cde92b82622b /kernel
parentd2a88342b9d69e550ae21d5d1fdd7a15fe039159 (diff)
Use high resolution timers in place of regular ones whenever possible on muqss since they are mandatory and low Hz is recommended.
Diffstat (limited to 'kernel')
-rw-r--r--kernel/time/timer.c33
1 files changed, 31 insertions, 2 deletions
diff --git a/kernel/time/timer.c b/kernel/time/timer.c
index f0be61c19bfb..782eb4f137e0 100644
--- a/kernel/time/timer.c
+++ b/kernel/time/timer.c
@@ -1745,6 +1745,35 @@ signed long __sched schedule_timeout(signed long timeout)
expire = timeout + jiffies;
+#if defined(CONFIG_SCHED_MUQSS)
+ /*
+ * Use high resolution timers in place of regular ones whenever possible
+ * on muqss since they are mandatory and low Hz is recommended.
+ */
+ if (likely(hrtimer_resolution < NSEC_PER_SEC / HZ)) {
+ int delta, secs;
+ ktime_t expires;
+
+ if (!timeout) {
+ current->state = TASK_RUNNING;
+ goto out;
+ }
+ secs = timeout / HZ;
+ delta = timeout % HZ;
+ delta *= NSEC_PER_SEC / HZ;
+ /*
+ * Round down half a tick to match what it would have been on
+ * average with regular tick based timers.
+ */
+ delta -= NSEC_PER_SEC / HZ / 2;
+ expires = ktime_set(secs, delta);
+ if (schedule_hrtimeout(&expires, HRTIMER_MODE_REL_PINNED) == -EINTR)
+ goto out_timeout;
+ timeout = 0;
+ goto out;
+ }
+#endif
+
setup_timer_on_stack(&timer, process_timeout, (unsigned long)current);
__mod_timer(&timer, expire, false);
schedule();
@@ -1752,10 +1781,10 @@ signed long __sched schedule_timeout(signed long timeout)
/* Remove the timer from the object tracker */
destroy_timer_on_stack(&timer);
-
+out_timeout:
timeout = expire - jiffies;
- out:
+out:
return timeout < 0 ? 0 : timeout;
}
EXPORT_SYMBOL(schedule_timeout);