1 // SPDX-License-Identifier: GPL-2.0 2 #include <math.h> 3 #include <unistd.h> 4 #include <stdio.h> 5 #include <stdlib.h> 6 #include <sys/types.h> 7 #include <sys/stat.h> 8 #include <fcntl.h> 9 #include <sys/timeb.h> 10 #include <sched.h> 11 #include <errno.h> 12 #include <string.h> 13 #include "../kselftest.h" 14 15 void usage(char *name) { 16 printf ("Usage: %s cpunum\n", name); 17 } 18 19 int main(int argc, char **argv) { 20 unsigned int i, cpu, fd; 21 char msr_file_name[64]; 22 long long tsc, old_tsc, new_tsc; 23 long long aperf, old_aperf, new_aperf; 24 long long mperf, old_mperf, new_mperf; 25 struct timeb before, after; 26 long long int start, finish, total; 27 cpu_set_t cpuset; 28 29 if (argc != 2) { 30 usage(argv[0]); 31 return 1; 32 } 33 34 errno = 0; 35 cpu = strtol(argv[1], (char **) NULL, 10); 36 37 if (errno) { 38 usage(argv[0]); 39 return 1; 40 } 41 42 sprintf(msr_file_name, "/dev/cpu/%d/msr", cpu); 43 fd = open(msr_file_name, O_RDONLY); 44 45 if (fd == -1) { 46 printf("/dev/cpu/%d/msr: %s\n", cpu, strerror(errno)); 47 return KSFT_SKIP; 48 } 49 50 CPU_ZERO(&cpuset); 51 CPU_SET(cpu, &cpuset); 52 53 if (sched_setaffinity(0, sizeof(cpu_set_t), &cpuset)) { 54 perror("Failed to set cpu affinity"); 55 return 1; 56 } 57 58 ftime(&before); 59 pread(fd, &old_tsc, sizeof(old_tsc), 0x10); 60 pread(fd, &old_aperf, sizeof(old_mperf), 0xe7); 61 pread(fd, &old_mperf, sizeof(old_aperf), 0xe8); 62 63 for (i=0; i<0x8fffffff; i++) { 64 sqrt(i); 65 } 66 67 ftime(&after); 68 pread(fd, &new_tsc, sizeof(new_tsc), 0x10); 69 pread(fd, &new_aperf, sizeof(new_mperf), 0xe7); 70 pread(fd, &new_mperf, sizeof(new_aperf), 0xe8); 71 72 tsc = new_tsc-old_tsc; 73 aperf = new_aperf-old_aperf; 74 mperf = new_mperf-old_mperf; 75 76 start = before.time*1000 + before.millitm; 77 finish = after.time*1000 + after.millitm; 78 total = finish - start; 79 80 printf("runTime: %4.2f\n", 1.0*total/1000); 81 printf("freq: %7.0f\n", tsc / (1.0*aperf / (1.0 * mperf)) / total); 82 return 0; 83 } 84