home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / nsprpub / pr / tests / attach.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  8.9 KB  |  347 lines

  1. /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
  2. /*
  3.  * The contents of this file are subject to the Netscape Public License
  4.  * Version 1.0 (the "NPL"); you may not use this file except in
  5.  * compliance with the NPL.  You may obtain a copy of the NPL at
  6.  * http://www.mozilla.org/NPL/
  7.  * 
  8.  * Software distributed under the NPL is distributed on an "AS IS" basis,
  9.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
  10.  * for the specific language governing rights and limitations under the
  11.  * NPL.
  12.  * 
  13.  * The Initial Developer of this code under the NPL is Netscape
  14.  * Communications Corporation.  Portions created by Netscape are
  15.  * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
  16.  * Reserved.
  17.  */
  18.  
  19. /***********************************************************************
  20. **  1996 - Netscape Communications Corporation
  21. **
  22. ** Name: attach.c
  23. **
  24. ** Description: Platform-specific code to create a native thread. The native thread will
  25. **                            repeatedly call PR_AttachThread and PR_DetachThread. The
  26. **                            primordial thread waits for this new thread to finish.
  27. **
  28. ** Modification History:
  29. ** 13-May-97 AGarcia- Converted the test to accomodate the debug_mode flag.
  30. **             The debug mode will print all of the printfs associated with this test.
  31. **             The regress mode will be the default mode. Since the regress tool limits
  32. **           the output to a one line status:PASS or FAIL,all of the printf statements
  33. **             have been handled with an if (debug_mode) statement.
  34. ** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to
  35. **            recognize the return code from tha main program.
  36. ** 12-June-97 Revert to return code 0 and 1.
  37. ***********************************************************************/
  38.  
  39. /***********************************************************************
  40. ** Includes
  41. ***********************************************************************/
  42.  
  43. /* Used to get the command line option */
  44. #include "nspr.h"
  45. #include "pprthred.h"
  46. #include "plgetopt.h"
  47.  
  48. #include <stdio.h>
  49.  
  50. #ifdef WIN32
  51. #include "process.h"
  52. #elif defined(_PR_PTHREADS)
  53. /*
  54.  * XXX: On Linux 2.0.27 (installed on tioman.mcom.com), sched.h uses
  55.  * this _P macro that seems to be undefined.  I suspect that it is
  56.  * a typo (should be __P).
  57.  */
  58. #if defined(LINUX)
  59. #define _P(x) __P(x)
  60. #endif
  61. #include <pthread.h>
  62. #include "md/_pth.h"
  63. #elif defined(IRIX)
  64. #include <sys/types.h>
  65. #include <sys/prctl.h>
  66. #include <sys/wait.h>
  67. #include <errno.h>
  68. #elif defined(SOLARIS)
  69. #include <thread.h>
  70. #elif defined(OS2)
  71. #define INCL_DOS
  72. #define INCL_ERRORS
  73. #include <os2.h>
  74. #endif
  75.  
  76. #define DEFAULT_COUNT 10000
  77. PRIntn failed_already=0;
  78. PRIntn debug_mode;
  79.  
  80.  
  81. int count;
  82.  
  83.  
  84. static void 
  85. AttachDetach(void)
  86. {
  87.     PRThread *me;
  88.     PRInt32 index;
  89.  
  90.     for (index=0;index<count; index++) {
  91.  
  92.         me = PR_AttachThread(PR_USER_THREAD, 
  93.                              PR_PRIORITY_NORMAL,
  94.                              NULL);
  95.  
  96.         if (!me) {
  97.             fprintf(stderr, "Error attaching thread %d: "
  98.             "nspr20 error code %d, os error code %d\n",
  99.             count, PR_GetError(), PR_GetOSError());
  100.         failed_already = 1;
  101.         return;
  102.         }
  103.  
  104.         PR_DetachThread();
  105.  
  106.     }
  107. }
  108.  
  109. /************************************************************************/
  110.  
  111. static void Measure(void (*func)(void), const char *msg)
  112. {
  113.     PRIntervalTime start, stop;
  114.     double d;
  115.  
  116.     start = PR_IntervalNow();
  117.     (*func)();
  118.     stop = PR_IntervalNow();
  119.  
  120.     d = (double)PR_IntervalToMicroseconds(stop - start);
  121.     if (debug_mode)
  122.     printf("%40s: %6.2f usec\n", msg, d / count);
  123. }
  124.  
  125. #ifdef WIN32
  126. static unsigned __stdcall threadStartFunc(void *arg)
  127. #elif defined(IRIX) && !defined(_PR_PTHREADS)
  128. static void threadStartFunc(void *arg)
  129. #else
  130. static void * threadStartFunc(void *arg)
  131. #endif
  132. {
  133. #ifdef _PR_DCETHREADS
  134.     {
  135.         int rv;
  136.         pthread_t self = pthread_self();
  137.         rv = pthread_detach(&self);
  138.         if (debug_mode) PR_ASSERT(0 == rv);
  139.         else if (0 != rv) failed_already=1;
  140.     }
  141. #endif
  142.  
  143.     Measure(AttachDetach, "Attach/Detach");
  144.  
  145. #ifndef IRIX
  146.     return 0;
  147. #endif
  148. }
  149.  
  150. int main(int argc, char **argv)
  151. {
  152. #ifdef _PR_PTHREADS
  153.     int rv;
  154.     pthread_t threadID;
  155.     pthread_attr_t attr;
  156. #elif defined(SOLARIS)
  157.     int rv;
  158.     thread_t threadID;
  159. #elif defined(WIN32)
  160.     DWORD rv;
  161.     unsigned threadID;
  162.     HANDLE hThread;
  163. #elif defined(IRIX)
  164.     int rv;
  165.     int threadID;
  166. #elif defined(OS2)
  167.     int rv;
  168.     TID threadID;
  169. #endif
  170.  
  171.     /* The command line argument: -d is used to determine if the test is being run
  172.     in debug mode. The regress tool requires only one line output:PASS or FAIL.
  173.     All of the printfs associated with this test has been handled with a if (debug_mode)
  174.     test.
  175.     Usage: test_name [-d] [-c n]
  176.     */
  177.     PLOptStatus os;
  178.     PLOptState *opt = PL_CreateOptState(argc, argv, "dc:");
  179.     while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
  180.     {
  181.         if (PL_OPT_BAD == os) continue;
  182.         switch (opt->option)
  183.         {
  184.         case 'd':  /* debug mode */
  185.             debug_mode = 1;
  186.             break;
  187.         case 'c':  /* loop count */
  188.             count = atoi(opt->value);
  189.             break;
  190.          default:
  191.             break;
  192.         }
  193.     }
  194.     PL_DestroyOptState(opt);
  195.  
  196. #if defined(WIN16)
  197.     printf("attach: This test is not valid for Win16\n");
  198.     goto exit_now;
  199. #endif
  200.  
  201.     if(0 == count) count = DEFAULT_COUNT;    
  202.  
  203.     /*
  204.      * To force the implicit initialization of nspr20
  205.      */
  206.     PR_SetError(0, 0);
  207.     PR_STDIO_INIT();
  208.  
  209.     /*
  210.      * Platform-specific code to create a native thread.  The native
  211.      * thread will repeatedly call PR_AttachThread and PR_DetachThread.
  212.      * The primordial thread waits for this new thread to finish.
  213.      */
  214.  
  215. #ifdef _PR_PTHREADS
  216.  
  217.     rv = PTHREAD_ATTR_INIT(&attr);
  218.     if (debug_mode) PR_ASSERT(0 == rv);
  219.     else if (0 != rv) {
  220.         failed_already=1;
  221.         goto exit_now;
  222.     }
  223.     
  224. #ifndef _PR_DCETHREADS
  225.     rv = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
  226.     if (debug_mode) PR_ASSERT(0 == rv);
  227.     else if (0 != rv) {
  228.         failed_already=1;
  229.         goto exit_now;
  230.     }
  231. #endif  /* !_PR_DCETHREADS */
  232.     rv = PTHREAD_CREATE(&threadID, attr, threadStartFunc, NULL);
  233.     if (rv != 0) {
  234.             fprintf(stderr, "thread creation failed: error code %d\n", rv);
  235.             failed_already=1;
  236.             goto exit_now;
  237.     }
  238.     else {
  239.         if (debug_mode)
  240.             printf ("thread creation succeeded \n");
  241.  
  242.     }
  243.     rv = PTHREAD_ATTR_DESTROY(&attr);
  244.     if (debug_mode) PR_ASSERT(0 == rv);
  245.     else if (0 != rv) {
  246.         failed_already=1;
  247.         goto exit_now;
  248.     }
  249.     rv = pthread_join(threadID, NULL);
  250.     if (debug_mode) PR_ASSERT(0 == rv);
  251.     else if (0 != rv) {
  252.         failed_already=1;
  253.         goto exit_now;
  254.     }
  255.  
  256. #elif defined(SOLARIS)
  257.  
  258.     rv = thr_create(NULL, 0, threadStartFunc, NULL, 0, &threadID);
  259.     if (rv != 0) {
  260.     if(!debug_mode) {
  261.         failed_already=1;
  262.         goto exit_now;
  263.     } else    
  264.         fprintf(stderr, "thread creation failed: error code %d\n", rv);
  265.     }
  266.     rv = thr_join(threadID, NULL, NULL);
  267.     if (debug_mode) PR_ASSERT(0 == rv);
  268.     else if (0 != rv)
  269.     {
  270.         failed_already=1;
  271.         goto exit_now;
  272.     }
  273.  
  274.  
  275. #elif defined(WIN32)
  276.  
  277.     hThread = (HANDLE) _beginthreadex(NULL, 0, threadStartFunc, NULL,
  278.             0, &threadID); 
  279.     if (hThread == 0) {
  280.         fprintf(stderr, "thread creation failed: error code %d\n",
  281.                 GetLastError());
  282.         failed_already=1;
  283.         goto exit_now;
  284.     }
  285.     rv = WaitForSingleObject(hThread, INFINITE);
  286.     if (debug_mode)PR_ASSERT(rv != WAIT_FAILED);
  287.     else if (rv != WAIT_FAILED) {
  288.         failed_already=1;
  289.         goto exit_now;
  290.     }
  291.  
  292. #elif defined(IRIX)
  293.  
  294.     threadID = sproc(threadStartFunc, PR_SALL, NULL);
  295.     if (threadID == -1) {
  296.  
  297.             fprintf(stderr, "thread creation failed: error code %d\n",
  298.                     errno);
  299.             failed_already=1;
  300.             goto exit_now;
  301.     
  302.     }
  303.     else {
  304.         if (debug_mode) 
  305.             printf ("thread creation succeeded \n");
  306.         goto exit_now;
  307.     }
  308.     rv = waitpid(threadID, NULL, 0);
  309.     if (debug_mode) PR_ASSERT(rv != -1);
  310.     else  if (rv != -1) {
  311.         failed_already=1;
  312.         goto exit_now;
  313.     }
  314.  
  315. #elif defined(OS2)
  316.  
  317.     threadID = (TID) _beginthread((void(* _Optlink)(void*))threadStartFunc, NULL,
  318.             32768, NULL); 
  319.     if (threadID == -1) {
  320.         fprintf(stderr, "thread creation failed: error code %d\n", errno);
  321.         failed_already=1;
  322.         goto exit_now;
  323.     }
  324.     rv = DosWaitThread(&threadID, DCWW_WAIT);
  325.     if (debug_mode)PR_ASSERT(rv == NO_ERROR);
  326.     else if (rv == NO_ERROR) {
  327.         failed_already=1;
  328.         goto exit_now;
  329.     }
  330.  
  331. #else
  332.     if (!debug_mode)
  333.         failed_already=1;
  334.     else    
  335.         printf("The attach test does not apply to this platform because\n"
  336.         "either this platform does not have native threads or the\n"
  337.         "test needs to be written for this platform.\n");
  338.     goto exit_now;
  339. #endif
  340.  
  341. exit_now:
  342.    if(failed_already)    
  343.         return 1;
  344.     else
  345.         return 0;
  346. }
  347.