From: Arjan van de Ven <arjan@infradead.org>
To: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-kernel@vger.kernel.org, mingo@elte.hu, alan@linux.intel.com
Subject: [patch] timer: Add a mod_timer_msec() API function
Date: Sun, 22 Nov 2009 15:41:11 -0800 [thread overview]
Message-ID: <20091122154111.197e1a8a@infradead.org> (raw)
Subject: timer: add a mod_timer_msec() API function
From: Arjan van de Ven <arjan@linux.intel.com>
There is a common pattern in the kernel, where the caller wants
to set a timer a specified number of milliseconds into the future.
The typical solution then ends up
mod_timer(&timer, jiffies + msecs_to_jiffies(msec_amount));
or
mod_timer(&timer, jiffies + HZ/some_value);
This patch aims to simplify this pattern for the caller, and at
the same time, make for a more power-friendly API.
The new pattern for identical behavior will be
mod_timer_msec(&timer, msec_amount, 0);
while
mod_timer_msec(&time, msec_amount, 100);
would give the kernel 100 milliseconds of slack to find a power
friendly time to group timers into one CPU wakeup.
A patch to convert a number of users, to show how the API is used,
will be sent as reply to this email.
Signed-off-by: Arjan van de Ven <arjan@linux.intel.com>
diff --git a/include/linux/timer.h b/include/linux/timer.h
index a2d1eb6..006d4da 100644
--- a/include/linux/timer.h
+++ b/include/linux/timer.h
@@ -162,6 +162,7 @@ static inline int timer_pending(const struct timer_list * timer)
extern void add_timer_on(struct timer_list *timer, int cpu);
extern int del_timer(struct timer_list * timer);
extern int mod_timer(struct timer_list *timer, unsigned long expires);
+extern int mod_timer_msec(struct timer_list *timer, unsigned long delay_ms, unsigned long slack_ms);
extern int mod_timer_pending(struct timer_list *timer, unsigned long expires);
extern int mod_timer_pinned(struct timer_list *timer, unsigned long expires);
diff --git a/kernel/timer.c b/kernel/timer.c
index 5db5a8d..c9d5cbf 100644
--- a/kernel/timer.c
+++ b/kernel/timer.c
@@ -751,6 +751,47 @@ int mod_timer(struct timer_list *timer, unsigned long expires)
EXPORT_SYMBOL(mod_timer);
/**
+ * mod_timer_msec - modify a timer's timeout, using relative milliseconds
+ * @timer: the timer to be modified
+ * @delay_ms: the desired minimum delay in milliseconds
+ * @slack_ms: the amount of slack is ok in firing the timer
+ *
+ * Changes the timeout of a timer similar to mod_timer().
+ *
+ * mod_timer_msec() takes relative milliseconds rather than absolute
+ * jiffies as argument and also takes a "slack" amount, which is
+ * an explicit permission to treat the time of the timer as less
+ * precise in order to allow grouping of timers.
+ *
+ * The function returns whether it has modified a pending timer or not.
+ * (ie. mod_timer() of an inactive timer returns 0, mod_timer() of an
+ * active timer returns 1.)
+ */
+int mod_timer_msec(struct timer_list *timer, unsigned long delay_ms, unsigned long slack_ms)
+{
+ unsigned long next_jiffies, max_jiffies;
+ unsigned long rounded_jiffies;
+
+ next_jiffies = jiffies + msecs_to_jiffies(delay_ms);
+ max_jiffies = jiffies + msecs_to_jiffies(delay_ms + slack_ms);
+ rounded_jiffies = round_jiffies(next_jiffies);
+
+ /* check if rounding up next_jiffies is within the max */
+ if (rounded_jiffies <= max_jiffies && rounded_jiffies >= next_jiffies) {
+ next_jiffies = rounded_jiffies;
+ } else {
+ /* regular rounding failed; try a rounding to multiple-of-16 */
+ rounded_jiffies = (next_jiffies + 15) & ~0xF;
+ if (rounded_jiffies <= max_jiffies)
+ next_jiffies = rounded_jiffies;
+ }
+
+ return mod_timer(timer, next_jiffies);
+}
+EXPORT_SYMBOL_GPL(mod_timer_msec);
+
+
+/**
* mod_timer_pinned - modify a timer's timeout
* @timer: the timer to be modified
* @expires: new timeout in jiffies
--
Arjan van de Ven Intel Open Source Technology Centre
For development, discussion and tips for power savings,
visit http://www.lesswatts.org
next reply other threads:[~2009-11-22 23:39 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-11-22 23:41 Arjan van de Ven [this message]
2009-11-22 23:42 ` [patch] timer: Add a mod_timer_msec() API function Arjan van de Ven
2009-11-23 8:26 ` Ingo Molnar
2009-11-23 14:51 ` Arjan van de Ven
2009-11-23 17:19 ` Thomas Gleixner
2009-11-24 10:14 ` Alan Cox
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20091122154111.197e1a8a@infradead.org \
--to=arjan@infradead.org \
--cc=alan@linux.intel.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@elte.hu \
--cc=tglx@linutronix.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.