All of lore.kernel.org
 help / color / mirror / Atom feed
* [LTP] [PATCH v2] nanosleep: Use CLOCK_MONOTONIC for elapsed time measurement
@ 2026-03-31 12:42 Andrea Cervesato
  2026-03-31 13:48 ` Cyril Hrubis
  0 siblings, 1 reply; 3+ messages in thread
From: Andrea Cervesato @ 2026-03-31 12:42 UTC (permalink / raw)
  To: Linux Test Project; +Cc: Claude

From: Andrea Cervesato <andrea.cervesato@suse.com>

All nanosleep POSIX conformance tests used CLOCK_REALTIME to measure
elapsed sleep duration. CLOCK_REALTIME can jump due to NTP corrections,
VM time sync, or other wall-clock adjustments, causing sporadic test
failures where measured time far exceeds expected sleep duration.

Switch to CLOCK_MONOTONIC which is immune to wall-clock changes and is
the correct clock for measuring elapsed durations. Guard with
_POSIX_MONOTONIC_CLOCK and fall back to CLOCK_REALTIME with a warning
on systems where CLOCK_MONOTONIC is unavailable.

Co-authored-by: Claude <noreply@anthropic.com>
Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
---
Changes in v2:
- introduce TEST_CLOCK to select the right available clock type
- print a message in case CLOCK_MONOTONIC is not available
- Link to v1: https://lore.kernel.org/r/20260331-nanosleep_posix_fix-v1-1-7a707f871582@suse.com
---
 .../conformance/interfaces/nanosleep/1-1.c                 | 14 ++++++++++++--
 .../conformance/interfaces/nanosleep/1-2.c                 | 14 ++++++++++++--
 .../conformance/interfaces/nanosleep/1-3.c                 | 14 ++++++++++++--
 .../conformance/interfaces/nanosleep/10000-1.c             | 14 ++++++++++++--
 .../conformance/interfaces/nanosleep/2-1.c                 | 14 ++++++++++++--
 .../conformance/interfaces/nanosleep/3-2.c                 | 14 ++++++++++++--
 .../conformance/interfaces/nanosleep/7-2.c                 | 14 ++++++++++++--
 7 files changed, 84 insertions(+), 14 deletions(-)

diff --git a/testcases/open_posix_testsuite/conformance/interfaces/nanosleep/1-1.c b/testcases/open_posix_testsuite/conformance/interfaces/nanosleep/1-1.c
index 687d01e288d914fbbdc18287746f71296c7a4327..75b34346f13d9b62e2333dbc78023a812fc9c908 100644
--- a/testcases/open_posix_testsuite/conformance/interfaces/nanosleep/1-1.c
+++ b/testcases/open_posix_testsuite/conformance/interfaces/nanosleep/1-1.c
@@ -12,13 +12,23 @@
 #include <time.h>
 #include "posixtest.h"
 
+#ifdef _POSIX_MONOTONIC_CLOCK
+#define TEST_CLOCK CLOCK_MONOTONIC
+#else
+#define TEST_CLOCK CLOCK_REALTIME
+#endif
+
 int main(void)
 {
 	struct timespec tssleepfor, tsstorage, tsbefore, tsafter;
 	int sleepnsec = 3;
 	int slepts = 0, sleptns = 0;
 
-	if (clock_gettime(CLOCK_REALTIME, &tsbefore) == -1) {
+#ifndef _POSIX_MONOTONIC_CLOCK
+	printf("CLOCK_MONOTONIC unavailable, test may fail due to external clock adjustments\n");
+#endif
+
+	if (clock_gettime(TEST_CLOCK, &tsbefore) == -1) {
 		perror("Error in clock_gettime()\n");
 		return PTS_UNRESOLVED;
 	}
@@ -30,7 +40,7 @@ int main(void)
 		return PTS_UNRESOLVED;
 	}
 
-	if (clock_gettime(CLOCK_REALTIME, &tsafter) == -1) {
+	if (clock_gettime(TEST_CLOCK, &tsafter) == -1) {
 		perror("Error in clock_gettime()\n");
 		return PTS_UNRESOLVED;
 	}
diff --git a/testcases/open_posix_testsuite/conformance/interfaces/nanosleep/1-2.c b/testcases/open_posix_testsuite/conformance/interfaces/nanosleep/1-2.c
index 76f31982508dc87a4f400022cd46fe766071f27d..4a38bd507bba47792b942feb53954b95e92dc222 100644
--- a/testcases/open_posix_testsuite/conformance/interfaces/nanosleep/1-2.c
+++ b/testcases/open_posix_testsuite/conformance/interfaces/nanosleep/1-2.c
@@ -15,13 +15,23 @@
 #include <sys/wait.h>
 #include "posixtest.h"
 
+#ifdef _POSIX_MONOTONIC_CLOCK
+#define TEST_CLOCK CLOCK_MONOTONIC
+#else
+#define TEST_CLOCK CLOCK_REALTIME
+#endif
+
 int main(void)
 {
 	struct timespec tssleepfor, tsstorage, tsbefore, tsafter;
 	int sleepsec = 30;
 	int pid;
 
-	if (clock_gettime(CLOCK_REALTIME, &tsbefore) == -1) {
+#ifndef _POSIX_MONOTONIC_CLOCK
+	printf("CLOCK_MONOTONIC unavailable, test may fail due to external clock adjustments\n");
+#endif
+
+	if (clock_gettime(TEST_CLOCK, &tsbefore) == -1) {
 		perror("Error in clock_gettime()\n");
 		return PTS_UNRESOLVED;
 	}
@@ -46,7 +56,7 @@ int main(void)
 			perror("Error waiting for child to exit\n");
 			return PTS_UNRESOLVED;
 		}
-		if (clock_gettime(CLOCK_REALTIME, &tsafter) == -1) {
+		if (clock_gettime(TEST_CLOCK, &tsafter) == -1) {
 			perror("Error in clock_gettime()\n");
 			return PTS_UNRESOLVED;
 		}
diff --git a/testcases/open_posix_testsuite/conformance/interfaces/nanosleep/1-3.c b/testcases/open_posix_testsuite/conformance/interfaces/nanosleep/1-3.c
index 31ac00858018c3741758d0b5f2bf28f87aa6c1bf..7d5600788d6bc4682f228ccc7c669576827c397a 100644
--- a/testcases/open_posix_testsuite/conformance/interfaces/nanosleep/1-3.c
+++ b/testcases/open_posix_testsuite/conformance/interfaces/nanosleep/1-3.c
@@ -16,6 +16,12 @@
 #include <sys/wait.h>
 #include "posixtest.h"
 
+#ifdef _POSIX_MONOTONIC_CLOCK
+#define TEST_CLOCK CLOCK_MONOTONIC
+#else
+#define TEST_CLOCK CLOCK_REALTIME
+#endif
+
 static void handler(int signo PTS_ATTRIBUTE_UNUSED)
 {
 	printf("In handler\n");
@@ -28,7 +34,11 @@ int main(void)
 	int pid;
 	struct sigaction act;
 
-	if (clock_gettime(CLOCK_REALTIME, &tsbefore) == -1) {
+#ifndef _POSIX_MONOTONIC_CLOCK
+	printf("CLOCK_MONOTONIC unavailable, test may fail due to external clock adjustments\n");
+#endif
+
+	if (clock_gettime(TEST_CLOCK, &tsbefore) == -1) {
 		perror("Error in clock_gettime()\n");
 		return PTS_UNRESOLVED;
 	}
@@ -64,7 +74,7 @@ int main(void)
 			perror("Error waiting for child to exit\n");
 			return PTS_UNRESOLVED;
 		}
-		if (clock_gettime(CLOCK_REALTIME, &tsafter) == -1) {
+		if (clock_gettime(TEST_CLOCK, &tsafter) == -1) {
 			perror("Error in clock_gettime()\n");
 			return PTS_UNRESOLVED;
 		}
diff --git a/testcases/open_posix_testsuite/conformance/interfaces/nanosleep/10000-1.c b/testcases/open_posix_testsuite/conformance/interfaces/nanosleep/10000-1.c
index 883885df434fb4ba3bb555dd565880f14623a984..ebcf366acb52fd149f19951a6e4e0764bd503807 100644
--- a/testcases/open_posix_testsuite/conformance/interfaces/nanosleep/10000-1.c
+++ b/testcases/open_posix_testsuite/conformance/interfaces/nanosleep/10000-1.c
@@ -19,6 +19,12 @@
 #include <errno.h>
 #include "posixtest.h"
 
+#ifdef _POSIX_MONOTONIC_CLOCK
+#define TEST_CLOCK CLOCK_MONOTONIC
+#else
+#define TEST_CLOCK CLOCK_REALTIME
+#endif
+
 #define NUMVALID 6
 #define NUMINVALID 7
 
@@ -51,18 +57,22 @@ int main(void)
 	int failure = 0;
 	int slepts = 0, sleptns = 0;
 
+#ifndef _POSIX_MONOTONIC_CLOCK
+	printf("CLOCK_MONOTONIC unavailable, test may fail due to external clock adjustments\n");
+#endif
+
 	for (i = 0; i < NUMVALID; i++) {
 		tssleepfor.tv_sec = sleepvalid[i][0];
 		tssleepfor.tv_nsec = sleepvalid[i][1];
 		printf("sleep %d sec %d nsec\n",
 		       (int)tssleepfor.tv_sec, (int)tssleepfor.tv_nsec);
-		if (clock_gettime(CLOCK_REALTIME, &tsbefore) == -1) {
+		if (clock_gettime(TEST_CLOCK, &tsbefore) == -1) {
 			perror("Error in clock_gettime()\n");
 			return PTS_UNRESOLVED;
 		}
 
 		if (nanosleep(&tssleepfor, &tsstorage) == 0) {
-			if (clock_gettime(CLOCK_REALTIME, &tsafter) == -1) {
+			if (clock_gettime(TEST_CLOCK, &tsafter) == -1) {
 				perror("Error in clock_gettime()\n");
 				return PTS_UNRESOLVED;
 			}
diff --git a/testcases/open_posix_testsuite/conformance/interfaces/nanosleep/2-1.c b/testcases/open_posix_testsuite/conformance/interfaces/nanosleep/2-1.c
index cce3941e7be7212ea286647ec601d3ecbb9bb85a..8586e0ecec023029b60bce8ad5e1e72206daee34 100644
--- a/testcases/open_posix_testsuite/conformance/interfaces/nanosleep/2-1.c
+++ b/testcases/open_posix_testsuite/conformance/interfaces/nanosleep/2-1.c
@@ -13,6 +13,12 @@
 #include <time.h>
 #include "posixtest.h"
 
+#ifdef _POSIX_MONOTONIC_CLOCK
+#define TEST_CLOCK CLOCK_MONOTONIC
+#else
+#define TEST_CLOCK CLOCK_REALTIME
+#endif
+
 #define NUMINTERVALS 13
 int main(void)
 {
@@ -25,7 +31,11 @@ int main(void)
 	int failure = 0;
 	int slepts, sleptns;
 
-	if (clock_gettime(CLOCK_REALTIME, &tsbefore) == -1) {
+#ifndef _POSIX_MONOTONIC_CLOCK
+	printf("CLOCK_MONOTONIC unavailable, test may fail due to external clock adjustments\n");
+#endif
+
+	if (clock_gettime(TEST_CLOCK, &tsbefore) == -1) {
 		perror("Error in clock_gettime()\n");
 		return PTS_UNRESOLVED;
 	}
@@ -38,7 +48,7 @@ int main(void)
 			return PTS_UNRESOLVED;
 		}
 
-		if (clock_gettime(CLOCK_REALTIME, &tsafter) == -1) {
+		if (clock_gettime(TEST_CLOCK, &tsafter) == -1) {
 			perror("Error in clock_gettime()\n");
 			return PTS_UNRESOLVED;
 		}
diff --git a/testcases/open_posix_testsuite/conformance/interfaces/nanosleep/3-2.c b/testcases/open_posix_testsuite/conformance/interfaces/nanosleep/3-2.c
index bfc271edf25f9cd0f343eef11b335d5da20eb646..1329a7e988055ed3815e4e4037f331f576264d1a 100644
--- a/testcases/open_posix_testsuite/conformance/interfaces/nanosleep/3-2.c
+++ b/testcases/open_posix_testsuite/conformance/interfaces/nanosleep/3-2.c
@@ -16,6 +16,12 @@
 #include <stdlib.h>
 #include "posixtest.h"
 
+#ifdef _POSIX_MONOTONIC_CLOCK
+#define TEST_CLOCK CLOCK_MONOTONIC
+#else
+#define TEST_CLOCK CLOCK_REALTIME
+#endif
+
 #define SLEEPSEC 5
 
 #define CHILDPASS 0		//if interrupted, child will return 0
@@ -26,7 +32,11 @@ int main(void)
 	int pid, slepts;
 	struct timespec tsbefore, tsafter;
 
-	if (clock_gettime(CLOCK_REALTIME, &tsbefore) != 0) {
+#ifndef _POSIX_MONOTONIC_CLOCK
+	printf("CLOCK_MONOTONIC unavailable, test may fail due to external clock adjustments\n");
+#endif
+
+	if (clock_gettime(TEST_CLOCK, &tsbefore) != 0) {
 		perror("clock_gettime() did not return success\n");
 		return PTS_UNRESOLVED;
 	}
@@ -74,7 +84,7 @@ int main(void)
 			return PTS_FAIL;
 		}
 
-		if (clock_gettime(CLOCK_REALTIME, &tsafter) == -1) {
+		if (clock_gettime(TEST_CLOCK, &tsafter) == -1) {
 			perror("Error in clock_gettime()\n");
 			return PTS_UNRESOLVED;
 		}
diff --git a/testcases/open_posix_testsuite/conformance/interfaces/nanosleep/7-2.c b/testcases/open_posix_testsuite/conformance/interfaces/nanosleep/7-2.c
index caf4470e4a26b27ec79deed27c147e2feceffdf8..70eeca9ff8eb10ac052b81f102853747a5066685 100644
--- a/testcases/open_posix_testsuite/conformance/interfaces/nanosleep/7-2.c
+++ b/testcases/open_posix_testsuite/conformance/interfaces/nanosleep/7-2.c
@@ -17,6 +17,12 @@
 #include <stdlib.h>
 #include "posixtest.h"
 
+#ifdef _POSIX_MONOTONIC_CLOCK
+#define TEST_CLOCK CLOCK_MONOTONIC
+#else
+#define TEST_CLOCK CLOCK_REALTIME
+#endif
+
 #define CHILDSUCCESS 1
 #define CHILDFAILURE 0
 
@@ -34,7 +40,11 @@ int main(void)
 	int pid;
 	struct sigaction act;
 
-	if (clock_gettime(CLOCK_REALTIME, &tsbefore) == -1) {
+#ifndef _POSIX_MONOTONIC_CLOCK
+	printf("CLOCK_MONOTONIC unavailable, test may fail due to external clock adjustments\n");
+#endif
+
+	if (clock_gettime(TEST_CLOCK, &tsbefore) == -1) {
 		perror("Error in clock_gettime()\n");
 		return PTS_UNRESOLVED;
 	}
@@ -60,7 +70,7 @@ int main(void)
 			return CHILDFAILURE;
 		}
 
-		if (clock_gettime(CLOCK_REALTIME, &tsafter) == -1) {
+		if (clock_gettime(TEST_CLOCK, &tsafter) == -1) {
 			perror("Error in clock_gettime()\n");
 			return CHILDFAILURE;
 		}

---
base-commit: 4688c20c01eece869b59e05ca3dd68c43e0d6af7
change-id: 20260331-nanosleep_posix_fix-66162acca1ed

Best regards,
-- 
Andrea Cervesato <andrea.cervesato@suse.com>


-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

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

* Re: [LTP] [PATCH v2] nanosleep: Use CLOCK_MONOTONIC for elapsed time measurement
  2026-03-31 12:42 [LTP] [PATCH v2] nanosleep: Use CLOCK_MONOTONIC for elapsed time measurement Andrea Cervesato
@ 2026-03-31 13:48 ` Cyril Hrubis
  2026-03-31 14:40   ` Andrea Cervesato via ltp
  0 siblings, 1 reply; 3+ messages in thread
From: Cyril Hrubis @ 2026-03-31 13:48 UTC (permalink / raw)
  To: Andrea Cervesato; +Cc: Claude, Linux Test Project

Hi!
Reviewed-by: Cyril Hrubis <chrubis@suse.cz>

-- 
Cyril Hrubis
chrubis@suse.cz

-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

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

* Re: [LTP] [PATCH v2] nanosleep: Use CLOCK_MONOTONIC for elapsed time measurement
  2026-03-31 13:48 ` Cyril Hrubis
@ 2026-03-31 14:40   ` Andrea Cervesato via ltp
  0 siblings, 0 replies; 3+ messages in thread
From: Andrea Cervesato via ltp @ 2026-03-31 14:40 UTC (permalink / raw)
  To: Cyril Hrubis; +Cc: Claude, Linux Test Project

Merged, thanks.

--
Andrea Cervesato
SUSE QE Automation Engineer Linux
andrea.cervesato@suse.com

-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

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

end of thread, other threads:[~2026-03-31 14:40 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-31 12:42 [LTP] [PATCH v2] nanosleep: Use CLOCK_MONOTONIC for elapsed time measurement Andrea Cervesato
2026-03-31 13:48 ` Cyril Hrubis
2026-03-31 14:40   ` Andrea Cervesato via ltp

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.