mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
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 = &current_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)

--


  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®