nsprpub/pr/tests/attach.c

changeset 0
6474c204b198
     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 +}

mercurial