suspend.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
  2. /* This Source Code Form is subject to the terms of the Mozilla Public
  3. * License, v. 2.0. If a copy of the MPL was not distributed with this
  4. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  5. #include "nspr.h"
  6. #include "prpriv.h"
  7. #include "prinrval.h"
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <string.h>
  11. PRMonitor *mon;
  12. PRInt32 count;
  13. PRInt32 alive;
  14. #define SLEEP_TIME 4 /* secs */
  15. void PR_CALLBACK
  16. Level_2_Thread(void *arg)
  17. {
  18. PR_Sleep(PR_MillisecondsToInterval(4 * 1000));
  19. printf("Level_2_Thread[0x%lx] exiting\n",PR_GetCurrentThread());
  20. return;
  21. }
  22. void PR_CALLBACK
  23. Level_1_Thread(void *arg)
  24. {
  25. PRUint32 tmp = (PRUint32)arg;
  26. PRThreadScope scope = (PRThreadScope) tmp;
  27. PRThread *thr;
  28. thr = PR_CreateThreadGCAble(PR_USER_THREAD,
  29. Level_2_Thread,
  30. NULL,
  31. PR_PRIORITY_HIGH,
  32. scope,
  33. PR_JOINABLE_THREAD,
  34. 0);
  35. if (!thr) {
  36. printf("Could not create thread!\n");
  37. } else {
  38. printf("Level_1_Thread[0x%lx] created %15s thread 0x%lx\n",
  39. PR_GetCurrentThread(),
  40. (scope == PR_GLOBAL_THREAD) ?
  41. "PR_GLOBAL_THREAD" : "PR_LOCAL_THREAD",
  42. thr);
  43. PR_JoinThread(thr);
  44. }
  45. PR_EnterMonitor(mon);
  46. alive--;
  47. PR_Notify(mon);
  48. PR_ExitMonitor(mon);
  49. printf("Thread[0x%lx] exiting\n",PR_GetCurrentThread());
  50. }
  51. static PRStatus PR_CALLBACK print_thread(PRThread *thread, int i, void *arg)
  52. {
  53. PRInt32 words;
  54. PRWord *registers;
  55. printf(
  56. "\nprint_thread[0x%lx]: %-20s - i = %ld\n",thread,
  57. (PR_GLOBAL_THREAD == PR_GetThreadScope(thread)) ?
  58. "PR_GLOBAL_THREAD" : "PR_LOCAL_THREAD", i);
  59. registers = PR_GetGCRegisters(thread, 0, (int *)&words);
  60. if (registers)
  61. printf("Registers R0 = 0x%x R1 = 0x%x R2 = 0x%x R3 = 0x%x\n",
  62. registers[0],registers[1],registers[2],registers[3]);
  63. printf("Stack Pointer = 0x%lx\n", PR_GetSP(thread));
  64. return PR_SUCCESS;
  65. }
  66. static void Level_0_Thread(PRThreadScope scope1, PRThreadScope scope2)
  67. {
  68. PRThread *thr;
  69. PRThread *me = PR_GetCurrentThread();
  70. int n;
  71. PRInt32 words;
  72. PRWord *registers;
  73. alive = 0;
  74. mon = PR_NewMonitor();
  75. alive = count;
  76. for (n=0; n<count; n++) {
  77. thr = PR_CreateThreadGCAble(PR_USER_THREAD,
  78. Level_1_Thread,
  79. (void *)scope2,
  80. PR_PRIORITY_NORMAL,
  81. scope1,
  82. PR_UNJOINABLE_THREAD,
  83. 0);
  84. if (!thr) {
  85. printf("Could not create thread!\n");
  86. alive--;
  87. }
  88. printf("Level_0_Thread[0x%lx] created %15s thread 0x%lx\n",
  89. PR_GetCurrentThread(),
  90. (scope1 == PR_GLOBAL_THREAD) ?
  91. "PR_GLOBAL_THREAD" : "PR_LOCAL_THREAD",
  92. thr);
  93. PR_Sleep(0);
  94. }
  95. PR_SuspendAll();
  96. PR_EnumerateThreads(print_thread, NULL);
  97. registers = PR_GetGCRegisters(me, 1, (int *)&words);
  98. if (registers)
  99. printf("My Registers: R0 = 0x%x R1 = 0x%x R2 = 0x%x R3 = 0x%x\n",
  100. registers[0],registers[1],registers[2],registers[3]);
  101. printf("My Stack Pointer = 0x%lx\n", PR_GetSP(me));
  102. PR_ResumeAll();
  103. /* Wait for all threads to exit */
  104. PR_EnterMonitor(mon);
  105. while (alive) {
  106. PR_Wait(mon, PR_INTERVAL_NO_TIMEOUT);
  107. }
  108. PR_ExitMonitor(mon);
  109. PR_DestroyMonitor(mon);
  110. }
  111. static void CreateThreadsUU(void)
  112. {
  113. Level_0_Thread(PR_LOCAL_THREAD, PR_LOCAL_THREAD);
  114. }
  115. static void CreateThreadsUK(void)
  116. {
  117. Level_0_Thread(PR_LOCAL_THREAD, PR_GLOBAL_THREAD);
  118. }
  119. static void CreateThreadsKU(void)
  120. {
  121. Level_0_Thread(PR_GLOBAL_THREAD, PR_LOCAL_THREAD);
  122. }
  123. static void CreateThreadsKK(void)
  124. {
  125. Level_0_Thread(PR_GLOBAL_THREAD, PR_GLOBAL_THREAD);
  126. }
  127. int main(int argc, char **argv)
  128. {
  129. PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
  130. PR_STDIO_INIT();
  131. if (argc > 1) {
  132. count = atoi(argv[1]);
  133. } else {
  134. count = 5;
  135. }
  136. printf("\n\n%20s%30s\n\n"," ","Suspend_Resume Test");
  137. CreateThreadsUU();
  138. CreateThreadsUK();
  139. CreateThreadsKU();
  140. CreateThreadsKK();
  141. PR_SetConcurrency(2);
  142. printf("\n%20s%30s\n\n"," ","Added 2nd CPU\n");
  143. CreateThreadsUK();
  144. CreateThreadsKK();
  145. CreateThreadsUU();
  146. CreateThreadsKU();
  147. PR_Cleanup();
  148. return 0;
  149. }