// SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note /* * vdso_clock_getres.c: Sample code to test clock_getres. * Copyright (c) 2019 Arm Ltd. * * Compile with: * gcc -std=gnu99 vdso_clock_getres.c * * Tested on ARM, ARM64, MIPS32, x86 (32-bit and 64-bit), * Power (32-bit and 64-bit), S390x (32-bit and 64-bit). * Might work on other architectures. */ #define _GNU_SOURCE #include <elf.h> #include <err.h> #include <fcntl.h> #include <stdint.h> #include <stdio.h> #include <stdlib.h> #include <time.h> #include <sys/auxv.h> #include <sys/mman.h> #include <sys/time.h> #include <unistd.h> #include <sys/syscall.h> #include "../kselftest.h" static long syscall_clock_getres(clockid_t _clkid, struct timespec *_ts) { long ret; ret = syscall(SYS_clock_getres, _clkid, _ts); return ret; } const char *vdso_clock_name[12] = { "CLOCK_REALTIME", "CLOCK_MONOTONIC", "CLOCK_PROCESS_CPUTIME_ID", "CLOCK_THREAD_CPUTIME_ID", "CLOCK_MONOTONIC_RAW", "CLOCK_REALTIME_COARSE", "CLOCK_MONOTONIC_COARSE", "CLOCK_BOOTTIME", "CLOCK_REALTIME_ALARM", "CLOCK_BOOTTIME_ALARM", "CLOCK_SGI_CYCLE", "CLOCK_TAI", }; /* * This function calls clock_getres in vdso and by system call * with different values for clock_id. * * Example of output: * * clock_id: CLOCK_REALTIME [PASS] * clock_id: CLOCK_BOOTTIME [PASS] * clock_id: CLOCK_TAI [PASS] * clock_id: CLOCK_REALTIME_COARSE [PASS] * clock_id: CLOCK_MONOTONIC [PASS] * clock_id: CLOCK_MONOTONIC_RAW [PASS] * clock_id: CLOCK_MONOTONIC_COARSE [PASS] */ static inline int vdso_test_clock(unsigned int clock_id) { struct timespec x, y; printf("clock_id: %s", vdso_clock_name[clock_id]); clock_getres(clock_id, &x); syscall_clock_getres(clock_id, &y); if ((x.tv_sec != y.tv_sec) || (x.tv_nsec != y.tv_nsec)) { printf(" [FAIL]\n"); return KSFT_FAIL; } printf(" [PASS]\n"); return KSFT_PASS; } int main(int argc, char **argv) { int ret = 0; #if _POSIX_TIMERS > 0 #ifdef CLOCK_REALTIME ret += vdso_test_clock(CLOCK_REALTIME); #endif #ifdef CLOCK_BOOTTIME ret += vdso_test_clock(CLOCK_BOOTTIME); #endif #ifdef CLOCK_TAI ret += vdso_test_clock(CLOCK_TAI); #endif #ifdef CLOCK_REALTIME_COARSE ret += vdso_test_clock(CLOCK_REALTIME_COARSE); #endif #ifdef CLOCK_MONOTONIC ret += vdso_test_clock(CLOCK_MONOTONIC); #endif #ifdef CLOCK_MONOTONIC_RAW ret += vdso_test_clock(CLOCK_MONOTONIC_RAW); #endif #ifdef CLOCK_MONOTONIC_COARSE ret += vdso_test_clock(CLOCK_MONOTONIC_COARSE); #endif #endif if (ret > 0) return KSFT_FAIL; return KSFT_PASS; }