1f08c3bdfSopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 2f08c3bdfSopenharmony_ci/* 3f08c3bdfSopenharmony_ci * Copyright (c) 2019 Linaro Limited. All rights reserved. 4f08c3bdfSopenharmony_ci * Author: Rafael David Tinoco <rafael.tinoco@linaro.org> 5f08c3bdfSopenharmony_ci */ 6f08c3bdfSopenharmony_ci/* 7f08c3bdfSopenharmony_ci * Basic test for clock_gettime(2) on multiple clocks: 8f08c3bdfSopenharmony_ci * 9f08c3bdfSopenharmony_ci * 1) CLOCK_REALTIME 10f08c3bdfSopenharmony_ci * 2) CLOCK_MONOTONIC 11f08c3bdfSopenharmony_ci * 3) CLOCK_PROCESS_CPUTIME_ID 12f08c3bdfSopenharmony_ci * 4) CLOCK_THREAD_CPUTIME_ID 13f08c3bdfSopenharmony_ci * 5) CLOCK_REALTIME_COARSE 14f08c3bdfSopenharmony_ci * 6) CLOCK_MONOTONIC_COARSE 15f08c3bdfSopenharmony_ci * 7) CLOCK_MONOTONIC_RAW 16f08c3bdfSopenharmony_ci * 8) CLOCK_BOOTTIME 17f08c3bdfSopenharmony_ci */ 18f08c3bdfSopenharmony_ci 19f08c3bdfSopenharmony_ci#include "config.h" 20f08c3bdfSopenharmony_ci#include "time64_variants.h" 21f08c3bdfSopenharmony_ci#include "tst_timer.h" 22f08c3bdfSopenharmony_ci#include "tst_safe_clocks.h" 23f08c3bdfSopenharmony_ci 24f08c3bdfSopenharmony_cistruct test_case { 25f08c3bdfSopenharmony_ci clockid_t clktype; 26f08c3bdfSopenharmony_ci int allow_inval; 27f08c3bdfSopenharmony_ci}; 28f08c3bdfSopenharmony_ci 29f08c3bdfSopenharmony_cistatic struct test_case tc[] = { 30f08c3bdfSopenharmony_ci { 31f08c3bdfSopenharmony_ci .clktype = CLOCK_REALTIME, 32f08c3bdfSopenharmony_ci }, 33f08c3bdfSopenharmony_ci { 34f08c3bdfSopenharmony_ci .clktype = CLOCK_MONOTONIC, 35f08c3bdfSopenharmony_ci }, 36f08c3bdfSopenharmony_ci { 37f08c3bdfSopenharmony_ci .clktype = CLOCK_PROCESS_CPUTIME_ID, 38f08c3bdfSopenharmony_ci }, 39f08c3bdfSopenharmony_ci { 40f08c3bdfSopenharmony_ci .clktype = CLOCK_THREAD_CPUTIME_ID, 41f08c3bdfSopenharmony_ci }, 42f08c3bdfSopenharmony_ci { 43f08c3bdfSopenharmony_ci .clktype = CLOCK_REALTIME_COARSE, 44f08c3bdfSopenharmony_ci .allow_inval = 1, 45f08c3bdfSopenharmony_ci }, 46f08c3bdfSopenharmony_ci { 47f08c3bdfSopenharmony_ci .clktype = CLOCK_MONOTONIC_COARSE, 48f08c3bdfSopenharmony_ci .allow_inval = 1, 49f08c3bdfSopenharmony_ci }, 50f08c3bdfSopenharmony_ci { 51f08c3bdfSopenharmony_ci .clktype = CLOCK_MONOTONIC_RAW, 52f08c3bdfSopenharmony_ci .allow_inval = 1, 53f08c3bdfSopenharmony_ci }, 54f08c3bdfSopenharmony_ci { 55f08c3bdfSopenharmony_ci .clktype = CLOCK_BOOTTIME, 56f08c3bdfSopenharmony_ci .allow_inval = 1, 57f08c3bdfSopenharmony_ci }, 58f08c3bdfSopenharmony_ci}; 59f08c3bdfSopenharmony_ci 60f08c3bdfSopenharmony_cistatic struct tst_ts spec; 61f08c3bdfSopenharmony_ci 62f08c3bdfSopenharmony_cistatic struct time64_variants variants[] = { 63f08c3bdfSopenharmony_ci { .clock_gettime = libc_clock_gettime, .ts_type = TST_LIBC_TIMESPEC, .desc = "vDSO or syscall with libc spec"}, 64f08c3bdfSopenharmony_ci 65f08c3bdfSopenharmony_ci#if (__NR_clock_gettime != __LTP__NR_INVALID_SYSCALL) 66f08c3bdfSopenharmony_ci { .clock_gettime = sys_clock_gettime, .ts_type = TST_KERN_OLD_TIMESPEC, .desc = "syscall with old kernel spec"}, 67f08c3bdfSopenharmony_ci#endif 68f08c3bdfSopenharmony_ci 69f08c3bdfSopenharmony_ci#if (__NR_clock_gettime64 != __LTP__NR_INVALID_SYSCALL) 70f08c3bdfSopenharmony_ci { .clock_gettime = sys_clock_gettime64, .ts_type = TST_KERN_TIMESPEC, .desc = "syscall time64 with kernel spec"}, 71f08c3bdfSopenharmony_ci#endif 72f08c3bdfSopenharmony_ci}; 73f08c3bdfSopenharmony_ci 74f08c3bdfSopenharmony_cistatic void setup(void) 75f08c3bdfSopenharmony_ci{ 76f08c3bdfSopenharmony_ci long unsigned utime; 77f08c3bdfSopenharmony_ci 78f08c3bdfSopenharmony_ci tst_res(TINFO, "Testing variant: %s", variants[tst_variant].desc); 79f08c3bdfSopenharmony_ci 80f08c3bdfSopenharmony_ci do { 81f08c3bdfSopenharmony_ci SAFE_FILE_SCANF("/proc/self/stat", 82f08c3bdfSopenharmony_ci "%*d %*s %*c %*d %*d %*d %*d %*d %*u %*u %*u %*u %*u %lu", 83f08c3bdfSopenharmony_ci &utime); 84f08c3bdfSopenharmony_ci } while (utime == 0); 85f08c3bdfSopenharmony_ci} 86f08c3bdfSopenharmony_ci 87f08c3bdfSopenharmony_cistatic void verify_clock_gettime(unsigned int i) 88f08c3bdfSopenharmony_ci{ 89f08c3bdfSopenharmony_ci struct time64_variants *tv = &variants[tst_variant]; 90f08c3bdfSopenharmony_ci int ret; 91f08c3bdfSopenharmony_ci 92f08c3bdfSopenharmony_ci memset(&spec, 0, sizeof(spec)); 93f08c3bdfSopenharmony_ci spec.type = tv->ts_type; 94f08c3bdfSopenharmony_ci 95f08c3bdfSopenharmony_ci TEST(tv->clock_gettime(tc[i].clktype, tst_ts_get(&spec))); 96f08c3bdfSopenharmony_ci 97f08c3bdfSopenharmony_ci if (TST_RET == -1) { 98f08c3bdfSopenharmony_ci /* errors: allow unsupported clock types */ 99f08c3bdfSopenharmony_ci if (tc[i].allow_inval && TST_ERR == EINVAL) { 100f08c3bdfSopenharmony_ci tst_res(TPASS, "clock_gettime(2): unsupported clock %s failed as expected", 101f08c3bdfSopenharmony_ci tst_clock_name(tc[i].clktype)); 102f08c3bdfSopenharmony_ci } else { 103f08c3bdfSopenharmony_ci tst_res(TFAIL | TTERRNO, "clock_gettime(2): clock %s failed unexpectedly", 104f08c3bdfSopenharmony_ci tst_clock_name(tc[i].clktype)); 105f08c3bdfSopenharmony_ci } 106f08c3bdfSopenharmony_ci 107f08c3bdfSopenharmony_ci } else { 108f08c3bdfSopenharmony_ci /* success: also check if timespec was changed */ 109f08c3bdfSopenharmony_ci ret = tst_ts_valid(&spec); 110f08c3bdfSopenharmony_ci if (!ret) { 111f08c3bdfSopenharmony_ci tst_res(TPASS, "clock_gettime(2): clock %s passed", 112f08c3bdfSopenharmony_ci tst_clock_name(tc[i].clktype)); 113f08c3bdfSopenharmony_ci } else if (ret == -1) { 114f08c3bdfSopenharmony_ci tst_res(TFAIL, "clock_gettime(2): clock %s passed, unchanged timespec", 115f08c3bdfSopenharmony_ci tst_clock_name(tc[i].clktype)); 116f08c3bdfSopenharmony_ci } else if (ret == -2) { 117f08c3bdfSopenharmony_ci tst_res(TFAIL, "clock_gettime(2): clock %s passed, Corrupted timespec", 118f08c3bdfSopenharmony_ci tst_clock_name(tc[i].clktype)); 119f08c3bdfSopenharmony_ci } 120f08c3bdfSopenharmony_ci } 121f08c3bdfSopenharmony_ci} 122f08c3bdfSopenharmony_ci 123f08c3bdfSopenharmony_cistatic struct tst_test test = { 124f08c3bdfSopenharmony_ci .test = verify_clock_gettime, 125f08c3bdfSopenharmony_ci .tcnt = ARRAY_SIZE(tc), 126f08c3bdfSopenharmony_ci .test_variants = ARRAY_SIZE(variants), 127f08c3bdfSopenharmony_ci .setup = setup, 128f08c3bdfSopenharmony_ci .needs_root = 1, 129f08c3bdfSopenharmony_ci}; 130