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