The Linux Kernel Mailing List
 help / color / mirror / Atom feed
From: Christoph Hellwig <hch@ns.caldera.de>
To: mkarras110@yahoo.com (Michael Arras)
Cc: linux-kernel@vger.kernel.org, torvalds@transmeta.com,
	marcelo@conectiva.com.br
Subject: Re: [PATCH] Fix for sys_nanosleep() in 2.4.16
Date: Thu, 29 Nov 2001 11:04:47 +0100	[thread overview]
Message-ID: <200111291004.fATA4l608978@ns.caldera.de> (raw)
In-Reply-To: <3C05DC1D.7071FC6B@yahoo.com>

In article <3C05DC1D.7071FC6B@yahoo.com> you wrote:
> Greetings,
>
> For many of us, the kernel thread scheduling resolution is
> 10ms (see getitimer(2)).  By adding 1 jiffy to the time to
> sleep in sys_nanosleep(), threads are sleeping 10ms too long.
> timespec_to_jiffies() does a good job at returning the
> appropriate number of jiffies to sleep.  There is no need to
> add one for good measure.

Please take a look at:

http://www.kernel.org/pub/linux/kernel/people/andrea/kernels/v2.4/2.4.15aa1/00_nanosleep-5

instead.

Linus & Marcelo: any chance to get that into the tree? (patch is inlined below)

	Christoph

-- 
Of course it doesn't work. We've performed a software upgrade.


diff -urN 2.4.6pre6/include/linux/time.h nanosleep/include/linux/time.h
--- 2.4.6pre6/include/linux/time.h	Thu Jun 14 18:07:48 2001
+++ nanosleep/include/linux/time.h	Thu Jun 28 11:47:14 2001
@@ -48,6 +48,27 @@
 	value->tv_sec = jiffies / HZ;
 }
 
+static __inline__ int
+timespec_before(struct timespec a, struct timespec b)
+{
+	if (a.tv_sec == b.tv_sec)
+		return a.tv_nsec < b.tv_nsec;
+	return a.tv_sec < b.tv_sec;
+}
+
+/* computes `a - b'  and write the result in `result', assumes `a >= b' */
+static inline void
+timespec_less(struct timespec a, struct timespec b, struct timespec * result)
+{
+	if (a.tv_nsec < b.tv_nsec)
+	{
+		a.tv_sec--;
+		a.tv_nsec += 1000000000;
+	}
+
+	result->tv_sec = a.tv_sec - b.tv_sec;
+	result->tv_nsec = a.tv_nsec - b.tv_nsec;
+}
 
 /* Converts Gregorian date to seconds since 1970-01-01 00:00:00.
  * Assumes input in normal date format, i.e. 1980-12-31 23:59:59
@@ -89,6 +110,27 @@
 	time_t		tv_sec;		/* seconds */
 	suseconds_t	tv_usec;	/* microseconds */
 };
+
+/* computes `a - b'  and write the result in `result', assumes `a >= b' */
+static inline void
+timeval_less(struct timeval a, struct timeval b, struct timeval * result)
+{
+	if (a.tv_usec < b.tv_usec)
+	{
+		a.tv_sec--;
+		a.tv_usec += 1000000;
+	}
+
+	result->tv_sec = a.tv_sec - b.tv_sec;
+	result->tv_usec = a.tv_usec - b.tv_usec;
+}
+
+static __inline__ void
+timeval_to_timespec(struct timeval tv, struct timespec * ts)
+{
+	ts->tv_sec = tv.tv_sec;
+	ts->tv_nsec = (long) tv.tv_usec * 1000;
+}
 
 struct timezone {
 	int	tz_minuteswest;	/* minutes west of Greenwich */
diff -urN 2.4.6pre6/kernel/timer.c nanosleep/kernel/timer.c
--- 2.4.6pre6/kernel/timer.c	Thu Jun 28 11:38:09 2001
+++ nanosleep/kernel/timer.c	Thu Jun 28 11:48:47 2001
@@ -798,6 +798,7 @@
 {
 	struct timespec t;
 	unsigned long expire;
+	struct timeval before, after;
 
 	if(copy_from_user(&t, rqtp, sizeof(struct timespec)))
 		return -EFAULT;
@@ -822,11 +823,20 @@
 	expire = timespec_to_jiffies(&t) + (t.tv_sec || t.tv_nsec);
 
 	current->state = TASK_INTERRUPTIBLE;
+	get_fast_time(&before);
 	expire = schedule_timeout(expire);
+	get_fast_time(&after);
 
 	if (expire) {
 		if (rmtp) {
-			jiffies_to_timespec(expire, &t);
+			struct timespec elapsed;
+
+			timeval_less(after, before, &after);
+			timeval_to_timespec(after, &elapsed);
+			if (timespec_before(elapsed, t))
+				timespec_less(t, elapsed, &t);
+			else
+				t.tv_nsec = t.tv_sec = 0;
 			if (copy_to_user(rmtp, &t, sizeof(struct timespec)))
 				return -EFAULT;
 		}

  reply	other threads:[~2001-11-29 10:06 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2001-11-29  6:56 [PATCH] Fix for sys_nanosleep() in 2.4.16 Michael Arras
2001-11-29 10:04 ` Christoph Hellwig [this message]
2001-11-29 23:41 ` george anzinger

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=200111291004.fATA4l608978@ns.caldera.de \
    --to=hch@ns.caldera.de \
    --cc=linux-kernel@vger.kernel.org \
    --cc=marcelo@conectiva.com.br \
    --cc=mkarras110@yahoo.com \
    --cc=torvalds@transmeta.com \
    /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