public inbox for cygwin-patches@cygwin.com
 help / color / mirror / Atom feed
* Fix nanosleep returning negative rem
@ 2021-07-20 15:16 David Allsopp
  2021-07-21  8:39 ` Corinna Vinschen
  0 siblings, 1 reply; 8+ messages in thread
From: David Allsopp @ 2021-07-20 15:16 UTC (permalink / raw)
  To: cygwin-patches

[-- Attachment #1: Type: text/plain, Size: 1021 bytes --]

I've pushed a repro case for this to
https://github.com/dra27/cygwin-nanosleep-bug.git

Originally noticed as the main CI system for OCaml has been failing
sporadically for the signal.ml test mentioned in that repo. This morning I
tried hammering that test on my dev machine and discovered that it fails
very frequently. No idea if that's drivers, Windows 10 updates, number of
cores or what, but it was definitely happening, and easily.

Drilling further, it appears that NtQueryTimer is able to return a negative
value in the TimeRemaining field even when SignalState is false. The values
I've seen have always been < 15ms - i.e. less than the timer resolution, so
I wonder if there is a point at which the timer has elapsed but has not been
signalled, but WaitForMultipleObjects returns because of the EINTR signal.
Mildly surprising that it seems to be so reproducible.

Anyway, a patch is attached which simply guards a negative return value. The
test on tbi.SignalState is in theory unnecessary.

All best,


David

[-- Attachment #2: 0001-Ensure-nanosleep-2-never-returns-negative-rem.patch --]
[-- Type: application/octet-stream, Size: 1911 bytes --]

From 24f5adc3ac8246d93582ac6e4b2779b369f8b3f1 Mon Sep 17 00:00:00 2001
From: David Allsopp <david.allsopp@metastack.com>
Date: Tue, 20 Jul 2021 16:07:00 +0100
Subject: [PATCH] Ensure nanosleep(2) never returns negative rem

It appears to be the case that NtQueryTimer can return a negative time
remaining for an unsignalled timer. The value appears to be less than
the timer resolution.

Signed-off-by: David Allsopp <david.allsopp@metastack.com>
---
 winsup/cygwin/cygwait.cc    | 6 ++++--
 winsup/cygwin/release/3.2.1 | 4 ++++
 2 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/winsup/cygwin/cygwait.cc b/winsup/cygwin/cygwait.cc
index 1d6c7c9cc..dbbe1db6e 100644
--- a/winsup/cygwin/cygwait.cc
+++ b/winsup/cygwin/cygwait.cc
@@ -104,8 +104,10 @@ cygwait (HANDLE object, PLARGE_INTEGER timeout, unsigned mask)
 		    sizeof tbi, NULL);
       /* if timer expired, TimeRemaining is negative and represents the
 	  system uptime when signalled */
-      if (timeout->QuadPart < 0LL)
-	timeout->QuadPart = tbi.SignalState ? 0LL : tbi.TimeRemaining.QuadPart;
+      if (timeout->QuadPart < 0LL) {
+	timeout->QuadPart = tbi.SignalState || tbi.TimeRemaining.QuadPart < 0LL
+                            ? 0LL : tbi.TimeRemaining.QuadPart;
+      }
       NtCancelTimer (_my_tls.locals.cw_timer, NULL);
     }
 
diff --git a/winsup/cygwin/release/3.2.1 b/winsup/cygwin/release/3.2.1
index 4f4db622a..2a339718c 100644
--- a/winsup/cygwin/release/3.2.1
+++ b/winsup/cygwin/release/3.2.1
@@ -44,3 +44,7 @@ Bug Fixes
   AF_UNSPEC.  As specified by POSIX and Linux, this is allowed on
   datagram sockets, and its effect is to reset the socket's peer
   address.
+
+- Fix nanosleep(2) returning negative rem. NtQueryTimer appears to be able to
+  return a negative remaining time (less than the timer resolution) for
+  unsignalled timers.
-- 
2.29.2.windows.2


^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2021-07-22  8:01 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-07-20 15:16 Fix nanosleep returning negative rem David Allsopp
2021-07-21  8:39 ` Corinna Vinschen
2021-07-21  9:07   ` David Allsopp
2021-07-21  9:30     ` Corinna Vinschen
2021-07-21  9:33       ` Corinna Vinschen
2021-07-21 16:02         ` David Allsopp
2021-07-21 17:57           ` Lavrentiev, Anton (NIH/NLM/NCBI) [C]
2021-07-22  8:01           ` Corinna Vinschen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).