1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * Copyright (c) Crackerjack Project., 2007-2008 ,Hitachi, Ltd 4 * Authors: Takahiro Yasui <takahiro.yasui.mp@hitachi.com>, 5 * Yumiko Sugita <yumiko.sugita.yf@hitachi.com>, 6 * Satoshi Fujiwara <sa-fuji@sdl.hitachi.co.jp> 7 * LTP authors: 8 * Manas Kumar Nayak maknayak@in.ibm.com> 9 * Zeng Linggang <zenglg.jy@cn.fujitsu.com> 10 * Cyril Hrubis <chrubis@suse.cz> 11 */ 12 13#include <errno.h> 14 15#include "tst_timer.h" 16#include "lapi/posix_clocks.h" 17 18static struct test_case { 19 char *name; 20 clockid_t clk_id; 21 int ret; 22 int err; 23} tcase[] = { 24 {"REALTIME", CLOCK_REALTIME, 0, 0}, 25 {"MONOTONIC", CLOCK_MONOTONIC, 0, 0}, 26 {"PROCESS_CPUTIME_ID", CLOCK_PROCESS_CPUTIME_ID, 0, 0}, 27 {"THREAD_CPUTIME_ID", CLOCK_THREAD_CPUTIME_ID, 0, 0}, 28 {"CLOCK_MONOTONIC_RAW", CLOCK_MONOTONIC_RAW, 0, 0,}, 29 {"CLOCK_REALTIME_COARSE", CLOCK_REALTIME_COARSE, 0, 0,}, 30 {"CLOCK_MONOTONIC_COARSE", CLOCK_MONOTONIC_COARSE, 0, 0,}, 31 {"CLOCK_BOOTTIME", CLOCK_BOOTTIME, 0, 0,}, 32 {"CLOCK_REALTIME_ALARM", CLOCK_REALTIME_ALARM, 0, 0,}, 33 {"CLOCK_BOOTTIME_ALARM", CLOCK_BOOTTIME_ALARM, 0, 0,}, 34 {"-1", -1, -1, EINVAL}, 35}; 36 37static struct tst_ts *tspec, *nspec = NULL; 38 39static struct test_variants { 40 int (*func)(clockid_t clk_id, void *ts); 41 enum tst_ts_type type; 42 struct tst_ts **spec; 43 char *desc; 44} variants[] = { 45 { .func = libc_clock_getres, .type = TST_LIBC_TIMESPEC, .spec = &tspec, .desc = "vDSO or syscall with libc spec"}, 46 { .func = libc_clock_getres, .type = TST_LIBC_TIMESPEC, .spec = &nspec, .desc = "vDSO or syscall with libc spec with NULL res"}, 47 48#if (__NR_clock_getres != __LTP__NR_INVALID_SYSCALL) 49 { .func = sys_clock_getres, .type = TST_KERN_OLD_TIMESPEC, .spec = &tspec, .desc = "syscall with old kernel spec"}, 50 { .func = sys_clock_getres, .type = TST_KERN_OLD_TIMESPEC, .spec = &nspec, .desc = "syscall with old kernel spec with NULL res"}, 51#endif 52 53#if (__NR_clock_getres_time64 != __LTP__NR_INVALID_SYSCALL) 54 { .func = sys_clock_getres64, .type = TST_KERN_TIMESPEC, .spec = &tspec, .desc = "syscall time64 with kernel spec"}, 55 { .func = sys_clock_getres64, .type = TST_KERN_TIMESPEC, .spec = &nspec, .desc = "syscall time64 with kernel spec with NULL res"}, 56#endif 57}; 58 59static void setup(void) 60{ 61 tspec->type = variants[tst_variant].type; 62 tst_res(TINFO, "Testing variant: %s", variants[tst_variant].desc); 63} 64 65static void do_test(unsigned int i) 66{ 67 struct test_variants *tv = &variants[tst_variant]; 68 69 TEST(tv->func(tcase[i].clk_id, tst_ts_get(*tv->spec))); 70 71 if (TST_RET != tcase[i].ret) { 72 if (TST_ERR == EINVAL) { 73 tst_res(TCONF, "clock_getres(%s, ...) NO SUPPORTED", tcase[i].name); 74 return; 75 } 76 77 tst_res(TFAIL | TTERRNO, "clock_getres(%s, ...) failed", tcase[i].name); 78 return; 79 } 80 81 if (TST_ERR != tcase[i].err) { 82 tst_res(TFAIL, 83 "clock_getres(%s, ...) failed unexpectedly: %s, expected: %s", 84 tcase[i].name, tst_strerrno(TST_ERR), tst_strerrno(tcase[i].err)); 85 return; 86 } 87 88 tst_res(TPASS, "clock_getres(%s, ...) succeeded", tcase[i].name); 89} 90 91static struct tst_test test = { 92 .test = do_test, 93 .tcnt = ARRAY_SIZE(tcase), 94 .test_variants = ARRAY_SIZE(variants), 95 .setup = setup, 96 .bufs = (struct tst_buffers []) { 97 {&tspec, .size = sizeof(*tspec)}, 98 {}, 99 } 100}; 101