public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: george anzinger <george@mvista.com>
To: Amos Waterland <apw@us.ibm.com>
Cc: Andrew Morton <akpm@osdl.org>, john stultz <johnstul@us.ibm.com>,
	linux-kernel@vger.kernel.org
Subject: Re: Fw: Re: 2.5 kernel regression in alarm() syscall behaviour?
Date: Mon, 14 Jul 2003 19:21:51 -0700	[thread overview]
Message-ID: <3F13653F.2020804@mvista.com> (raw)
In-Reply-To: <20030715015303.GA4845@kvasir.austin.ibm.com>

Amos Waterland wrote:
> On Mon, Jul 14, 2003 at 05:16:06PM -0700, george anzinger wrote:
> 
>>I suppose we are going to have a lot of these.  The test calls alarm
>>which sets up an itimer for the specified number of seconds and
>>returns the number of seconds remaining on the old itimer.  If any
>>useconds remain, seconds is boosted by 1.  The test expects the number
>>returned to be the same as what was sent, i.e. 1 second wait is
>>expected to return 1 second if it is immeadiatly queried.
>>
>>The problem with this test is that it assumes that seconds can be
>>translated into jiffies with out any error.  Jiffies, however, is now
>>defined to be close but not equal to 1/HZ.  In fact, on the x86
>>jiffies is 999848 nano seconds.  The conversion of a second with the
>>proper round up gives 1001 jiffies and converting this back to seconds
>>gives 1.000847848 seconds.  It is this 0.000847848 that is forcing the
>>subject test to report a number higher than expected.
>>
>>IMHO it is the test that is wrong, not the kernel.
> 
> 
> Thanks for your explanation.
> 
> The language of the SuSv3[1] seems a little vague:
> 
>   If there is a previous alarm() request with time remaining, alarm()
>   shall return a non-zero value that is the number of seconds until the
>   previous request would have generated a SIGALRM signal.
> 
> It leaves open to interpretation the question of what the return value
> should be if the delta between calling alarm(1) and alarm(n) is near 0s,
> about .5s, and near 1s.  I think the issue can be boiled down to an
> implementation choice of floor(delta), round(delta), ceil(delta).
> 
> Linux 2.4, Solaris, OpenBSD take the floor() approach.  Running
> alarm2.c[2] on them gives results similar to the following; where
> 'delta' is the difference in microseconds between calling alarm(1) and
> alarm(2), and 'ret' is the return value of the alarm(2) call:
> 
> t1      t2      delta   ret
> ------  ------  ------  ------
> 940284  947913  7629    1
> 948336  57230   108894  1
> 57697   266358  208661  1
> 266826  576979  310153  1
> 577455  986953  409498  1
> 987447  497109  509662  1
> 497576  106690  609114  1
> 107173  817304  710131  1
> 817767  626956  809189  1
> Alarm clock
> 
> That is, even when 809ms have passed between calling alarm(1) and
> alarm(2), Linux 2.4/Solaris/OpenBSD report that there is 1s "until the
> previous request would have generated a SIGALRM signal."
> 
> Since 2.5 is incrementing tv_sec if any tv_usec remain, it is much
> closer to taking a ceil() approach: 1.000847848 gets converted to 2,
> rather than 1.
> 
> I guess the question boils down to: does Linux 2.6 want to make a
> different implementation choice than 2.4 and other Unix variants?

It is the glibc "alarm()" code that is doing this, not the kernel.

AND, gosh, I was hoping the standard would give some guidance here, 
but it completely ignores the issue.

-g
> 
> ----
> 
> [1] http://www.opengroup.org/onlinepubs/007904975/functions/alarm.html
> 
> [2]
> 
> #include <unistd.h>
> #include <stdio.h>
> #include <sys/time.h>
> 
> /* Returns the difference in usecs between now and before.
>  */
> long delta_t(struct timeval now, struct timeval before)
> {
>     if (now.tv_sec == before.tv_sec && now.tv_usec >= before.tv_usec) {
>         return now.tv_usec - before.tv_usec;
>     } else if (now.tv_sec > before.tv_sec) {
>         return (now.tv_usec + 1000000) - before.tv_usec;
>     }
> 
>     return -1;
> }
> 
> int main(int argc, char **argv)
> {
>     int i, ret, fails = 0;
>     struct timeval t1, t2;
> 
>     printf("t1\tt2\tdelta\tret\n------\t------\t------\t------\n");
> 
>     for (i = 0; ; i += 100000) {
>         gettimeofday(&t1, NULL);
> 
>         alarm(1);
>         usleep(i);
>         ret = alarm(2);
> 
>         gettimeofday(&t2, NULL);
> 
>         printf("%li\t%li\t%li\t%i\n", t1.tv_usec,
>                t2.tv_usec, delta_t(t2, t1), ret);
>     }
> 
>     return fails;
> }
> 
> 

-- 
George Anzinger   george@mvista.com
High-res-timers:  http://sourceforge.net/projects/high-res-timers/
Preemption patch: http://www.kernel.org/pub/linux/kernel/people/rml


      reply	other threads:[~2003-07-17 23:57 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <20030714101656.73cdb75f.akpm@osdl.org>
2003-07-15  0:16 ` Fw: Re: 2.5 kernel regression in alarm() syscall behaviour? george anzinger
2003-07-15  1:53   ` Amos Waterland
2003-07-15  2:21     ` george anzinger [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=3F13653F.2020804@mvista.com \
    --to=george@mvista.com \
    --cc=akpm@osdl.org \
    --cc=apw@us.ibm.com \
    --cc=johnstul@us.ibm.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