[LTP] [PATCH v4 2/2] Add clock_settime04 test
Andrea Cervesato
andrea.cervesato@suse.com
Fri Aug 1 15:17:39 CEST 2025
On 8/1/25 2:41 PM, Cyril Hrubis wrote:
> Hi!
>>> Here as well, SAFE_CLOCK_GETTIME() uses struct timespec as defined by
>>> libc, so we have to either use syscall that corresponds to the
>>> begin->type (tv->clock_gettime), or covert the value from
>>> SAFE_CLOCK_GETTIME() into the right type. I guess that it would look
>>> like:
>> Why not just going back to the original idea in v1, where we are using
>> the clock_gettime/settime corresponding to the right libc?
> Actually the v4 was quite close to what I had in my mind, the corrected
> code looks like:
>
> // SPDX-License-Identifier: GPL-2.0-or-later
> /*
> * Copyright (c) 2025 Andrea Cervesato <andrea.cervesato@suse.com>
> */
>
> /*\
> * Verify that changing the value of the CLOCK_REALTIME clock via
> * clock_settime() shall have no effect on a thread that is blocked on
> * absolute/relative clock_nanosleep().
> */
>
> #include "tst_test.h"
> #include "tst_timer.h"
> #include "tst_safe_clocks.h"
> #include "time64_variants.h"
>
> #define SEC_TO_US(x) (x * 1000 * 1000)
>
> #define CHILD_SLEEP_US SEC_TO_US(5)
> #define PARENT_SLEEP_S 2
> #define DELTA_US SEC_TO_US(1)
>
> static struct tst_ts *sleep_child;
>
> static struct time64_variants variants[] = {
> {
> .clock_nanosleep = libc_clock_nanosleep,
> .ts_type = TST_LIBC_TIMESPEC,
> .desc = "vDSO or syscall with libc spec"
> },
>
> #if (__NR_clock_nanosleep != __LTP__NR_INVALID_SYSCALL)
> {
> .clock_nanosleep = sys_clock_nanosleep,
> .ts_type = TST_KERN_OLD_TIMESPEC,
> .desc = "syscall with old kernel spec"
> },
> #endif
>
> #if (__NR_clock_nanosleep_time64 != __LTP__NR_INVALID_SYSCALL)
> {
> .clock_nanosleep = sys_clock_nanosleep64,
> .ts_type = TST_KERN_TIMESPEC,
> .desc = "syscall time64 with kernel spec"
> },
> #endif
> };
>
> static void child_nanosleep(struct time64_variants *tv, const int flags)
> {
> long long delta;
> struct timespec begin, end;
>
> SAFE_CLOCK_GETTIME(CLOCK_MONOTONIC, &begin);
>
> if (flags & TIMER_ABSTIME) {
> tst_res(TINFO, "Using absolute time sleep");
>
> tst_ts_set_sec(sleep_child, begin.tv_sec);
> tst_ts_set_nsec(sleep_child, begin.tv_nsec);
>
> *sleep_child = tst_ts_add_us(*sleep_child, CHILD_SLEEP_US);
> } else {
> tst_res(TINFO, "Using relative time sleep");
>
> *sleep_child = tst_ts_from_us(sleep_child->type, CHILD_SLEEP_US);
> }
>
> TEST(tv->clock_nanosleep(CLOCK_REALTIME, flags, tst_ts_get(sleep_child), NULL));
> if (TST_RET)
> tst_brk(TBROK | TERRNO, "clock_nanosleep() error");
>
> SAFE_CLOCK_GETTIME(CLOCK_MONOTONIC, &end);
>
> if (tst_timespec_lt(end, begin)) {
> tst_res(TFAIL, "clock_settime() didn't sleep enough. "
> "begin: %lld ms >= end: %lld ms",
> tst_timespec_to_ms(begin),
> tst_timespec_to_ms(end));
> return;
> }
>
> delta = tst_timespec_abs_diff_us(begin, end);
> if (!(flags & TIMER_ABSTIME))
> delta -= CHILD_SLEEP_US;
>
> if (delta > DELTA_US) {
> tst_res(TFAIL, "parent clock_settime() affected child sleep. "
> "begin: %lld ms, end: %lld ms",
> tst_timespec_to_ms(begin),
> tst_timespec_to_ms(end));
> return;
> }
>
> tst_res(TPASS, "parent clock_settime() didn't affect child sleep "
> "(delta time: %lld us)", delta);
> }
>
> static void run(unsigned int tc_index)
> {
> struct time64_variants *tv = &variants[tst_variant];
> struct timespec begin;
> struct timespec sleep_parent = {
> .tv_sec = PARENT_SLEEP_S,
> };
>
> if (!SAFE_FORK()) {
> child_nanosleep(tv, tc_index ? TIMER_ABSTIME : 0);
> exit(0);
> }
>
> SAFE_CLOCK_GETTIME(CLOCK_REALTIME, &begin);
> SAFE_CLOCK_NANOSLEEP(CLOCK_REALTIME, 0, &sleep_parent, NULL);
> SAFE_CLOCK_SETTIME(CLOCK_REALTIME, &begin);
> }
>
> static void setup(void)
> {
> sleep_child->type = variants[tst_variant].ts_type;
>
> tst_res(TINFO, "Testing variant: %s", variants[tst_variant].desc);
> }
>
> static struct tst_test test = {
> .test = run,
> .setup = setup,
> .tcnt = 2,
> .needs_root = 1,
> .forks_child = 1,
> .restore_wallclock = 1,
> .test_variants = ARRAY_SIZE(variants),
> .bufs = (struct tst_buffers []) {
> {&sleep_child, .size = sizeof(struct tst_ts)},
> {},
> }
> };
Ok feel free to push with Co-developed.
Acked-by: Andrea Cervesato <andrea.cervesato@suse.com>
Thanks,
- Andrea
More information about the ltp
mailing list