mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Andrew Morton <akpm@digeo.com>
To: george anzinger <george@mvista.com>
Cc: linux-kernel@vger.kernel.org
Subject: Re: [patch] nanosleep() fix for current bk
Date: Thu, 20 Mar 2003 00:30:26 -0800	[thread overview]
Message-ID: <20030320003026.53add413.akpm@digeo.com> (raw)
In-Reply-To: <3E79754E.8060504@mvista.com>

george anzinger <george@mvista.com> wrote:
>
> Andrew Morton wrote:
> > This should fix up the various mysterious application failures which people
> > have been seeing (xmms, mplayer, DB2 at least).
> > 
> > A couple of things:
> > 
> > -               if (rq_time <= get_jiffies_64())
> > -                       return 0;
> > 
> > That was unsafe against wrapping.
> 
> Uh, I don't think so.  They are both 64 bits.  It that wraps we will 
> both be long gone ...

Well, someome may decide to set INTIAL_JIFFIES to -300HZ.  It is more
correct.

> > Also I think this calculation:
> > 
> > -		if (abs || !rq_time){
> > -			adjust_abs_time(&posix_clocks[which_clock], &t, abs);
> >  
> > -			tstojiffie(&t, posix_clocks[which_clock].res, &rq_time);
> > -		}
> > 
> > should be outside the loop, yes?
> 
> No.  If abs is set we need to redue the conversion just in case the 
> clock was set (and setting the clock will wake us up early).  If abs 
> is not set, we just do the conversion once, after which rq_time will 
> be non-zero and we will use the old expire time.

OK.   Here's an updated patch.

 kernel/posix-timers.c |   44 ++++++++++++++++++++------------------------
 1 files changed, 20 insertions(+), 24 deletions(-)

diff -puN kernel/posix-timers.c~posix-timers-fixes kernel/posix-timers.c
--- 25/kernel/posix-timers.c~posix-timers-fixes	2003-03-19 22:56:25.000000000 -0800
+++ 25-akpm/kernel/posix-timers.c	2003-03-20 00:15:17.000000000 -0800
@@ -182,8 +182,7 @@ init_posix_timers(void)
 
 __initcall(init_posix_timers);
 
-static inline int
-tstojiffie(struct timespec *tp, int res, u64 *jiff)
+static void tstojiffie(struct timespec *tp, int res, u64 *jiff)
 {
 	unsigned long sec = tp->tv_sec;
 	long nsec = tp->tv_nsec + res - 1;
@@ -212,17 +211,14 @@ tstojiffie(struct timespec *tp, int res,
 	 * Split to jiffie and sub jiffie
 	 */
 	*jiff += nsec / (NSEC_PER_SEC / HZ);
-	/*
-	 * We trust that the optimizer will use the remainder from the 
-	 * above div in the following operation as long as they are close. 
-	 */
-	return 0;
 }
+
 static void
 tstotimer(struct itimerspec *time, struct k_itimer *timer)
 {
 	u64 result;
 	int res = posix_clocks[timer->it_clock].res;
+
 	tstojiffie(&time->it_value, res, &result);
 	timer->it_timer.expires = (unsigned long)result;
 	tstojiffie(&time->it_interval, res, &result);
@@ -1195,6 +1191,7 @@ sys_clock_nanosleep(clockid_t which_cloc
 	return ret;
 
 }
+
 long
 do_clock_nanosleep(clockid_t which_clock, int flags, struct timespec *tsave)
 {
@@ -1225,41 +1222,40 @@ do_clock_nanosleep(clockid_t which_clock
 		rq_time = (rq_time << 32) + restart_block->arg2;
 		if (!rq_time)
 			return -EINTR;
-		if (rq_time <= get_jiffies_64())
-			return 0;
+		left = rq_time - get_jiffies_64();
+		if (left <= 0LL)
+			return 0;	/* Already passed */
 	}
 
 	if (abs && (posix_clocks[which_clock].clock_get !=
 		    posix_clocks[CLOCK_MONOTONIC].clock_get)) {
 		add_wait_queue(&nanosleep_abs_wqueue, &abs_wqueue);
 	}
+
 	do {
 		t = *tsave;
-		if (abs || !rq_time){
+		if (abs || !rq_time) {
 			adjust_abs_time(&posix_clocks[which_clock], &t, abs);
-
 			tstojiffie(&t, posix_clocks[which_clock].res, &rq_time);
 		}
-#if (BITS_PER_LONG < 64)
-		if ((rq_time - get_jiffies_64()) > MAX_JIFFY_OFFSET){
-			new_timer.expires = MAX_JIFFY_OFFSET;
-		}else
-#endif
-		{
-			new_timer.expires = (long)rq_time;
-		}
-		current->state = TASK_INTERRUPTIBLE;
+
+		left = rq_time - get_jiffies_64();
+		if (left >= MAX_JIFFY_OFFSET)
+			left = MAX_JIFFY_OFFSET;
+		if (left < 0)
+			break;
+
+		new_timer.expires = jiffies + left;
+		__set_current_state(TASK_INTERRUPTIBLE);
 		add_timer(&new_timer);
 
 		schedule();
 
 		del_timer_sync(&new_timer);
 		left = rq_time - get_jiffies_64();
-	}
-	while ( (left > 0)  &&
-		!test_thread_flag(TIF_SIGPENDING));
+	} while (left > 0 && !test_thread_flag(TIF_SIGPENDING));
 
-	if( abs_wqueue.task_list.next)
+	if (abs_wqueue.task_list.next)
 		finish_wait(&nanosleep_abs_wqueue, &abs_wqueue);
 
 	if (left > 0) {

_


      reply	other threads:[~2003-03-20  8:19 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2003-03-20  6:26 Andrew Morton
2003-03-20  8:01 ` george anzinger
2003-03-20  8:30   ` Andrew Morton [this message]

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=20030320003026.53add413.akpm@digeo.com \
    --to=akpm@digeo.com \
    --cc=george@mvista.com \
    --cc=linux-kernel@vger.kernel.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®