public inbox for ltp@lists.linux.it
 help / color / mirror / Atom feed
* [LTP] [PATCH v2] nanosleep: use POSIX runtime detection for CLOCK_MONOTONIC
@ 2026-04-16 12:33 Andrea Cervesato
  2026-04-16 13:45 ` [LTP] " linuxtestproject.agent
  2026-04-17 12:58 ` [LTP] [PATCH v2] " Petr Vorel
  0 siblings, 2 replies; 3+ messages in thread
From: Andrea Cervesato @ 2026-04-16 12:33 UTC (permalink / raw)
  To: Linux Test Project

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

All nanosleep POSIX conformance tests used a compile-time #ifdef on
_POSIX_MONOTONIC_CLOCK to select the clock for measuring elapsed
sleep duration. This was incorrect for two reasons:

1. Three test files (1-1.c, 2-1.c, 10000-1.c) did not include
   <unistd.h>, so the macro was never defined and the tests silently
   fell back to CLOCK_REALTIME.

2. On Linux/glibc, _POSIX_MONOTONIC_CLOCK is defined as 0, meaning
   support is optional and must be verified at runtime via
   sysconf(_SC_MONOTONIC_CLOCK). The #ifdef treated 0 the same as
   >0 (always available), which is not POSIX-correct.

Using CLOCK_REALTIME caused sporadic test failures when NTP or VM
time sync adjusted the wall clock during sleep, producing results
like "slept 32s >> 10s".

Extract the clock selection logic into a shared helpers.h with a
get_supported_clock() function that performs proper POSIX runtime
detection via sysconf(), and use it across all affected tests.

Fixes: f992f6e25fce ("nanosleep: Use CLOCK_MONOTONIC for elapsed time measurement")
Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
---
Some nanosleep tests are not recognizing CLOCK_MONOTONIC at runtime
even if it's available:

CLOCK_MONOTONIC unavailable, test may fail due to external clock adjustments
sleep 0 sec 30000000 nsec
PASS - slept 0s30078623ns ~= 0s30000000ns
sleep 1 sec 0 nsec
PASS - slept 1s97618ns ~= 1s0ns
sleep 1 sec 30000000 nsec
PASS - slept 1s30109248ns ~= 1s30000000ns
sleep 2 sec 0 nsec
PASS - slept 2s147180ns ~= 2s0ns
sleep 10 sec 5000 nsec
FAIL - slept 32s630120452ns >> 10s5000ns
sleep 13 sec 5 nsec
PASS - slept 13s146848ns ~= 13s5ns
sleep -1 sec -1 nsec
sleep 0 sec -1 nsec
sleep 1 sec 1000000000 nsec
sleep 2 sec 1000000000 nsec
sleep -2147483647 sec -2147483647 nsec
sleep 1 sec 2147483647 nsec
sleep 0 sec 1075002478 nsec
At least one test FAILED
---
Changes in v2:
- add <unistd.h> to imports
- Link to v1: https://lore.kernel.org/r/20260416-fix_nanosleep_include-v1-1-f584b5556141@suse.com
---
 .../conformance/interfaces/nanosleep/1-1.c         | 16 ++++---------
 .../conformance/interfaces/nanosleep/1-2.c         | 16 ++++---------
 .../conformance/interfaces/nanosleep/1-3.c         | 16 ++++---------
 .../conformance/interfaces/nanosleep/10000-1.c     | 16 ++++---------
 .../conformance/interfaces/nanosleep/2-1.c         | 16 ++++---------
 .../conformance/interfaces/nanosleep/3-2.c         | 16 ++++---------
 .../conformance/interfaces/nanosleep/7-2.c         | 16 ++++---------
 .../conformance/interfaces/nanosleep/helpers.h     | 28 ++++++++++++++++++++++
 8 files changed, 56 insertions(+), 84 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 75b34346f13d9b62e2333dbc78023a812fc9c908..803569b138a1f17c0dede0c03406d3c7e52c4215 100644
--- a/testcases/open_posix_testsuite/conformance/interfaces/nanosleep/1-1.c
+++ b/testcases/open_posix_testsuite/conformance/interfaces/nanosleep/1-1.c
@@ -11,24 +11,16 @@
 #include <stdio.h>
 #include <time.h>
 #include "posixtest.h"
-
-#ifdef _POSIX_MONOTONIC_CLOCK
-#define TEST_CLOCK CLOCK_MONOTONIC
-#else
-#define TEST_CLOCK CLOCK_REALTIME
-#endif
+#include "helpers.h"
 
 int main(void)
 {
 	struct timespec tssleepfor, tsstorage, tsbefore, tsafter;
 	int sleepnsec = 3;
 	int slepts = 0, sleptns = 0;
+	clockid_t test_clock = get_supported_clock();
 
-#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) {
+	if (clock_gettime(test_clock, &tsbefore) == -1) {
 		perror("Error in clock_gettime()\n");
 		return PTS_UNRESOLVED;
 	}
@@ -40,7 +32,7 @@ int main(void)
 		return PTS_UNRESOLVED;
 	}
 
