vireshk

Remote-wakeups

Mar 9th, 2017
303
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.01 KB | None | 0 0
  1. /*
  2. * Remote Wakeup Cpufreq Latency Testcase
  3. *
  4. * A thread which was formerly low demand wakes up and starts running nonstop on
  5. * CPU0. This task is known in this testcase as the "framework thread."
  6. *
  7. * Immediately after that, a task on CPU1 causes a new task to be created on
  8. * CPU0. This new task also wants to run for a long time.
  9. *
  10. * Because the new task was created remotely a scheduler callback not
  11. * immediately invoked. It may be a full tick before the scheduler callback
  12. * fires.
  13. *
  14. * Affinity is used in this test case to generate the conditions necessary to
  15. * expose potentially high latency for a schedutil response. These conditions
  16. * should be observable without affinity however.
  17. */
  18.  
  19. #define _GNU_SOURCE
  20. #include <stdio.h>
  21. #include <pthread.h>
  22. #include <sys/time.h>
  23. #include <unistd.h>
  24.  
  25. int do_some_work(void)
  26. {
  27. int scratch;
  28. int i = 0;
  29.  
  30. while (i < 10000)
  31. scratch = ((scratch + 34) *3) % 7 + i++;
  32. return scratch;
  33. }
  34.  
  35. void do_busy(unsigned int usec)
  36. {
  37. long long usec_passed;
  38. struct timeval start, tv;
  39.  
  40. gettimeofday(&start, NULL);
  41.  
  42. while (1) {
  43. gettimeofday(&tv, NULL);
  44. usec_passed = tv.tv_sec - start.tv_sec;
  45. usec_passed *= 1000000;
  46. usec_passed += tv.tv_usec - start.tv_usec;
  47. if (usec_passed >= usec)
  48. return;
  49. else
  50. do_some_work();
  51. }
  52. }
  53.  
  54. /*
  55. * The framework thread is the thread that will have a low demand but start
  56. * running nonstop on CPU0 just before the woken_thread is woken on CPU0.
  57. */
  58. pthread_t framework_thread;
  59. void *framework_fn(void *arg)
  60. {
  61. cpu_set_t mask;
  62.  
  63. CPU_ZERO(&mask);
  64. CPU_SET(0, &mask);
  65. if (sched_setaffinity(0, sizeof(mask), &mask)) {
  66. printf("Could not set main thread affinity!\n");
  67. return NULL;
  68. }
  69.  
  70. usleep(398000);
  71.  
  72. do_busy(200000);
  73.  
  74. return NULL;
  75. }
  76.  
  77. /*
  78. * This thread gets woken up on CPU0. It is a new thread so it should have high
  79. * demand.
  80. */
  81. pthread_t woken_thread;
  82. void *woken_fn(void *arg)
  83. {
  84. /* Busy work! */
  85. do_busy(200000);
  86.  
  87. return NULL;
  88. }
  89.  
  90. int main(int argc, char **argv)
  91. {
  92. cpu_set_t mask;
  93. pthread_attr_t attrs;
  94.  
  95. /* The main task runs on CPU 1. */
  96. CPU_ZERO(&mask);
  97. CPU_SET(1, &mask);
  98. if (sched_setaffinity(0, sizeof(mask), &mask)) {
  99. printf("Could not set main thread affinity!\n");
  100. return -1;
  101. }
  102.  
  103. /* The "framework" and new tasks run on CPU0. */
  104. CPU_ZERO(&mask);
  105. CPU_SET(0, &mask);
  106. pthread_attr_init(&attrs);
  107. pthread_attr_setaffinity_np(&attrs, sizeof(mask), &mask);
  108. if (pthread_create(&framework_thread, &attrs, framework_fn,
  109. NULL)) {
  110. printf("Error creating framework thread!\n");
  111. return -1;
  112. }
  113.  
  114. /* Sleep just a little longer than the framework thread. */
  115. usleep(400000);
  116.  
  117. /* Wake up the new task. */
  118. if (pthread_create(&woken_thread, &attrs, woken_fn,
  119. NULL)) {
  120. printf("Error creating framework thread!\n");
  121. return -1;
  122. }
  123.  
  124. pthread_join(woken_thread, NULL);
  125. pthread_join(framework_thread, NULL);
  126.  
  127. printf("Current process: %u, framework: %u, woken: %u\n", getpid(),
  128. framework_thread, woken_thread);
  129.  
  130. return 0;
  131. }
Add Comment
Please, Sign In to add comment