public inbox for ltp@lists.linux.it
 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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox