You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
- Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
/* Mostly written (for sleep.c) by Paul Eggert.
Factored out (creating this file) by Jim Meyering. */
#include <sys/types.h>
#include <time.h>
-#include "timespec.h"
-#include "gethrxtime.h"
-#include "xtime.h"
-
-/* The extra casts work around common compiler bugs. */
-#define TYPE_SIGNED(t) (! ((t) 0 < (t) -1))
-/* The outer cast is needed to work around a bug in Cray C 5.0.3.0.
- It is necessary at least when t == time_t. */
-#define TYPE_MINIMUM(t) ((t) (TYPE_SIGNED (t) \
- ? ~ (t) 0 << (sizeof (t) * CHAR_BIT - 1) : (t) 0))
-#define TYPE_MAXIMUM(t) ((t) (~ (t) 0 - TYPE_MINIMUM (t)))
+#include "intprops.h"
#ifndef TIME_T_MAX
# define TIME_T_MAX TYPE_MAXIMUM (time_t)
#endif
-/* POSIX.1-2001 requires that when a process is suspended, then
- resumed, nanosleep (A, B) returns -1, sets errno to EINTR, and sets
- *B to the time remaining at the point of resumption. However, some
- versions of the Linux kernel incorrectly return the time remaining
- at the point of suspension. Work around this bug on GNU/Linux
- hosts by computing the remaining time here after nanosleep returns,
- rather than by relying on nanosleep's computation. */
-#ifdef __linux__
-enum { NANOSLEEP_BUG_WORKAROUND = true };
-#else
-enum { NANOSLEEP_BUG_WORKAROUND = false };
-#endif
-
/* Sleep until the time (call it WAKE_UP_TIME) specified as
SECONDS seconds after the time this function is called.
SECONDS must be non-negative. If SECONDS is so large that
bool overflow = false;
double ns;
struct timespec ts_sleep;
- xtime_t stop = 0;
assert (0 <= seconds);
- if (NANOSLEEP_BUG_WORKAROUND)
- {
- xtime_t now = gethrxtime ();
- double increment = XTIME_PRECISION * seconds;
- xtime_t incr = increment;
- stop = now + incr + (incr < increment);
- overflow = (stop < now);
- }
-
/* Separate whole seconds from nanoseconds.
Be careful to detect any overflow. */
ts_sleep.tv_sec = seconds;
ts_sleep.tv_nsec = BILLION - 1;
}
+ /* Linux-2.6.8.1's nanosleep returns -1, but doesn't set errno
+ when resumed after being suspended. Earlier versions would
+ set errno to EINTR. nanosleep from linux-2.6.10, as well as
+ implementations by (all?) other vendors, doesn't return -1
+ in that case; either it continues sleeping (if time remains)
+ or it returns zero (if the wake-up time has passed). */
+ errno = 0;
if (nanosleep (&ts_sleep, NULL) == 0)
break;
- if (errno != EINTR)
+ if (errno != EINTR && errno != 0)
return -1;
-
- if (NANOSLEEP_BUG_WORKAROUND)
- {
- xtime_t now = gethrxtime ();
- if (stop <= now)
- break;
- else
- {
- xtime_t remaining = stop - now;
- ts_sleep.tv_sec = xtime_nonnegative_sec (remaining);
- ts_sleep.tv_nsec = xtime_nonnegative_nsec (remaining);
- }
- }
}
return 0;