From: tglx@linutronix.de
To: linux-kernel@vger.kernel.org
Cc: akpm@osdl.org, rostedt@goodmis.org, johnstul@us.ibm.com,
zippel@linux-m86k.org, mingo@elte.hu
Subject: [patch 18/21] Create hrtimer nanosleep API
Date: Tue, 06 Dec 2005 01:01:44 +0100 [thread overview]
Message-ID: <20051206000155.335080000@tglx.tec.linutronix.de> (raw)
In-Reply-To: <20051206000126.589223000@tglx.tec.linutronix.de>
[-- Attachment #1: hrtimer-nanosleep-interface.patch --]
[-- Type: text/plain, Size: 4700 bytes --]
- introduce the hrtimer_nanosleep() and hrtimer_nanosleep_real() APIs.
Not yet used by any code.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
include/linux/hrtimer.h | 6 ++
kernel/hrtimer.c | 127 ++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 133 insertions(+)
Index: linux-2.6.15-rc5/include/linux/hrtimer.h
===================================================================
--- linux-2.6.15-rc5.orig/include/linux/hrtimer.h
+++ linux-2.6.15-rc5/include/linux/hrtimer.h
@@ -121,6 +121,12 @@ static inline int hrtimer_active(const s
extern unsigned long hrtimer_forward(struct hrtimer *timer,
const ktime_t interval);
+/* Precise sleep: */
+extern long hrtimer_nanosleep(struct timespec *rqtp,
+ struct timespec __user *rmtp,
+ const enum hrtimer_mode mode,
+ const clockid_t clockid);
+
/* Soft interrupt function to run the hrtimer queues: */
extern void hrtimer_run_queues(void);
Index: linux-2.6.15-rc5/kernel/hrtimer.c
===================================================================
--- linux-2.6.15-rc5.orig/kernel/hrtimer.c
+++ linux-2.6.15-rc5/kernel/hrtimer.c
@@ -581,6 +581,133 @@ void hrtimer_run_queues(void)
}
/*
+ * Sleep related functions:
+ */
+
+/**
+ * schedule_hrtimer - sleep until timeout
+ *
+ * @timer: hrtimer variable initialized with the correct clock base
+ * @mode: timeout value is abs/rel
+ *
+ * Make the current task sleep until @timeout is
+ * elapsed.
+ *
+ * You can set the task state as follows -
+ *
+ * %TASK_UNINTERRUPTIBLE - at least @timeout is guaranteed to
+ * pass before the routine returns. The routine will return 0
+ *
+ * %TASK_INTERRUPTIBLE - the routine may return early if a signal is
+ * delivered to the current task. In this case the remaining time
+ * will be returned
+ *
+ * The current task state is guaranteed to be TASK_RUNNING when this
+ * routine returns.
+ */
+static ktime_t __sched
+schedule_hrtimer(struct hrtimer *timer, const enum hrtimer_mode mode)
+{
+ /* fn stays NULL, meaning single-shot wakeup: */
+ timer->data = current;
+
+ hrtimer_start(timer, timer->expires, mode);
+
+ schedule();
+ hrtimer_cancel(timer);
+
+ /* Return the remaining time: */
+ if (timer->state != HRTIMER_EXPIRED)
+ return ktime_sub(timer->expires, timer->base->get_time());
+ else
+ return (ktime_t) {.tv64 = 0 };
+}
+
+static inline ktime_t __sched
+schedule_hrtimer_interruptible(struct hrtimer *timer,
+ const enum hrtimer_mode mode)
+{
+ set_current_state(TASK_INTERRUPTIBLE);
+
+ return schedule_hrtimer(timer, mode);
+}
+
+static long __sched
+nanosleep_restart(struct restart_block *restart, clockid_t clockid)
+{
+ struct timespec __user *rmtp, tu;
+ void *rfn_save = restart->fn;
+ struct hrtimer timer;
+ ktime_t rem;
+
+ restart->fn = do_no_restart_syscall;
+
+ hrtimer_init(&timer, clockid);
+
+ timer.expires.tv64 = ((u64)restart->arg1 << 32) | (u64) restart->arg0;
+
+ rem = schedule_hrtimer_interruptible(&timer, HRTIMER_ABS);
+
+ if (rem.tv64 <= 0)
+ return 0;
+
+ rmtp = (struct timespec __user *) restart->arg2;
+ tu = ktime_to_timespec(rem);
+ if (rmtp && copy_to_user(rmtp, &tu, sizeof(tu)))
+ return -EFAULT;
+
+ restart->fn = rfn_save;
+
+ /* The other values in restart are already filled in */
+ return -ERESTART_RESTARTBLOCK;
+}
+
+static long __sched nanosleep_restart_mono(struct restart_block *restart)
+{
+ return nanosleep_restart(restart, CLOCK_MONOTONIC);
+}
+
+static long __sched nanosleep_restart_real(struct restart_block *restart)
+{
+ return nanosleep_restart(restart, CLOCK_REALTIME);
+}
+
+long hrtimer_nanosleep(struct timespec *rqtp, struct timespec __user *rmtp,
+ const enum hrtimer_mode mode, const clockid_t clockid)
+{
+ struct restart_block *restart;
+ struct hrtimer timer;
+ struct timespec tu;
+ ktime_t rem;
+
+ hrtimer_init(&timer, clockid);
+
+ timer.expires = timespec_to_ktime(*rqtp);
+
+ rem = schedule_hrtimer_interruptible(&timer, mode);
+ if (rem.tv64 <= 0)
+ return 0;
+
+ /* Absolute timers do not update the rmtp value: */
+ if (mode == HRTIMER_ABS)
+ return -ERESTARTNOHAND;
+
+ tu = ktime_to_timespec(rem);
+
+ if (rmtp && copy_to_user(rmtp, &tu, sizeof(tu)))
+ return -EFAULT;
+
+ restart = ¤t_thread_info()->restart_block;
+ restart->fn = (clockid == CLOCK_MONOTONIC) ?
+ nanosleep_restart_mono : nanosleep_restart_real;
+ restart->arg0 = timer.expires.tv64 & 0xFFFFFFFF;
+ restart->arg1 = timer.expires.tv64 >> 32;
+ restart->arg2 = (unsigned long) rmtp;
+
+ return -ERESTART_RESTARTBLOCK;
+}
+
+/*
* Functions related to boot-time initialization:
*/
static void __devinit init_hrtimers_cpu(int cpu)
--
next prev parent reply other threads:[~2005-12-06 0:39 UTC|newest]
Thread overview: 69+ messages / expand[flat|nested] mbox.gz Atom feed top
2005-12-06 0:01 [patch 00/21] hrtimer - High-resolution timer subsystem tglx
2005-12-06 0:01 ` [patch 01/21] Move div_long_long_rem out of jiffies.h tglx
2005-12-06 0:01 ` [patch 02/21] Remove duplicate div_long_long_rem implementation tglx
2005-12-06 0:01 ` [patch 03/21] Deinline mktime and set_normalized_timespec tglx
2005-12-06 0:01 ` [patch 04/21] Clean up mktime and make arguments const tglx
2005-12-06 0:01 ` [patch 05/21] Export deinlined mktime tglx
2005-12-06 0:01 ` [patch 06/21] Remove unused clock constants tglx
2005-12-06 0:01 ` [patch 07/21] Coding style clean up of " tglx
2005-12-06 0:01 ` [patch 08/21] Coding style and white space cleanup tglx
2005-12-06 0:01 ` [patch 09/21] Make clockid_t arguments const tglx
2005-12-06 0:01 ` [patch 10/21] Coding style and white space cleanup tglx
2005-12-06 0:01 ` [patch 11/21] Create and use timespec_valid macro tglx
2005-12-06 0:01 ` [patch 12/21] Validate timespec of do_sys_settimeofday tglx
2005-12-06 0:01 ` [patch 13/21] Introduce nsec_t type and conversion functions tglx
2005-12-06 0:01 ` [patch 14/21] Introduce ktime_t time format tglx
2005-12-06 0:01 ` [patch 15/21] hrtimer core code tglx
2005-12-15 3:43 ` Matt Helsley
2005-12-06 0:01 ` [patch 16/21] hrtimer documentation tglx
2005-12-06 0:01 ` [patch 17/21] Switch itimers to hrtimer tglx
2005-12-06 0:01 ` tglx [this message]
2005-12-06 0:01 ` [patch 19/21] Switch sys_nanosleep " tglx
2005-12-06 0:01 ` [patch 20/21] Switch clock_nanosleep to hrtimer nanosleep API tglx
2005-12-06 0:01 ` [patch 21/21] Convert posix timers completely tglx
2005-12-06 17:32 ` [patch 00/21] hrtimer - High-resolution timer subsystem Roman Zippel
2005-12-06 19:07 ` Ingo Molnar
2005-12-07 3:05 ` Roman Zippel
2005-12-08 5:18 ` Paul Jackson
2005-12-08 8:12 ` Ingo Molnar
2005-12-08 9:26 ` Ingo Molnar
2005-12-08 13:08 ` Roman Zippel
2005-12-08 15:36 ` Steven Rostedt
2005-12-06 22:10 ` Thomas Gleixner
2005-12-07 3:11 ` Roman Zippel
2005-12-06 22:28 ` Thomas Gleixner
2005-12-07 9:31 ` Andrew Morton
2005-12-07 10:11 ` Ingo Molnar
2005-12-07 10:20 ` Ingo Molnar
2005-12-07 10:23 ` Nick Piggin
2005-12-07 10:49 ` Ingo Molnar
2005-12-07 11:09 ` Nick Piggin
2005-12-07 11:33 ` Ingo Molnar
2005-12-07 11:40 ` Nick Piggin
2005-12-07 13:06 ` Roman Zippel
2005-12-07 12:40 ` Roman Zippel
2005-12-07 23:12 ` Nick Piggin
2005-12-07 12:18 ` Roman Zippel
2005-12-07 16:55 ` Ingo Molnar
2005-12-07 17:17 ` Roman Zippel
2005-12-07 17:57 ` Ingo Molnar
2005-12-07 18:18 ` Roman Zippel
2005-12-07 18:02 ` Paul Baxter
2005-12-09 17:23 ` Thomas Gleixner
2005-12-12 13:39 ` Roman Zippel
2005-12-12 16:42 ` Thomas Gleixner
2005-12-12 18:37 ` Thomas Gleixner
2005-12-13 1:25 ` George Anzinger
2005-12-13 9:18 ` Thomas Gleixner
2005-12-15 1:35 ` Roman Zippel
2005-12-15 2:29 ` George Anzinger
2005-12-19 14:56 ` Roman Zippel
2005-12-19 20:54 ` George Anzinger
2005-12-21 23:03 ` Roman Zippel
2005-12-22 4:30 ` George Anzinger
2005-12-14 20:48 ` Roman Zippel
2005-12-14 22:30 ` Thomas Gleixner
2005-12-15 0:55 ` George Anzinger
2005-12-15 14:18 ` Steven Rostedt
2005-12-19 14:50 ` Roman Zippel
2005-12-19 22:05 ` Thomas Gleixner
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=20051206000155.335080000@tglx.tec.linutronix.de \
--to=tglx@linutronix.de \
--cc=akpm@osdl.org \
--cc=johnstul@us.ibm.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@elte.hu \
--cc=rostedt@goodmis.org \
--cc=zippel@linux-m86k.org \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®