unix: in TestClockNanosleep, compare wall times when sleeping until wall times

Previously, we were sleeping until a wall time but then comparing the
duration slept using monotonic time. If the wall time happens to jump
during the sleep, the monotonic time can legitimately be shorter than
the wall time.

Fixes golang/go#42513

Change-Id: Iaef8d9ba46082e821f5cb18c96b9869238d7af05
Reviewed-on: https://go-review.googlesource.com/c/sys/+/363456
Trust: Bryan C. Mills <bcmills@google.com>
Run-TryBot: Bryan C. Mills <bcmills@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Tobias Klauser <tobias.klauser@gmail.com>
diff --git a/unix/syscall_linux_test.go b/unix/syscall_linux_test.go
index 910f579..3a07cfe 100644
--- a/unix/syscall_linux_test.go
+++ b/unix/syscall_linux_test.go
@@ -671,8 +671,22 @@
 			continue
 		} else if err != nil {
 			t.Errorf("ClockNanosleep(CLOCK_REALTIME, TIMER_ABSTIME, %#v (=%v), nil) = %v", &abs, until, err)
-		} else if slept := time.Since(start); slept < delay {
-			t.Errorf("ClockNanosleep(CLOCK_REALTIME, TIMER_ABSTIME, %#v (=%v), nil) slept only %v", &abs, until, slept)
+		} else {
+			// We asked for CLOCK_REALTIME, but we have no way to know whether it
+			// jumped backward after ClockNanosleep returned. Compare both ways,
+			// and only fail if both the monotonic and wall clocks agree that
+			// the elapsed sleep was too short.
+			//
+			// This can still theoretically fail spuriously: if the clock jumps
+			// forward during ClockNanosleep and then backward again before we can
+			// call time.Now, then we could end up with a time that is too short on
+			// both the monotonic scale (because of the forward jump) and the
+			// real-time scale (because of the backward jump. However, it seems
+			// unlikely that two such contrary jumps will ever occur in the time it
+			// takes to execute this test.
+			if now := time.Now(); now.Before(until) && now.Round(0).Before(until) {
+				t.Errorf("ClockNanosleep(CLOCK_REALTIME, TIMER_ABSTIME, %#v (=%v), nil) slept only until %v", &abs, until, now)
+			}
 		}
 		break
 	}