From: "Pádraig Brady" <P@draigBrady.com>
To: Thomas Gleixner <tglx@linutronix.de>,
Linux Kernel Mailing List <linux-kernel@vger.kernel.org>
Cc: Paul Eggert <eggert@cs.ucla.edu>, bug-gnulib <bug-gnulib@gnu.org>
Subject: nanosleep truncated on 64 bit Linux by 292 billion years
Date: Mon, 27 Oct 2014 04:01:44 +0000 [thread overview]
Message-ID: <544DC3A8.1060103@draigBrady.com> (raw)
In-Reply-To: <alpine.DEB.2.10.1408060017090.3323@nanos>
[-- Attachment #1: Type: text/plain, Size: 867 bytes --]
I noticed that nanosleep() on 64 bit, "only" supports 292 years,
rather than the full potential 292 billion years with 64 bit time_t, due to:
https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/include/linux/time.h?id=refs/tags/v3.16#n87
Attached is a program from Paul Eggert that illustrates the bug.
Running this program on a buggy host outputs something like this:
Setting alarm for 1 second from now ...
Sleeping for 9223372036854775807.999999999 seconds...
After alarm sent off, remaining time is 9223357678.462306617 seconds;
i.e., nanosleep claimed that it slept for about 293079448610.606445 years.
Gnulib-using applications have a workaround for this bug, but a workaround
shouldn't be necessary. For what it's worth, the bug is fixed in Solaris 11 (x86-64),
though it's present in Solaris 10 (64-bit sparc).
thanks,
Pádraig.
[-- Attachment #2: nanosleep-bug.c --]
[-- Type: text/plain, Size: 1175 bytes --]
#include <time.h>
#include <errno.h>
#include <limits.h>
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
static void
check_for_SIGALRM (int sig)
{
if (sig != SIGALRM)
_exit (1);
}
int
main (void)
{
static struct sigaction act;
struct timespec forever, remaining;
time_t time_t_max = (1ull << (sizeof time_t_max * CHAR_BIT - 1)) - 1;
act.sa_handler = check_for_SIGALRM;
sigemptyset (&act.sa_mask);
sigaction (SIGALRM, &act, NULL);
forever.tv_sec = time_t_max;
forever.tv_nsec = 999999999;
printf ("Setting alarm for 1 second from now ...\n");
alarm (1);
printf ("Sleeping for %lld.%09ld seconds...\n",
(long long) forever.tv_sec, forever.tv_nsec);
if (nanosleep (&forever, &remaining) == 0)
return 2;
if (errno != EINTR)
return 3;
if (remaining.tv_sec < time_t_max - 10)
{
printf ("After alarm sent off, remaining time is %lld.%09ld seconds;\n",
(long long) remaining.tv_sec, remaining.tv_nsec);
printf ("i.e., nanosleep claimed that it slept for about %f years.\n",
(forever.tv_sec - remaining.tv_sec) / (24 * 60 * 60 * 364.2425));
return 4;
}
printf ("ok\n");
return 0;
}
next parent reply other threads:[~2014-10-27 4:11 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <53E0FF15.4090808@draigBrady.com>
[not found] ` <53E13F04.70609@cs.ucla.edu>
[not found] ` <alpine.DEB.2.10.1408060017090.3323@nanos>
2014-10-27 4:01 ` Pádraig Brady [this message]
2014-10-28 15:45 ` Thomas Gleixner
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=544DC3A8.1060103@draigBrady.com \
--to=p@draigbrady.com \
--cc=bug-gnulib@gnu.org \
--cc=eggert@cs.ucla.edu \
--cc=linux-kernel@vger.kernel.org \
--cc=tglx@linutronix.de \
/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
Powered by JetHome