linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] Fix for sys_nanosleep() in 2.4.16
@ 2001-11-29  6:56 Michael Arras
  2001-11-29 10:04 ` Christoph Hellwig
  2001-11-29 23:41 ` george anzinger
  0 siblings, 2 replies; 3+ messages in thread
From: Michael Arras @ 2001-11-29  6:56 UTC (permalink / raw)
  To: linux-kernel

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.

Mike Arras
mkarras110@yahoo.com

diff -urN linux-2.4.16/kernel/timer.c linux/kernel/timer.c
--- linux-2.4.16/kernel/timer.c Mon Oct  8 13:41:41 2001
+++ linux/kernel/timer.c        Wed Nov 28 00:23:15 2001
@@ -825,7 +825,7 @@
                return 0;
        }
 
-       expire = timespec_to_jiffies(&t) + (t.tv_sec || t.tv_nsec);
+       expire = timespec_to_jiffies(&t);
 
        current->state = TASK_INTERRUPTIBLE;
        expire = schedule_timeout(expire);

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] Fix for sys_nanosleep() in 2.4.16
  2001-11-29  6:56 [PATCH] Fix for sys_nanosleep() in 2.4.16 Michael Arras
@ 2001-11-29 10:04 ` Christoph Hellwig
  2001-11-29 23:41 ` george anzinger
  1 sibling, 0 replies; 3+ messages in thread
From: Christoph Hellwig @ 2001-11-29 10:04 UTC (permalink / raw)
  To: Michael Arras; +Cc: linux-kernel, torvalds, marcelo

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;
 		}

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] Fix for sys_nanosleep() in 2.4.16
  2001-11-29  6:56 [PATCH] Fix for sys_nanosleep() in 2.4.16 Michael Arras
  2001-11-29 10:04 ` Christoph Hellwig
@ 2001-11-29 23:41 ` george anzinger
  1 sibling, 0 replies; 3+ messages in thread
From: george anzinger @ 2001-11-29 23:41 UTC (permalink / raw)
  To: Michael Arras; +Cc: linux-kernel

Michael Arras 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.
>
Not really.  It depends on where the call is made with respect to the
next jiffies interrupt.  The standard says that the call MUST not return
early, thus, on the chance that the current time is not exactly on a
jiffies edge, the one must be added.  The average sleep should be 1/HZ+
1/(2*HZ) or 15ms, but never less than 10ms.  For higher resolution stay
tuned to the high-res-timers project (see signature line).


-- 
George           george@mvista.com
High-res-timers: http://sourceforge.net/projects/high-res-timers/
Real time sched: http://sourceforge.net/projects/rtsched/

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2001-11-29 23:42 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2001-11-29  6:56 [PATCH] Fix for sys_nanosleep() in 2.4.16 Michael Arras
2001-11-29 10:04 ` Christoph Hellwig
2001-11-29 23:41 ` george anzinger

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).