-	if (clock_gettime(TEST_CLOCK, &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 4a38bd507bba47792b942feb53954b95e92dc222..116510ea26ab6b7792c9aba5aa18eb7b926e59df 100644
--- a/testcases/open_posix_testsuite/conformance/interfaces/nanosleep/1-2.c
+++ b/testcases/open_posix_testsuite/conformance/interfaces/nanosleep/1-2.c
@@ -14,24 +14,16 @@
 #include <unistd.h>
 #include <sys/wait.h>
 #include "posixtest.h"
-
-#ifdef _POSIX_MONOTONIC_CLOCK
-#define TEST_CLOCK CLOCK_MONOTONIC
-#else
-#define TEST_CLOCK CLOCK_REALTIME
-#endif
+#include "helpers.h"
 
 int main(void)
 {
 	struct timespec tssleepfor, tsstorage, tsbefore, tsafter;
 	int sleepsec = 30;
 	int pid;
+	clockid_t test_clock = get_supported_clock();
 
-#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) {
+	if (clock_gettime(test_clock, &tsbefore) == -1) {
 		perror("Error in clock_gettime()\n");
 		return PTS_UNRESOLVED;
 	}
@@ -56,7 +48,7 @@ int main(void)
 			perror("Error waiting for child to exit\n");
 			return PTS_UNRESOLVED;
 		}
-		if (clock_gettime(TEST_CLOCK, &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 7d5600788d6bc4682f228ccc7c669576827c397a..6baed5c89aa5ccb149f0a47da05b17c4880c06d4 100644
--- a/testcases/open_posix_testsuite/conformance/interfaces/nanosleep/1-3.c
+++ b/testcases/open_posix_testsuite/conformance/interfaces/nanosleep/1-3.c
@@ -15,12 +15,7 @@
 #include <unistd.h>
 #include <sys/wait.h>
 #include "posixtest.h"
-
-#ifdef _POSIX_MONOTONIC_CLOCK
-#define TEST_CLOCK CLOCK_MONOTONIC
-#else
-#define TEST_CLOCK CLOCK_REALTIME
-#endif
+#include "helpers.h"
 
 static void handler(int signo PTS_ATTRIBUTE_UNUSED)
 {
@@ -33,12 +28,9 @@ int main(void)
 	int sleepsec = 30;
 	int pid;
 	struct sigaction act;
+	clockid_t test_clock = get_supported_clock();
 
-#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) {
+	if (clock_gettime(test_clock, &tsbefore) == -1) {
 		perror("Error in clock_gettime()\n");
 		return PTS_UNRESOLVED;
 	}
@@ -74,7 +66,7 @@ int main(void)
 			perror("Error waiting for child to exit\n");
 			return PTS_UNRESOLVED;
 		}
-		if (clock_gettime(TEST_CLOCK, &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 ebcf366acb52fd149f19951a6e4e0764bd503807..c9d1cc303c629d7bbcf0fb4451103ef1729e4609 100644
--- a/testcases/open_posix_testsuite/conformance/interfaces/nanosleep/10000-1.c
+++ b/testcases/open_posix_testsuite/conformance/interfaces/nanosleep/10000-1.c
@@ -18,12 +18,7 @@
 #include <time.h>
 #include <errno.h>
 #include "posixtest.h"
-
-#ifdef _POSIX_MONOTONIC_CLOCK
-#define TEST_CLOCK CLOCK_MONOTONIC
-#else
-#define TEST_CLOCK CLOCK_REALTIME
-#endif
+#include "helpers.h"
 
 #define NUMVALID 6
 #define NUMINVALID 7
@@ -56,23 +51,20 @@ int main(void)
 	int i;
 	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
+	clockid_t test_clock = get_supported_clock();
 
 	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(TEST_CLOCK, &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(TEST_CLOCK, &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 8586e0ecec023029b60bce8ad5e1e72206daee34..02b122a786ef4e735d4e74f1a96e5263cd7333b1 100644
--- a/testcases/open_posix_testsuite/conformance/interfaces/nanosleep/2-1.c
+++ b/testcases/open_posix_testsuite/conformance/interfaces/nanosleep/2-1.c
@@ -12,12 +12,7 @@
 #include <stdio.h>
 #include <time.h>
 #include "posixtest.h"
-
-#ifdef _POSIX_MONOTONIC_CLOCK
-#define TEST_CLOCK CLOCK_MONOTONIC
-#else
-#define TEST_CLOCK CLOCK_REALTIME
-#endif
+#include "helpers.h"
 
 #define NUMINTERVALS 13
 int main(void)
@@ -30,12 +25,9 @@ int main(void)
 	int i;
 	int failure = 0;
 	int slepts, sleptns;
+	clockid_t test_clock = get_supported_clock();
 
-#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) {
+	if (clock_gettime(test_clock, &tsbefore) == -1) {
 		perror("Error in clock_gettime()\n");
 		return PTS_UNRESOLVED;
 	}
@@ -48,7 +40,7 @@ int main(void)
 			return PTS_UNRESOLVED;
 		}
 
-		if (clock_gettime(TEST_CLOCK, &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 1329a7e988055ed3815e4e4037f331f576264d1a..2110e0ddad36877150ba4aacaaf28a079207539a 100644
--- a/testcases/open_posix_testsuite/conformance/interfaces/nanosleep/3-2.c
+++ b/testcases/open_posix_testsuite/conformance/interfaces/nanosleep/3-2.c
@@ -15,12 +15,7 @@
 #include <sys/wait.h>
 #include <stdlib.h>
 #include "posixtest.h"
-
-#ifdef _POSIX_MONOTONIC_CLOCK
-#define TEST_CLOCK CLOCK_MONOTONIC
-#else
-#define TEST_CLOCK CLOCK_REALTIME
-#endif
+#include "helpers.h"
 
 #define SLEEPSEC 5
 
@@ -31,12 +26,9 @@ int main(void)
 {
 	int pid, slepts;
 	struct timespec tsbefore, tsafter;
+	clockid_t test_clock = get_supported_clock();
 
-#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) {
+	if (clock_gettime(test_clock, &tsbefore) != 0) {
 		perror("clock_gettime() did not return success\n");
 		return PTS_UNRESOLVED;
 	}
@@ -84,7 +76,7 @@ int main(void)
 			return PTS_FAIL;
 		}
 
-		if (clock_gettime(TEST_CLOCK, &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 70eeca9ff8eb10ac052b81f102853747a5066685..16e44e142473188cdfab70e4d1d334e0bed71d1c 100644
--- a/testcases/open_posix_testsuite/conformance/interfaces/nanosleep/7-2.c
+++ b/testcases/open_posix_testsuite/conformance/interfaces/nanosleep/7-2.c
@@ -16,12 +16,7 @@
 #include <sys/wait.h>
 #include <stdlib.h>
 #include "posixtest.h"
-
-#ifdef _POSIX_MONOTONIC_CLOCK
-#define TEST_CLOCK CLOCK_MONOTONIC
-#else
-#define TEST_CLOCK CLOCK_REALTIME
-#endif
+#include "helpers.h"
 
 #define CHILDSUCCESS 1
 #define CHILDFAILURE 0
@@ -39,12 +34,9 @@ int main(void)
 	int sleepsec = 30;
 	int pid;
 	struct sigaction act;
+	clockid_t test_clock = get_supported_clock();
 
-#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) {
+	if (clock_gettime(test_clock, &tsbefore) == -1) {
 		perror("Error in clock_gettime()\n");
 		return PTS_UNRESOLVED;
 	}
@@ -70,7 +62,7 @@ int main(void)
 			return CHILDFAILURE;
 		}
 
-		if (clock_gettime(TEST_CLOCK, &tsafter) == -1) {
+		if (clock_gettime(test_clock, &tsafter) == -1) {
 			perror("Error in clock_gettime()\n");
 			return CHILDFAILURE;
 		}
diff --git a/testcases/open_posix_testsuite/conformance/interfaces/nanosleep/helpers.h b/testcases/open_posix_testsuite/conformance/interfaces/nanosleep/helpers.h
new file mode 100644
index 0000000000000000000000000000000000000000..a70e4c290c76c61adc55e9b006b65597dde4677d
--- /dev/null
+++ b/testcases/open_posix_testsuite/conformance/interfaces/nanosleep/helpers.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2026, Linux Test Project
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef NANOSLEEP_HELPERS_H
+#define NANOSLEEP_HELPERS_H
+
+#include <stdio.h>
+#include <unistd.h>
+#include <time.h>
+
+static inline clockid_t get_supported_clock(void)
+{
+#ifdef _POSIX_MONOTONIC_CLOCK
+	if (_POSIX_MONOTONIC_CLOCK > 0)
+		return CLOCK_MONOTONIC;
+
+	if (!_POSIX_MONOTONIC_CLOCK && sysconf(_SC_MONOTONIC_CLOCK) > 0)
+		return CLOCK_MONOTONIC;
+#endif
+
+	printf("CLOCK_MONOTONIC unavailable, test may fail due to "
+	       "external clock adjustments\n");
+	return CLOCK_REALTIME;
+}
+
+#endif /* NANOSLEEP_HELPERS_H */

---
base-commit: 620d596c79493af089ba6a1c4dc79efcc76a67c7
change-id: 20260416-fix_nanosleep_include-edcc8f01f0e0

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] nanosleep: use POSIX runtime detection for CLOCK_MONOTONIC
  2026-04-16 12:33 [LTP] [PATCH v2] nanosleep: use POSIX runtime detection for CLOCK_MONOTONIC Andrea Cervesato
@ 2026-04-16 13:45 ` linuxtestproject.agent
  2026-04-17 12:58 ` [LTP] [PATCH v2] " Petr Vorel
  1 sibling, 0 replies; 3+ messages in thread
From: linuxtestproject.agent @ 2026-04-16 13:45 UTC (permalink / raw)
  To: Andrea Cervesato; +Cc: ltp, LTP AI Reviewer

Hi Andrea,

On 2026-04-16, Andrea Cervesato wrote:
> nanosleep: use POSIX runtime detection for CLOCK_MONOTONIC

> +static inline clockid_t get_supported_clock(void)
> +{
> +#ifdef _POSIX_MONOTONIC_CLOCK
> +	if (_POSIX_MONOTONIC_CLOCK > 0)
> +		return CLOCK_MONOTONIC;
> +
> +	if (!_POSIX_MONOTONIC_CLOCK && sysconf(_SC_MONOTONIC_CLOCK) > 0)
> +		return CLOCK_MONOTONIC;
> +#endif
> +
> +	printf("CLOCK_MONOTONIC unavailable, test may fail due to "
> +	       "external clock adjustments\n");
> +	return CLOCK_REALTIME;
> +}

Correct POSIX runtime detection — handles all three _POSIX_MONOTONIC_CLOCK
states (>0, ==0, undefined) properly, and the unistd.h include in helpers.h
closes the silent fallback that affected 1-1.c, 2-1.c, and 10000-1.c.

Reviewed-by: LTP AI Reviewer <ltp-ai@noreply.github.com>

---
Note:

Our agent completed the review of the patch.

The agent can sometimes produce false positives although often its
findings are genuine. If you find issues with the review, please
comment this email or ignore the suggestions.

Regards,
LTP AI Reviewer

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

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

* Re: [LTP] [PATCH v2] nanosleep: use POSIX runtime detection for CLOCK_MONOTONIC
  2026-04-16 12:33 [LTP] [PATCH v2] nanosleep: use POSIX runtime detection for CLOCK_MONOTONIC Andrea Cervesato
  2026-04-16 13:45 ` [LTP] " linuxtestproject.agent
@ 2026-04-17 12:58 ` Petr Vorel
  1 sibling, 0 replies; 3+ messages in thread
From: Petr Vorel @ 2026-04-17 12:58 UTC (permalink / raw)
  To: Andrea Cervesato; +Cc: Linux Test Project

Hi Andrea,

...
> --- /dev/null
> +++ b/testcases/open_posix_testsuite/conformance/interfaces/nanosleep/helpers.h
> @@ -0,0 +1,28 @@
> +/*
> + * Copyright (c) 2026, Linux Test Project
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + */
> +
> +#ifndef NANOSLEEP_HELPERS_H
> +#define NANOSLEEP_HELPERS_H
> +
> +#include <stdio.h>
> +#include <unistd.h>
> +#include <time.h>
> +
> +static inline clockid_t get_supported_clock(void)
> +{
> +#ifdef _POSIX_MONOTONIC_CLOCK
> +	if (_POSIX_MONOTONIC_CLOCK > 0)
> +		return CLOCK_MONOTONIC;
> +
> +	if (!_POSIX_MONOTONIC_CLOCK && sysconf(_SC_MONOTONIC_CLOCK) > 0)
> +		return CLOCK_MONOTONIC;
> +#endif
> +
> +	printf("CLOCK_MONOTONIC unavailable, test may fail due to "
> +	       "external clock adjustments\n");
+1 for warning. But please don't split string just due few chars over 100.

> +	return CLOCK_REALTIME;
I've suggested [1] in clock_settime [2] to move this function to newly created
testcases/open_posix_testsuite/include/clock.h, so that clock_settime/helpers.h
can also use it.

Kind regards,
Petr

[1] https://lore.kernel.org/ltp/20260417125322.GA419619@pevik/
[2] https://patchwork.ozlabs.org/project/ltp/patch/20260416-fix_clock_settime_helper-v1-1-2874202291bf@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-04-17 12:58 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-16 12:33 [LTP] [PATCH v2] nanosleep: use POSIX runtime detection for CLOCK_MONOTONIC Andrea Cervesato
2026-04-16 13:45 ` [LTP] " linuxtestproject.agent
2026-04-17 12:58 ` [LTP] [PATCH v2] " Petr Vorel

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox