[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.


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>

# include <sys/wait.h>
# define WEXITSTATUS(s) (((s) >> 8) & 0xff)

# include <sys/time.h>
# include <time.h>
#  include <sys/time.h>
# else
#  include <time.h>
# endif

/* Some systems don't define this struct, e.g., AIX 4.1, Ultrix 4.3.  */
struct timespec
  time_t tv_sec;
  long tv_nsec;

/* 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-'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.  */
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);
      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));

reply via email to

[Prev in Thread] Current Thread [Next in Thread]