Wed, 31 Dec 2014 06:55:46 +0100
Added tag TORBROWSER_REPLICA for changeset 6474c204b198
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/. */
6 /***********************************************************************
7 ** 1996 - Netscape Communications Corporation
8 **
9 ** Name: attach.c
10 **
11 ** Description: Platform-specific code to create a native thread. The native thread will
12 ** repeatedly call PR_AttachThread and PR_DetachThread. The
13 ** primordial thread waits for this new thread to finish.
14 **
15 ** Modification History:
16 ** 13-May-97 AGarcia- Converted the test to accomodate the debug_mode flag.
17 ** The debug mode will print all of the printfs associated with this test.
18 ** The regress mode will be the default mode. Since the regress tool limits
19 ** the output to a one line status:PASS or FAIL,all of the printf statements
20 ** have been handled with an if (debug_mode) statement.
21 ** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to
22 ** recognize the return code from tha main program.
23 ** 12-June-97 Revert to return code 0 and 1.
24 ***********************************************************************/
26 /***********************************************************************
27 ** Includes
28 ***********************************************************************/
30 /* Used to get the command line option */
31 #include "nspr.h"
32 #include "pprthred.h"
33 #include "plgetopt.h"
35 #include <stdio.h>
37 #ifdef WIN32
38 #include <windows.h>
39 #include <process.h>
40 #elif defined(_PR_PTHREADS)
41 #include <pthread.h>
42 #include "md/_pth.h"
43 #elif defined(IRIX)
44 #include <sys/types.h>
45 #include <sys/prctl.h>
46 #include <sys/wait.h>
47 #include <errno.h>
48 #elif defined(SOLARIS)
49 #include <thread.h>
50 #elif defined(OS2)
51 #define INCL_DOS
52 #define INCL_ERRORS
53 #include <os2.h>
54 #include <process.h>
55 #elif defined(XP_BEOS)
56 #include <kernel/OS.h>
57 #endif
59 #define DEFAULT_COUNT 1000
60 PRIntn failed_already=0;
61 PRIntn debug_mode;
64 int count;
67 static void
68 AttachDetach(void)
69 {
70 PRThread *me;
71 PRInt32 index;
73 for (index=0;index<count; index++) {
74 me = PR_AttachThread(PR_USER_THREAD,
75 PR_PRIORITY_NORMAL,
76 NULL);
78 if (!me) {
79 fprintf(stderr, "Error attaching thread %d: PR_AttachThread failed\n",
80 count);
81 failed_already = 1;
82 return;
83 }
84 PR_DetachThread();
85 }
86 }
88 /************************************************************************/
90 static void Measure(void (*func)(void), const char *msg)
91 {
92 PRIntervalTime start, stop;
93 double d;
95 start = PR_IntervalNow();
96 (*func)();
97 stop = PR_IntervalNow();
99 d = (double)PR_IntervalToMicroseconds(stop - start);
100 if (debug_mode)
101 printf("%40s: %6.2f usec\n", msg, d / count);
102 }
104 #ifdef WIN32
105 static unsigned __stdcall threadStartFunc(void *arg)
106 #elif defined(IRIX) && !defined(_PR_PTHREADS)
107 static void threadStartFunc(void *arg)
108 #elif defined(XP_BEOS)
109 static int32 threadStartFunc(void *arg)
110 #else
111 static void * threadStartFunc(void *arg)
112 #endif
113 {
114 #ifdef _PR_DCETHREADS
115 {
116 int rv;
117 pthread_t self = pthread_self();
118 rv = pthread_detach(&self);
119 if (debug_mode) PR_ASSERT(0 == rv);
120 else if (0 != rv) failed_already=1;
121 }
122 #endif
124 Measure(AttachDetach, "Attach/Detach");
126 #ifndef IRIX
127 return 0;
128 #endif
129 }
131 int main(int argc, char **argv)
132 {
133 #ifdef _PR_PTHREADS
134 int rv;
135 pthread_t threadID;
136 pthread_attr_t attr;
137 #elif defined(SOLARIS)
138 int rv;
139 thread_t threadID;
140 #elif defined(WIN32)
141 DWORD rv;
142 unsigned threadID;
143 HANDLE hThread;
144 #elif defined(IRIX)
145 int rv;
146 int threadID;
147 #elif defined(OS2)
148 int rv;
149 TID threadID;
150 #elif defined(XP_BEOS)
151 thread_id threadID;
152 int32 threadRV;
153 status_t waitRV;
154 #endif
156 /* The command line argument: -d is used to determine if the test is being run
157 in debug mode. The regress tool requires only one line output:PASS or FAIL.
158 All of the printfs associated with this test has been handled with a if (debug_mode)
159 test.
160 Usage: test_name [-d] [-c n]
161 */
162 PLOptStatus os;
163 PLOptState *opt = PL_CreateOptState(argc, argv, "dc:");
164 while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
165 {
166 if (PL_OPT_BAD == os) continue;
167 switch (opt->option)
168 {
169 case 'd': /* debug mode */
170 debug_mode = 1;
171 break;
172 case 'c': /* loop count */
173 count = atoi(opt->value);
174 break;
175 default:
176 break;
177 }
178 }
179 PL_DestroyOptState(opt);
181 #if defined(WIN16)
182 printf("attach: This test is not valid for Win16\n");
183 goto exit_now;
184 #endif
186 if(0 == count) count = DEFAULT_COUNT;
188 /*
189 * To force the implicit initialization of nspr20
190 */
191 PR_SetError(0, 0);
192 PR_STDIO_INIT();
194 /*
195 * Platform-specific code to create a native thread. The native
196 * thread will repeatedly call PR_AttachThread and PR_DetachThread.
197 * The primordial thread waits for this new thread to finish.
198 */
200 #ifdef _PR_PTHREADS
202 rv = _PT_PTHREAD_ATTR_INIT(&attr);
203 if (debug_mode) PR_ASSERT(0 == rv);
204 else if (0 != rv) {
205 failed_already=1;
206 goto exit_now;
207 }
209 #ifndef _PR_DCETHREADS
210 rv = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
211 if (debug_mode) PR_ASSERT(0 == rv);
212 else if (0 != rv) {
213 failed_already=1;
214 goto exit_now;
215 }
216 #endif /* !_PR_DCETHREADS */
217 rv = _PT_PTHREAD_CREATE(&threadID, attr, threadStartFunc, NULL);
218 if (rv != 0) {
219 fprintf(stderr, "thread creation failed: error code %d\n", rv);
220 failed_already=1;
221 goto exit_now;
222 }
223 else {
224 if (debug_mode)
225 printf ("thread creation succeeded \n");
227 }
228 rv = _PT_PTHREAD_ATTR_DESTROY(&attr);
229 if (debug_mode) PR_ASSERT(0 == rv);
230 else if (0 != rv) {
231 failed_already=1;
232 goto exit_now;
233 }
234 rv = pthread_join(threadID, NULL);
235 if (debug_mode) PR_ASSERT(0 == rv);
236 else if (0 != rv) {
237 failed_already=1;
238 goto exit_now;
239 }
241 #elif defined(SOLARIS)
243 rv = thr_create(NULL, 0, threadStartFunc, NULL, 0, &threadID);
244 if (rv != 0) {
245 if(!debug_mode) {
246 failed_already=1;
247 goto exit_now;
248 } else
249 fprintf(stderr, "thread creation failed: error code %d\n", rv);
250 }
251 rv = thr_join(threadID, NULL, NULL);
252 if (debug_mode) PR_ASSERT(0 == rv);
253 else if (0 != rv)
254 {
255 failed_already=1;
256 goto exit_now;
257 }
260 #elif defined(WIN32)
262 hThread = (HANDLE) _beginthreadex(NULL, 0, threadStartFunc, NULL,
263 STACK_SIZE_PARAM_IS_A_RESERVATION, &threadID);
264 if (hThread == 0) {
265 fprintf(stderr, "thread creation failed: error code %d\n",
266 GetLastError());
267 failed_already=1;
268 goto exit_now;
269 }
270 rv = WaitForSingleObject(hThread, INFINITE);
271 if (debug_mode)PR_ASSERT(rv != WAIT_FAILED);
272 else if (rv == WAIT_FAILED) {
273 failed_already=1;
274 goto exit_now;
275 }
277 #elif defined(IRIX)
279 threadID = sproc(threadStartFunc, PR_SALL, NULL);
280 if (threadID == -1) {
282 fprintf(stderr, "thread creation failed: error code %d\n",
283 errno);
284 failed_already=1;
285 goto exit_now;
287 }
288 else {
289 if (debug_mode)
290 printf ("thread creation succeeded \n");
291 sleep(3);
292 goto exit_now;
293 }
294 rv = waitpid(threadID, NULL, 0);
295 if (debug_mode) PR_ASSERT(rv != -1);
296 else if (rv != -1) {
297 failed_already=1;
298 goto exit_now;
299 }
301 #elif defined(OS2)
303 threadID = (TID) _beginthread((void *)threadStartFunc, NULL,
304 32768, NULL);
305 if (threadID == -1) {
306 fprintf(stderr, "thread creation failed: error code %d\n", errno);
307 failed_already=1;
308 goto exit_now;
309 }
310 rv = DosWaitThread(&threadID, DCWW_WAIT);
311 if (debug_mode) {
312 PR_ASSERT(rv == NO_ERROR);
313 } else if (rv != NO_ERROR) {
314 failed_already=1;
315 goto exit_now;
316 }
318 #elif defined(XP_BEOS)
320 threadID = spawn_thread(threadStartFunc, NULL, B_NORMAL_PRIORITY, NULL);
321 if (threadID <= B_ERROR) {
322 fprintf(stderr, "thread creation failed: error code %08lx\n", threadID);
323 failed_already = 1;
324 goto exit_now;
325 }
326 if (resume_thread(threadID) != B_OK) {
327 fprintf(stderr, "failed starting thread: error code %08lx\n", threadID);
328 failed_already = 1;
329 goto exit_now;
330 }
332 waitRV = wait_for_thread(threadID, &threadRV);
333 if (debug_mode)
334 PR_ASSERT(waitRV == B_OK);
335 else if (waitRV != B_OK) {
336 failed_already = 1;
337 goto exit_now;
338 }
340 #else
341 if (!debug_mode)
342 failed_already=1;
343 else
344 printf("The attach test does not apply to this platform because\n"
345 "either this platform does not have native threads or the\n"
346 "test needs to be written for this platform.\n");
347 goto exit_now;
348 #endif
350 exit_now:
351 if(failed_already)
352 return 1;
353 else
354 return 0;
355 }