0001
0002
0003
0004
0005
0006
0007
0008 #include <stdio.h>
0009 #include <stdlib.h>
0010 #include <unistd.h>
0011 #include <signal.h>
0012 #include <inttypes.h>
0013
0014
0015 #include <sys/prctl.h>
0016 #include <linux/prctl.h>
0017
0018
0019 #ifndef PR_GET_TSC
0020 #define PR_GET_TSC 25
0021 #define PR_SET_TSC 26
0022 # define PR_TSC_ENABLE 1
0023 # define PR_TSC_SIGSEGV 2
0024 #endif
0025
0026 const char *tsc_names[] =
0027 {
0028 [0] = "[not set]",
0029 [PR_TSC_ENABLE] = "PR_TSC_ENABLE",
0030 [PR_TSC_SIGSEGV] = "PR_TSC_SIGSEGV",
0031 };
0032
0033 static uint64_t rdtsc(void)
0034 {
0035 uint32_t lo, hi;
0036
0037 __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi));
0038 return (uint64_t)hi << 32 | lo;
0039 }
0040
0041 static void sigsegv_cb(int sig)
0042 {
0043 int tsc_val = 0;
0044
0045 printf("[ SIG_SEGV ]\n");
0046 printf("prctl(PR_GET_TSC, &tsc_val); ");
0047 fflush(stdout);
0048
0049 if ( prctl(PR_GET_TSC, &tsc_val) == -1)
0050 perror("prctl");
0051
0052 printf("tsc_val == %s\n", tsc_names[tsc_val]);
0053 printf("prctl(PR_SET_TSC, PR_TSC_ENABLE)\n");
0054 fflush(stdout);
0055 if ( prctl(PR_SET_TSC, PR_TSC_ENABLE) == -1)
0056 perror("prctl");
0057
0058 printf("rdtsc() == ");
0059 }
0060
0061 int main(void)
0062 {
0063 int tsc_val = 0;
0064
0065 signal(SIGSEGV, sigsegv_cb);
0066
0067 printf("rdtsc() == %llu\n", (unsigned long long)rdtsc());
0068 printf("prctl(PR_GET_TSC, &tsc_val); ");
0069 fflush(stdout);
0070
0071 if ( prctl(PR_GET_TSC, &tsc_val) == -1)
0072 perror("prctl");
0073
0074 printf("tsc_val == %s\n", tsc_names[tsc_val]);
0075 printf("rdtsc() == %llu\n", (unsigned long long)rdtsc());
0076 printf("prctl(PR_SET_TSC, PR_TSC_ENABLE)\n");
0077 fflush(stdout);
0078
0079 if ( prctl(PR_SET_TSC, PR_TSC_ENABLE) == -1)
0080 perror("prctl");
0081
0082 printf("rdtsc() == %llu\n", (unsigned long long)rdtsc());
0083 printf("prctl(PR_SET_TSC, PR_TSC_SIGSEGV)\n");
0084 fflush(stdout);
0085
0086 if ( prctl(PR_SET_TSC, PR_TSC_SIGSEGV) == -1)
0087 perror("prctl");
0088
0089 printf("rdtsc() == ");
0090 fflush(stdout);
0091 printf("%llu\n", (unsigned long long)rdtsc());
0092 fflush(stdout);
0093
0094 exit(EXIT_SUCCESS);
0095 }
0096