disable-tsc-ctxt-sw-stress-test.c 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. /*
  2. * Tests for prctl(PR_GET_TSC, ...) / prctl(PR_SET_TSC, ...)
  3. *
  4. * Tests if the control register is updated correctly
  5. * at context switches
  6. *
  7. * Warning: this test will cause a very high load for a few seconds
  8. *
  9. */
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #include <unistd.h>
  13. #include <signal.h>
  14. #include <inttypes.h>
  15. #include <wait.h>
  16. #include <sys/prctl.h>
  17. #include <linux/prctl.h>
  18. /* Get/set the process' ability to use the timestamp counter instruction */
  19. #ifndef PR_GET_TSC
  20. #define PR_GET_TSC 25
  21. #define PR_SET_TSC 26
  22. # define PR_TSC_ENABLE 1 /* allow the use of the timestamp counter */
  23. # define PR_TSC_SIGSEGV 2 /* throw a SIGSEGV instead of reading the TSC */
  24. #endif
  25. uint64_t rdtsc() {
  26. uint32_t lo, hi;
  27. /* We cannot use "=A", since this would use %rax on x86_64 */
  28. __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi));
  29. return (uint64_t)hi << 32 | lo;
  30. }
  31. void sigsegv_expect(int sig)
  32. {
  33. /* */
  34. }
  35. void segvtask(void)
  36. {
  37. if (prctl(PR_SET_TSC, PR_TSC_SIGSEGV) < 0)
  38. {
  39. perror("prctl");
  40. exit(0);
  41. }
  42. signal(SIGSEGV, sigsegv_expect);
  43. alarm(10);
  44. rdtsc();
  45. fprintf(stderr, "FATAL ERROR, rdtsc() succeeded while disabled\n");
  46. exit(0);
  47. }
  48. void sigsegv_fail(int sig)
  49. {
  50. fprintf(stderr, "FATAL ERROR, rdtsc() failed while enabled\n");
  51. exit(0);
  52. }
  53. void rdtsctask(void)
  54. {
  55. if (prctl(PR_SET_TSC, PR_TSC_ENABLE) < 0)
  56. {
  57. perror("prctl");
  58. exit(0);
  59. }
  60. signal(SIGSEGV, sigsegv_fail);
  61. alarm(10);
  62. for(;;) rdtsc();
  63. }
  64. int main(int argc, char **argv)
  65. {
  66. int n_tasks = 100, i;
  67. fprintf(stderr, "[No further output means we're allright]\n");
  68. for (i=0; i<n_tasks; i++)
  69. if (fork() == 0)
  70. {
  71. if (i & 1)
  72. segvtask();
  73. else
  74. rdtsctask();
  75. }
  76. for (i=0; i<n_tasks; i++)
  77. wait(NULL);
  78. exit(0);
  79. }