Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
0002 /*
0003  * vdso_clock_getres.c: Sample code to test clock_getres.
0004  * Copyright (c) 2019 Arm Ltd.
0005  *
0006  * Compile with:
0007  * gcc -std=gnu99 vdso_clock_getres.c
0008  *
0009  * Tested on ARM, ARM64, MIPS32, x86 (32-bit and 64-bit),
0010  * Power (32-bit and 64-bit), S390x (32-bit and 64-bit).
0011  * Might work on other architectures.
0012  */
0013 
0014 #define _GNU_SOURCE
0015 #include <elf.h>
0016 #include <err.h>
0017 #include <fcntl.h>
0018 #include <stdint.h>
0019 #include <stdio.h>
0020 #include <stdlib.h>
0021 #include <time.h>
0022 #include <sys/auxv.h>
0023 #include <sys/mman.h>
0024 #include <sys/time.h>
0025 #include <unistd.h>
0026 #include <sys/syscall.h>
0027 
0028 #include "../kselftest.h"
0029 
0030 static long syscall_clock_getres(clockid_t _clkid, struct timespec *_ts)
0031 {
0032     long ret;
0033 
0034     ret = syscall(SYS_clock_getres, _clkid, _ts);
0035 
0036     return ret;
0037 }
0038 
0039 const char *vdso_clock_name[12] = {
0040     "CLOCK_REALTIME",
0041     "CLOCK_MONOTONIC",
0042     "CLOCK_PROCESS_CPUTIME_ID",
0043     "CLOCK_THREAD_CPUTIME_ID",
0044     "CLOCK_MONOTONIC_RAW",
0045     "CLOCK_REALTIME_COARSE",
0046     "CLOCK_MONOTONIC_COARSE",
0047     "CLOCK_BOOTTIME",
0048     "CLOCK_REALTIME_ALARM",
0049     "CLOCK_BOOTTIME_ALARM",
0050     "CLOCK_SGI_CYCLE",
0051     "CLOCK_TAI",
0052 };
0053 
0054 /*
0055  * This function calls clock_getres in vdso and by system call
0056  * with different values for clock_id.
0057  *
0058  * Example of output:
0059  *
0060  * clock_id: CLOCK_REALTIME [PASS]
0061  * clock_id: CLOCK_BOOTTIME [PASS]
0062  * clock_id: CLOCK_TAI [PASS]
0063  * clock_id: CLOCK_REALTIME_COARSE [PASS]
0064  * clock_id: CLOCK_MONOTONIC [PASS]
0065  * clock_id: CLOCK_MONOTONIC_RAW [PASS]
0066  * clock_id: CLOCK_MONOTONIC_COARSE [PASS]
0067  */
0068 static inline int vdso_test_clock(unsigned int clock_id)
0069 {
0070     struct timespec x, y;
0071 
0072     printf("clock_id: %s", vdso_clock_name[clock_id]);
0073     clock_getres(clock_id, &x);
0074     syscall_clock_getres(clock_id, &y);
0075 
0076     if ((x.tv_sec != y.tv_sec) || (x.tv_nsec != y.tv_nsec)) {
0077         printf(" [FAIL]\n");
0078         return KSFT_FAIL;
0079     }
0080 
0081     printf(" [PASS]\n");
0082     return KSFT_PASS;
0083 }
0084 
0085 int main(int argc, char **argv)
0086 {
0087     int ret;
0088 
0089 #if _POSIX_TIMERS > 0
0090 
0091 #ifdef CLOCK_REALTIME
0092     ret = vdso_test_clock(CLOCK_REALTIME);
0093 #endif
0094 
0095 #ifdef CLOCK_BOOTTIME
0096     ret += vdso_test_clock(CLOCK_BOOTTIME);
0097 #endif
0098 
0099 #ifdef CLOCK_TAI
0100     ret += vdso_test_clock(CLOCK_TAI);
0101 #endif
0102 
0103 #ifdef CLOCK_REALTIME_COARSE
0104     ret += vdso_test_clock(CLOCK_REALTIME_COARSE);
0105 #endif
0106 
0107 #ifdef CLOCK_MONOTONIC
0108     ret += vdso_test_clock(CLOCK_MONOTONIC);
0109 #endif
0110 
0111 #ifdef CLOCK_MONOTONIC_RAW
0112     ret += vdso_test_clock(CLOCK_MONOTONIC_RAW);
0113 #endif
0114 
0115 #ifdef CLOCK_MONOTONIC_COARSE
0116     ret += vdso_test_clock(CLOCK_MONOTONIC_COARSE);
0117 #endif
0118 
0119 #endif
0120     if (ret > 0)
0121         return KSFT_FAIL;
0122 
0123     return KSFT_PASS;
0124 }