Merge branch 'parisc-4.6-4' of git://git.kernel.org/pub/scm/linux/kernel/git/deller...
[linux/fpc-iii.git] / Documentation / prctl / disable-tsc-ctxt-sw-stress-test.c
blobf7499d1c0415f3f8aa00779b5768cfa3c536f871
1 /*
2 * Tests for prctl(PR_GET_TSC, ...) / prctl(PR_SET_TSC, ...)
4 * Tests if the control register is updated correctly
5 * at context switches
7 * Warning: this test will cause a very high load for a few seconds
9 */
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <unistd.h>
14 #include <signal.h>
15 #include <inttypes.h>
16 #include <wait.h>
19 #include <sys/prctl.h>
20 #include <linux/prctl.h>
22 /* Get/set the process' ability to use the timestamp counter instruction */
23 #ifndef PR_GET_TSC
24 #define PR_GET_TSC 25
25 #define PR_SET_TSC 26
26 # define PR_TSC_ENABLE 1 /* allow the use of the timestamp counter */
27 # define PR_TSC_SIGSEGV 2 /* throw a SIGSEGV instead of reading the TSC */
28 #endif
30 static uint64_t rdtsc(void)
32 uint32_t lo, hi;
33 /* We cannot use "=A", since this would use %rax on x86_64 */
34 __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi));
35 return (uint64_t)hi << 32 | lo;
38 static void sigsegv_expect(int sig)
40 /* */
43 static void segvtask(void)
45 if (prctl(PR_SET_TSC, PR_TSC_SIGSEGV) < 0)
47 perror("prctl");
48 exit(0);
50 signal(SIGSEGV, sigsegv_expect);
51 alarm(10);
52 rdtsc();
53 fprintf(stderr, "FATAL ERROR, rdtsc() succeeded while disabled\n");
54 exit(0);
58 static void sigsegv_fail(int sig)
60 fprintf(stderr, "FATAL ERROR, rdtsc() failed while enabled\n");
61 exit(0);
64 static void rdtsctask(void)
66 if (prctl(PR_SET_TSC, PR_TSC_ENABLE) < 0)
68 perror("prctl");
69 exit(0);
71 signal(SIGSEGV, sigsegv_fail);
72 alarm(10);
73 for(;;) rdtsc();
77 int main(void)
79 int n_tasks = 100, i;
81 fprintf(stderr, "[No further output means we're allright]\n");
83 for (i=0; i<n_tasks; i++)
84 if (fork() == 0)
86 if (i & 1)
87 segvtask();
88 else
89 rdtsctask();
92 for (i=0; i<n_tasks; i++)
93 wait(NULL);
95 exit(0);