1 // SPDX-License-Identifier: GPL-2.0
14 #include "../kselftest.h"
16 #define MSEC_PER_SEC 1000L
17 #define NSEC_PER_MSEC 1000000L
19 void usage(char *name
) {
20 printf ("Usage: %s cpunum\n", name
);
23 int main(int argc
, char **argv
) {
24 unsigned int i
, cpu
, fd
;
25 char msr_file_name
[64];
26 long long tsc
, old_tsc
, new_tsc
;
27 long long aperf
, old_aperf
, new_aperf
;
28 long long mperf
, old_mperf
, new_mperf
;
29 struct timespec before
, after
;
30 long long int start
, finish
, total
;
39 cpu
= strtol(argv
[1], (char **) NULL
, 10);
46 sprintf(msr_file_name
, "/dev/cpu/%d/msr", cpu
);
47 fd
= open(msr_file_name
, O_RDONLY
);
50 printf("/dev/cpu/%d/msr: %s\n", cpu
, strerror(errno
));
55 CPU_SET(cpu
, &cpuset
);
57 if (sched_setaffinity(0, sizeof(cpu_set_t
), &cpuset
)) {
58 perror("Failed to set cpu affinity");
62 if (clock_gettime(CLOCK_MONOTONIC
, &before
) < 0) {
63 perror("clock_gettime");
66 pread(fd
, &old_tsc
, sizeof(old_tsc
), 0x10);
67 pread(fd
, &old_aperf
, sizeof(old_mperf
), 0xe7);
68 pread(fd
, &old_mperf
, sizeof(old_aperf
), 0xe8);
70 for (i
=0; i
<0x8fffffff; i
++) {
74 if (clock_gettime(CLOCK_MONOTONIC
, &after
) < 0) {
75 perror("clock_gettime");
78 pread(fd
, &new_tsc
, sizeof(new_tsc
), 0x10);
79 pread(fd
, &new_aperf
, sizeof(new_mperf
), 0xe7);
80 pread(fd
, &new_mperf
, sizeof(new_aperf
), 0xe8);
82 tsc
= new_tsc
-old_tsc
;
83 aperf
= new_aperf
-old_aperf
;
84 mperf
= new_mperf
-old_mperf
;
86 start
= before
.tv_sec
*MSEC_PER_SEC
+ before
.tv_nsec
/NSEC_PER_MSEC
;
87 finish
= after
.tv_sec
*MSEC_PER_SEC
+ after
.tv_nsec
/NSEC_PER_MSEC
;
88 total
= finish
- start
;
90 printf("runTime: %4.2f\n", 1.0*total
/MSEC_PER_SEC
);
91 printf("freq: %7.0f\n", tsc
/ (1.0*aperf
/ (1.0 * mperf
)) / total
);