public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Paulo Marques <pmarques@grupopie.com>
To: Olivier Croquette <ocroquette@free.fr>
Cc: LKML <linux-kernel@vger.kernel.org>
Subject: Re: setitimer timer expires too early
Date: Fri, 29 Apr 2005 20:06:52 +0100	[thread overview]
Message-ID: <427285CC.9090300@grupopie.com> (raw)
In-Reply-To: <42726DDD.1010204@free.fr>

[-- Attachment #1: Type: text/plain, Size: 1746 bytes --]

Olivier Croquette wrote:
> Hello
> 
> I wrote a program which uses setitimer to implement a usleep() equivalent.
> [...]
> Anyone have an idea?
> Can you reproduce that?

I can reproduce that.

It seems that the code responsible for this is in kernel/itimer.c:126:

	p->signal->real_timer.expires = jiffies + interval;
	add_timer(&p->signal->real_timer);

If you request an interval of, lets say 900 usecs, the interval given by 
timeval_to_jiffies will be 1.

If you request this when we are half-way between two timer ticks, the 
interval will only give 400 usecs.

If we want to guarantee that we never ever give intervals less than 
requested, the simple solution would be to change that to:

	p->signal->real_timer.expires = jiffies + interval + 1;

This however will produce pathological cases, like having a idle system 
being requested 1 ms timeouts will give systematically 2 ms timeouts, 
whereas currently it simply gives a few usecs less than 1 ms.

The complex (and more computationally expensive) solution would be to 
check the gettimeofday time, and compute the correct number of jiffies. 
This way, if we request a 300 usecs timer 200 usecs inside the timer 
tick, we can wait just one tick, but not if we are 800 usecs inside the 
tick. This would also mean that we would have to lock preemption during 
these computations to avoid races, etc.

I've searched the archives but couldn't find this particular issue being 
discussed before.

Attached is a patch to do the simple solution, in case anybody thinks 
that it should be used.

Signed-Off-By: Paulo Marques <pmarques@grupopie.com>

-- 
Paulo Marques - www.grupopie.com

All that is necessary for the triumph of evil is that good men do nothing.
Edmund Burke (1729 - 1797)

[-- Attachment #2: itimer_patch --]
[-- Type: text/plain, Size: 632 bytes --]

--- ./kernel/itimer.c.orig	2005-04-29 19:59:12.937832959 +0100
+++ ./kernel/itimer.c	2005-04-29 20:01:49.849787304 +0100
@@ -123,7 +123,11 @@ static inline void it_real_arm(struct ta
 		return;
 	if (interval > (unsigned long) LONG_MAX)
 		interval = LONG_MAX;
-	p->signal->real_timer.expires = jiffies + interval;
+	/* the "+ 1" below makes sure that the timer doesn't go off before
+	 * the interval requested. This could happen if 
+	 * time requested % (usecs per jiffy) is more than the usecs left
+	 * in the current jiffy */
+	p->signal->real_timer.expires = jiffies + interval + 1;
 	add_timer(&p->signal->real_timer);
 }
 

  reply	other threads:[~2005-04-29 19:08 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2005-04-29 17:24 setitimer timer expires too early Olivier Croquette
2005-04-29 19:06 ` Paulo Marques [this message]
2005-04-29 21:25   ` Nish Aravamudan
2005-04-30 15:32     ` Olivier Croquette
2005-05-02  6:07       ` Nish Aravamudan

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=427285CC.9090300@grupopie.com \
    --to=pmarques@grupopie.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=ocroquette@free.fr \
    /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