Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 | // 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; } |