1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/nsprpub/pr/tests/attach.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,355 @@ 1.4 +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +/*********************************************************************** 1.10 +** 1996 - Netscape Communications Corporation 1.11 +** 1.12 +** Name: attach.c 1.13 +** 1.14 +** Description: Platform-specific code to create a native thread. The native thread will 1.15 +** repeatedly call PR_AttachThread and PR_DetachThread. The 1.16 +** primordial thread waits for this new thread to finish. 1.17 +** 1.18 +** Modification History: 1.19 +** 13-May-97 AGarcia- Converted the test to accomodate the debug_mode flag. 1.20 +** The debug mode will print all of the printfs associated with this test. 1.21 +** The regress mode will be the default mode. Since the regress tool limits 1.22 +** the output to a one line status:PASS or FAIL,all of the printf statements 1.23 +** have been handled with an if (debug_mode) statement. 1.24 +** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to 1.25 +** recognize the return code from tha main program. 1.26 +** 12-June-97 Revert to return code 0 and 1. 1.27 +***********************************************************************/ 1.28 + 1.29 +/*********************************************************************** 1.30 +** Includes 1.31 +***********************************************************************/ 1.32 + 1.33 +/* Used to get the command line option */ 1.34 +#include "nspr.h" 1.35 +#include "pprthred.h" 1.36 +#include "plgetopt.h" 1.37 + 1.38 +#include <stdio.h> 1.39 + 1.40 +#ifdef WIN32 1.41 +#include <windows.h> 1.42 +#include <process.h> 1.43 +#elif defined(_PR_PTHREADS) 1.44 +#include <pthread.h> 1.45 +#include "md/_pth.h" 1.46 +#elif defined(IRIX) 1.47 +#include <sys/types.h> 1.48 +#include <sys/prctl.h> 1.49 +#include <sys/wait.h> 1.50 +#include <errno.h> 1.51 +#elif defined(SOLARIS) 1.52 +#include <thread.h> 1.53 +#elif defined(OS2) 1.54 +#define INCL_DOS 1.55 +#define INCL_ERRORS 1.56 +#include <os2.h> 1.57 +#include <process.h> 1.58 +#elif defined(XP_BEOS) 1.59 +#include <kernel/OS.h> 1.60 +#endif 1.61 + 1.62 +#define DEFAULT_COUNT 1000 1.63 +PRIntn failed_already=0; 1.64 +PRIntn debug_mode; 1.65 + 1.66 + 1.67 +int count; 1.68 + 1.69 + 1.70 +static void 1.71 +AttachDetach(void) 1.72 +{ 1.73 + PRThread *me; 1.74 + PRInt32 index; 1.75 + 1.76 + for (index=0;index<count; index++) { 1.77 + me = PR_AttachThread(PR_USER_THREAD, 1.78 + PR_PRIORITY_NORMAL, 1.79 + NULL); 1.80 + 1.81 + if (!me) { 1.82 + fprintf(stderr, "Error attaching thread %d: PR_AttachThread failed\n", 1.83 + count); 1.84 + failed_already = 1; 1.85 + return; 1.86 + } 1.87 + PR_DetachThread(); 1.88 + } 1.89 +} 1.90 + 1.91 +/************************************************************************/ 1.92 + 1.93 +static void Measure(void (*func)(void), const char *msg) 1.94 +{ 1.95 + PRIntervalTime start, stop; 1.96 + double d; 1.97 + 1.98 + start = PR_IntervalNow(); 1.99 + (*func)(); 1.100 + stop = PR_IntervalNow(); 1.101 + 1.102 + d = (double)PR_IntervalToMicroseconds(stop - start); 1.103 + if (debug_mode) 1.104 + printf("%40s: %6.2f usec\n", msg, d / count); 1.105 +} 1.106 + 1.107 +#ifdef WIN32 1.108 +static unsigned __stdcall threadStartFunc(void *arg) 1.109 +#elif defined(IRIX) && !defined(_PR_PTHREADS) 1.110 +static void threadStartFunc(void *arg) 1.111 +#elif defined(XP_BEOS) 1.112 +static int32 threadStartFunc(void *arg) 1.113 +#else 1.114 +static void * threadStartFunc(void *arg) 1.115 +#endif 1.116 +{ 1.117 +#ifdef _PR_DCETHREADS 1.118 + { 1.119 + int rv; 1.120 + pthread_t self = pthread_self(); 1.121 + rv = pthread_detach(&self); 1.122 + if (debug_mode) PR_ASSERT(0 == rv); 1.123 + else if (0 != rv) failed_already=1; 1.124 + } 1.125 +#endif 1.126 + 1.127 + Measure(AttachDetach, "Attach/Detach"); 1.128 + 1.129 +#ifndef IRIX 1.130 + return 0; 1.131 +#endif 1.132 +} 1.133 + 1.134 +int main(int argc, char **argv) 1.135 +{ 1.136 +#ifdef _PR_PTHREADS 1.137 + int rv; 1.138 + pthread_t threadID; 1.139 + pthread_attr_t attr; 1.140 +#elif defined(SOLARIS) 1.141 + int rv; 1.142 + thread_t threadID; 1.143 +#elif defined(WIN32) 1.144 + DWORD rv; 1.145 + unsigned threadID; 1.146 + HANDLE hThread; 1.147 +#elif defined(IRIX) 1.148 + int rv; 1.149 + int threadID; 1.150 +#elif defined(OS2) 1.151 + int rv; 1.152 + TID threadID; 1.153 +#elif defined(XP_BEOS) 1.154 + thread_id threadID; 1.155 + int32 threadRV; 1.156 + status_t waitRV; 1.157 +#endif 1.158 + 1.159 + /* The command line argument: -d is used to determine if the test is being run 1.160 + in debug mode. The regress tool requires only one line output:PASS or FAIL. 1.161 + All of the printfs associated with this test has been handled with a if (debug_mode) 1.162 + test. 1.163 + Usage: test_name [-d] [-c n] 1.164 + */ 1.165 + PLOptStatus os; 1.166 + PLOptState *opt = PL_CreateOptState(argc, argv, "dc:"); 1.167 + while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) 1.168 + { 1.169 + if (PL_OPT_BAD == os) continue; 1.170 + switch (opt->option) 1.171 + { 1.172 + case 'd': /* debug mode */ 1.173 + debug_mode = 1; 1.174 + break; 1.175 + case 'c': /* loop count */ 1.176 + count = atoi(opt->value); 1.177 + break; 1.178 + default: 1.179 + break; 1.180 + } 1.181 + } 1.182 + PL_DestroyOptState(opt); 1.183 + 1.184 +#if defined(WIN16) 1.185 + printf("attach: This test is not valid for Win16\n"); 1.186 + goto exit_now; 1.187 +#endif 1.188 + 1.189 + if(0 == count) count = DEFAULT_COUNT; 1.190 + 1.191 + /* 1.192 + * To force the implicit initialization of nspr20 1.193 + */ 1.194 + PR_SetError(0, 0); 1.195 + PR_STDIO_INIT(); 1.196 + 1.197 + /* 1.198 + * Platform-specific code to create a native thread. The native 1.199 + * thread will repeatedly call PR_AttachThread and PR_DetachThread. 1.200 + * The primordial thread waits for this new thread to finish. 1.201 + */ 1.202 + 1.203 +#ifdef _PR_PTHREADS 1.204 + 1.205 + rv = _PT_PTHREAD_ATTR_INIT(&attr); 1.206 + if (debug_mode) PR_ASSERT(0 == rv); 1.207 + else if (0 != rv) { 1.208 + failed_already=1; 1.209 + goto exit_now; 1.210 + } 1.211 + 1.212 +#ifndef _PR_DCETHREADS 1.213 + rv = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); 1.214 + if (debug_mode) PR_ASSERT(0 == rv); 1.215 + else if (0 != rv) { 1.216 + failed_already=1; 1.217 + goto exit_now; 1.218 + } 1.219 +#endif /* !_PR_DCETHREADS */ 1.220 + rv = _PT_PTHREAD_CREATE(&threadID, attr, threadStartFunc, NULL); 1.221 + if (rv != 0) { 1.222 + fprintf(stderr, "thread creation failed: error code %d\n", rv); 1.223 + failed_already=1; 1.224 + goto exit_now; 1.225 + } 1.226 + else { 1.227 + if (debug_mode) 1.228 + printf ("thread creation succeeded \n"); 1.229 + 1.230 + } 1.231 + rv = _PT_PTHREAD_ATTR_DESTROY(&attr); 1.232 + if (debug_mode) PR_ASSERT(0 == rv); 1.233 + else if (0 != rv) { 1.234 + failed_already=1; 1.235 + goto exit_now; 1.236 + } 1.237 + rv = pthread_join(threadID, NULL); 1.238 + if (debug_mode) PR_ASSERT(0 == rv); 1.239 + else if (0 != rv) { 1.240 + failed_already=1; 1.241 + goto exit_now; 1.242 + } 1.243 + 1.244 +#elif defined(SOLARIS) 1.245 + 1.246 + rv = thr_create(NULL, 0, threadStartFunc, NULL, 0, &threadID); 1.247 + if (rv != 0) { 1.248 + if(!debug_mode) { 1.249 + failed_already=1; 1.250 + goto exit_now; 1.251 + } else 1.252 + fprintf(stderr, "thread creation failed: error code %d\n", rv); 1.253 + } 1.254 + rv = thr_join(threadID, NULL, NULL); 1.255 + if (debug_mode) PR_ASSERT(0 == rv); 1.256 + else if (0 != rv) 1.257 + { 1.258 + failed_already=1; 1.259 + goto exit_now; 1.260 + } 1.261 + 1.262 + 1.263 +#elif defined(WIN32) 1.264 + 1.265 + hThread = (HANDLE) _beginthreadex(NULL, 0, threadStartFunc, NULL, 1.266 + STACK_SIZE_PARAM_IS_A_RESERVATION, &threadID); 1.267 + if (hThread == 0) { 1.268 + fprintf(stderr, "thread creation failed: error code %d\n", 1.269 + GetLastError()); 1.270 + failed_already=1; 1.271 + goto exit_now; 1.272 + } 1.273 + rv = WaitForSingleObject(hThread, INFINITE); 1.274 + if (debug_mode)PR_ASSERT(rv != WAIT_FAILED); 1.275 + else if (rv == WAIT_FAILED) { 1.276 + failed_already=1; 1.277 + goto exit_now; 1.278 + } 1.279 + 1.280 +#elif defined(IRIX) 1.281 + 1.282 + threadID = sproc(threadStartFunc, PR_SALL, NULL); 1.283 + if (threadID == -1) { 1.284 + 1.285 + fprintf(stderr, "thread creation failed: error code %d\n", 1.286 + errno); 1.287 + failed_already=1; 1.288 + goto exit_now; 1.289 + 1.290 + } 1.291 + else { 1.292 + if (debug_mode) 1.293 + printf ("thread creation succeeded \n"); 1.294 + sleep(3); 1.295 + goto exit_now; 1.296 + } 1.297 + rv = waitpid(threadID, NULL, 0); 1.298 + if (debug_mode) PR_ASSERT(rv != -1); 1.299 + else if (rv != -1) { 1.300 + failed_already=1; 1.301 + goto exit_now; 1.302 + } 1.303 + 1.304 +#elif defined(OS2) 1.305 + 1.306 + threadID = (TID) _beginthread((void *)threadStartFunc, NULL, 1.307 + 32768, NULL); 1.308 + if (threadID == -1) { 1.309 + fprintf(stderr, "thread creation failed: error code %d\n", errno); 1.310 + failed_already=1; 1.311 + goto exit_now; 1.312 + } 1.313 + rv = DosWaitThread(&threadID, DCWW_WAIT); 1.314 + if (debug_mode) { 1.315 + PR_ASSERT(rv == NO_ERROR); 1.316 + } else if (rv != NO_ERROR) { 1.317 + failed_already=1; 1.318 + goto exit_now; 1.319 + } 1.320 + 1.321 +#elif defined(XP_BEOS) 1.322 + 1.323 + threadID = spawn_thread(threadStartFunc, NULL, B_NORMAL_PRIORITY, NULL); 1.324 + if (threadID <= B_ERROR) { 1.325 + fprintf(stderr, "thread creation failed: error code %08lx\n", threadID); 1.326 + failed_already = 1; 1.327 + goto exit_now; 1.328 + } 1.329 + if (resume_thread(threadID) != B_OK) { 1.330 + fprintf(stderr, "failed starting thread: error code %08lx\n", threadID); 1.331 + failed_already = 1; 1.332 + goto exit_now; 1.333 + } 1.334 + 1.335 + waitRV = wait_for_thread(threadID, &threadRV); 1.336 + if (debug_mode) 1.337 + PR_ASSERT(waitRV == B_OK); 1.338 + else if (waitRV != B_OK) { 1.339 + failed_already = 1; 1.340 + goto exit_now; 1.341 + } 1.342 + 1.343 +#else 1.344 + if (!debug_mode) 1.345 + failed_already=1; 1.346 + else 1.347 + printf("The attach test does not apply to this platform because\n" 1.348 + "either this platform does not have native threads or the\n" 1.349 + "test needs to be written for this platform.\n"); 1.350 + goto exit_now; 1.351 +#endif 1.352 + 1.353 +exit_now: 1.354 + if(failed_already) 1.355 + return 1; 1.356 + else 1.357 + return 0; 1.358 +}