mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Thomas Gleixner <tglx@linutronix.de>
To: linux-kernel@vger.kernel.org
Cc: akpm@osdl.org, mingo@elte.hu, zippel@linux-m68k.org,
	george@mvista.com, johnstul@us.ibm.com
Subject: [patch 19/43] Introduce ktimer_nanosleep APIs
Date: Thu, 01 Dec 2005 01:03:33 +0100	[thread overview]
Message-ID: <1133395413.32542.462.camel@tglx.tec.linutronix.de> (raw)
In-Reply-To: <20051130231140.164337000@tglx.tec.linutronix.de>

plain text document attachment (ktimer-nanosleep-interface.patch)
- introduce the ktimer_nanosleep() and ktimer_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/ktimer.h |    6 +
 kernel/ktimer.c        |  164 +++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 170 insertions(+)

Index: linux-2.6.15-rc2-rework/include/linux/ktimer.h
===================================================================
--- linux-2.6.15-rc2-rework.orig/include/linux/ktimer.h
+++ linux-2.6.15-rc2-rework/include/linux/ktimer.h
@@ -155,6 +155,12 @@ extern ktime_t ktimer_round_timeval(cons
 extern ktime_t ktimer_round_timespec(const struct ktimer *timer,
 				     const struct timespec *ts);
 
+/* Precise sleep: */
+extern long ktimer_nanosleep(struct timespec *rqtp,
+			     struct timespec __user *rmtp, const int mode);
+extern long ktimer_nanosleep_real(struct timespec *rqtp,
+				  struct timespec __user *rmtp, const int mode);
+
 #ifdef CONFIG_SMP
 extern void wait_for_ktimer(const struct ktimer *timer);
 #else
Index: linux-2.6.15-rc2-rework/kernel/ktimer.c
===================================================================
--- linux-2.6.15-rc2-rework.orig/kernel/ktimer.c
+++ linux-2.6.15-rc2-rework/kernel/ktimer.c
@@ -806,6 +806,170 @@ void ktimer_run_queues(void)
 }
 
 /*
+ * Sleep related functions:
+ */
+
+/*
+ * Process-wakeup callback:
+ */
+static void ktimer_wake_up(void *data)
+{
+	wake_up_process(data);
+}
+
+/**
+ * schedule_ktimer - sleep until timeout
+ *
+ * @timer:	ktimer variable initialized with the correct clock base
+ * @t:		timeout value
+ * @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_ktimer(struct ktimer *timer, ktime_t *t, const int mode)
+{
+	timer->data = current;
+	timer->function = ktimer_wake_up;
+
+	if (unlikely(ktimer_start(timer, t, mode) < 0)) {
+		__set_current_state(TASK_RUNNING);
+	} else {
+		if (current->state != TASK_RUNNING)
+			schedule();
+		ktimer_cancel(timer);
+	}
+
+	/* Store the absolute expiry time */
+	*t = timer->expires;
+
+	/* Return the remaining time */
+	return ktime_sub(timer->expires, timer->expired);
+}
+
+static ktime_t __sched
+schedule_ktimer_interruptible(struct ktimer *timer, ktime_t *t, const int mode)
+{
+	set_current_state(TASK_INTERRUPTIBLE);
+
+	return schedule_ktimer(timer, t, mode);
+}
+
+static long __sched
+nanosleep_restart(struct ktimer *timer, struct restart_block *restart)
+{
+	void *rfn_save = restart->fn;
+	struct timespec __user *rmtp;
+	struct timespec tu;
+	ktime_t t, rem;
+
+	restart->fn = do_no_restart_syscall;
+
+	t = ktime_set_low_high(restart->arg0, restart->arg1);
+
+	rem = schedule_ktimer_interruptible(timer, &t, KTIMER_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)
+{
+	struct ktimer timer;
+
+	ktimer_init(&timer);
+
+	return nanosleep_restart(&timer, restart);
+}
+
+static long __sched nanosleep_restart_real(struct restart_block *restart)
+{
+	struct ktimer timer;
+
+	ktimer_init_clock(&timer, CLOCK_REALTIME);
+
+	return nanosleep_restart(&timer, restart);
+}
+
+static long __ktimer_nanosleep(struct ktimer *timer, struct timespec *rqtp,
+			     struct timespec __user *rmtp, const int mode,
+			     long (*rfn)(struct restart_block *))
+{
+	struct timespec tu;
+	ktime_t rem, t;
+	struct restart_block *restart;
+
+	t = timespec_to_ktime(*rqtp);
+
+	/* t is updated to absolute expiry time ! */
+	rem = schedule_ktimer_interruptible(timer, &t, mode | KTIMER_ROUND);
+
+	if (rem.tv64 <= 0)
+		return 0;
+
+	/* Absolute timers do not update the rmtp value */
+	if (mode == KTIMER_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 = rfn;
+	restart->arg0 = ktime_get_low(t);
+	restart->arg1 = ktime_get_high(t);
+	restart->arg2 = (unsigned long) rmtp;
+
+	return -ERESTART_RESTARTBLOCK;
+}
+
+long ktimer_nanosleep(struct timespec *rqtp,
+			   struct timespec __user *rmtp, const int mode)
+{
+	struct ktimer timer;
+
+	ktimer_init(&timer);
+
+	return __ktimer_nanosleep(&timer, rqtp, rmtp, mode,
+				nanosleep_restart_mono);
+}
+
+long ktimer_nanosleep_real(struct timespec *rqtp,
+			   struct timespec __user *rmtp, const int mode)
+{
+	struct ktimer timer;
+
+	ktimer_init_clock(&timer, CLOCK_REALTIME);
+	return __ktimer_nanosleep(&timer, rqtp, rmtp, mode,
+				nanosleep_restart_real);
+}
+
+/*
  * Functions related to boot-time initialization:
  */
 static void __devinit init_ktimers_cpu(int cpu)

--


  parent reply	other threads:[~2005-12-01  0:07 UTC|newest]

Thread overview: 47+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <20051130231140.164337000@tglx.tec.linutronix.de>
2005-12-01  0:00 ` [patch 01/43] Move div_long_long_rem out of jiffies.h Thomas Gleixner
2005-12-01  2:06   ` Adrian Bunk
2005-12-01 11:38   ` Christoph Hellwig
2005-12-01  0:02 ` [patch 02/43] Remove duplicate div_long_long_rem implementation Thomas Gleixner
2005-12-01  0:02 ` [patch 03/43] Deinline mktime and set_normalized_timespec Thomas Gleixner
2005-12-01  0:02 ` [patch 04/43] Clean up mktime and add const modifiers Thomas Gleixner
2005-12-01  0:02 ` [patch 05/43] Export deinlined mktime Thomas Gleixner
2005-12-01  0:02 ` [patch 06/43] Remove unused clock constants Thomas Gleixner
2005-12-01  0:02 ` [patch 07/43] Cleanup clock constants coding style Thomas Gleixner
2005-12-01  0:03 ` [patch 08/43] Coding style and whitespace cleanup time.h Thomas Gleixner
2005-12-01  0:03 ` [patch 09/43] Make clock selectors in posix-timers const Thomas Gleixner
2005-12-01  0:03 ` [patch 10/43] Coding style and white space cleanup posix-timer.h Thomas Gleixner
2005-12-01  0:03 ` [patch 11/43] Create timespec_valid macro Thomas Gleixner
2005-12-01  0:03 ` [patch 12/43] Check user space timespec in do_sys_settimeofday Thomas Gleixner
2005-12-01  0:03 ` [patch 13/43] Introduce nsec_t type and conversion functions Thomas Gleixner
2005-12-01  0:03 ` [patch 14/43] Introduce ktime_t time format Thomas Gleixner
2005-12-01  0:03 ` [patch 15/43] ktimer core code Thomas Gleixner
2005-12-01  0:03 ` [patch 16/43] ktimer documentation Thomas Gleixner
2005-12-01  0:03 ` [patch 17/43] Switch itimers to ktimer Thomas Gleixner
2005-12-01  0:03 ` [patch 18/43] Remove now unnecessary includes Thomas Gleixner
2005-12-01  0:03 ` Thomas Gleixner [this message]
2005-12-01  0:03 ` [patch 20/43] Convert sys_nanosleep to ktimer_nanosleep Thomas Gleixner
2005-12-01  0:03 ` [patch 21/43] Switch clock_nanosleep to ktimer nanosleep API Thomas Gleixner
2005-12-01  0:03 ` [patch 22/43] Convert posix interval timers to use ktimers Thomas Gleixner
2005-12-01  0:03 ` [patch 23/43] Simplify ktimers rearm code Thomas Gleixner
2005-12-01  0:03 ` [patch 24/43] Split timeout code into kernel/ktimeout.c Thomas Gleixner
2005-12-01  0:03 ` [patch 25/43] Create ktimeout.h and move timer.h code into it Thomas Gleixner
2005-12-01  2:36   ` Adrian Bunk
2005-12-01  2:51     ` Ingo Molnar
2005-12-01  0:03 ` [patch 26/43] Rename struct timer_list to struct ktimeout Thomas Gleixner
2005-12-01  0:03 ` [patch 27/43] Convert timer_list users to ktimeout Thomas Gleixner
2005-12-01  0:03 ` [patch 28/43] Convert ktimeout.h and create wrappers Thomas Gleixner
2005-12-01  0:03 ` [patch 29/43] Convert ktimeout.c to ktimeout struct and APIs Thomas Gleixner
2005-12-01  0:04 ` [patch 30/43] ktimeout documentation Thomas Gleixner
2005-12-01  0:04 ` [patch 31/43] rename init_ktimeout() to ktimeout_init() Thomas Gleixner
2005-12-01  0:04 ` [patch 32/43] rename setup_ktimeout() to ktimeout_setup() Thomas Gleixner
2005-12-01  0:04 ` [patch 33/43] rename add_ktimeout_on() to ktimeout_add_on() Thomas Gleixner
2005-12-01  0:04 ` [patch 34/43] rename del_ktimeout() to ktimeout_del() Thomas Gleixner
2005-12-01  0:04 ` [patch 35/43] rename __mod_ktimeout() to __mod_ktimeout() Thomas Gleixner
2005-12-01  0:04 ` [patch 36/43] rename mod_ktimeout() to ktimeout_mod() Thomas Gleixner
2005-12-01  0:04 ` [patch 37/43] rename next_ktimeout_interrupt() to ktimeout_next_interrupt() Thomas Gleixner
2005-12-01  0:04 ` [patch 38/43] rename add_ktimeout() to ktimeout_add() Thomas Gleixner
2005-12-01  0:04 ` [patch 39/43] rename try_to_del_ktimeout_sync() to ktimeout_try_to_del_sync() Thomas Gleixner
2005-12-01  0:04 ` [patch 40/43] rename del_ktimeout_sync() to del_ktimeout_sync() Thomas Gleixner
2005-12-01  0:04 ` [patch 41/43] rename del_singleshot_ktimeout_sync() to ktimeout_del_singleshot_sync() Thomas Gleixner
2005-12-01  0:04 ` [patch 42/43] rename TIMER_SOFTIRQ to TIMEOUT_SOFTIRQ Thomas Gleixner
2005-12-01  0:04 ` [patch 43/43] ktimeout code style cleanups 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=1133395413.32542.462.camel@tglx.tec.linutronix.de \
    --to=tglx@linutronix.de \
    --cc=akpm@osdl.org \
    --cc=george@mvista.com \
    --cc=johnstul@us.ibm.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@elte.hu \
    --cc=zippel@linux-m68k.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®