[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[bug-gnulib] detecting nonconforming nanosleep
From: |
Jim Meyering |
Subject: |
[bug-gnulib] detecting nonconforming nanosleep |
Date: |
Mon, 28 Feb 2005 11:29:17 +0100 |
Here's code to detect whether xnanosleep.c needs its work-around.
I'm going to put this code in an autoconf run-test so that programs
like sleep et al can avoid linking with -lrt when possible.
The idea is to fork, run nanosleep 1s in the child, have the parent
send SIGTSTP, then SIGCONT to the child and to have the child report
back how nanosleep responded via its _exit status. The parent has to
sleep a little to avoid a race condition.
If anyone sees a way to improve it, please let me know.
Jim
This program would be run only on systems with the nanosleep
function and with a definition of SIGCONT.
Also, it'd have to link with gl_FUNC_NANOSLEEP's $LIB_NANOSLEEP
to get Solaris's -lrt.
---------------------------
/* Detect how nanosleep works when it is resumed after being suspended. */
/* Copyright (C) 2005 Free Software Foundation, Inc.
This file is free software; the Free Software Foundation
gives unlimited permission to copy and/or distribute it,
with or without modifications, as long as this notice is preserved.
Written by Jim Meyering. */
#include "config.h"
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>
#include <stdlib.h>
#include <errno.h>
#if HAVE_SYS_WAIT_H
# include <sys/wait.h>
#endif
#ifndef WEXITSTATUS
# define WEXITSTATUS(s) (((s) >> 8) & 0xff)
#endif
#if TIME_WITH_SYS_TIME
# include <sys/time.h>
# include <time.h>
#else
# if HAVE_SYS_TIME_H
# include <sys/time.h>
# else
# include <time.h>
# endif
#endif
#if ! HAVE_STRUCT_TIMESPEC
/* Some systems don't define this struct, e.g., AIX 4.1, Ultrix 4.3. */
struct timespec
{
time_t tv_sec;
long tv_nsec;
};
#endif
/* Exit nonzero means we set NANOSLEEP_SUSPEND_BUG, which makes
xnanosleep work around the bug -- ultimately, that may mean linking
with libraries like librt to use the gethrxtime module. */
/* Determine whether suspend/resume makes nanosleep fail (return nonzero)
with EINTR. Most implementations do the right thing and continue
sleeping (assuming the wake-up time is still in the future), but with
Linux kernels predating 2.6.10, nanosleep returns -1, sets errno to
EINTR, but indicates a time remaining that doesn't account for the
time elapsed between the suspend and resume signals.
Also, linux-2.6.8.1's nanosleep fails but neglects to set errno.
As far as I know, the implementations that return -1 in this situation
are also the ones with the bug that xnanosleep works around. */
int
main ()
{
pid_t pid = fork ();
if (pid < 0)
abort ();
if (pid == 0)
{
static const struct timespec child_sleep = { 1, 0 };
errno = 0;
if (nanosleep (&child_sleep, NULL) == 0)
_exit (0);
_exit (errno == EINTR || errno == 0 ? 1 : 2);
}
else
{
int status;
static const struct timespec delay = { 0, 300000000 };
if (nanosleep (&delay, NULL) != 0
|| kill (pid, SIGTSTP) != 0
|| kill (pid, SIGCONT) != 0
|| wait (&status) != pid)
abort ();
exit (WEXITSTATUS (status));
}
}
- [bug-gnulib] detecting nonconforming nanosleep,
Jim Meyering <=