nsprpub/pr/tests/attach.c

Wed, 31 Dec 2014 06:55:50 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:55:50 +0100
changeset 2
7e26c7da4463
permissions
-rw-r--r--

Added tag UPSTREAM_283F7C6 for changeset ca08bd8f51b2

     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 }

mercurial