home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / nsprpub / pr / tests / sem.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  6.0 KB  |  235 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. **
  21. ** Name: sem.c
  22. **
  23. ** Description: Tests Semaphonre functions.
  24. **
  25. ** Modification History:
  26. ** 20-May-97 AGarcia- Converted the test to accomodate the debug_mode flag.
  27. **             The debug mode will print all of the printfs associated with this test.
  28. **             The regress mode will be the default mode. Since the regress tool limits
  29. **           the output to a one line status:PASS or FAIL,all of the printf statements
  30. **             have been handled with an if (debug_mode) statement.
  31. ** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to
  32. **            recognize the return code from tha main program.
  33. ***********************************************************************/
  34.  
  35. /***********************************************************************
  36. ** Includes
  37. ***********************************************************************/
  38. /* Used to get the command line option */
  39. #include "plgetopt.h"
  40.  
  41. #include "nspr.h"
  42. #include "prpriv.h"
  43.  
  44. #include <stdio.h>
  45. #include <stdlib.h>
  46. #include <string.h>
  47.  
  48. PRIntn failed_already=0;
  49. PRIntn debug_mode;
  50.  
  51. /* 
  52.     Since we don't have stdin, stdout everywhere, we will fake 
  53.     it with our in-memory buffers called stdin and stdout.
  54. */
  55.  
  56. #define SBSIZE 1024
  57.  
  58. #ifdef XP_MAC
  59. #include "prlog.h"
  60. #include "prsem.h"
  61. #define printf PR_LogPrint
  62. extern void SetupMacPrintfLog(char *logFile);
  63. #else
  64. #include "obsolete/prsem.h"
  65. #endif
  66.  
  67. static char stdinBuf[SBSIZE];
  68. static char stdoutBuf[SBSIZE];
  69.  
  70. static PRUintn stdinBufIdx = 0;
  71. static PRUintn stdoutBufIdx = 0;
  72. static PRStatus finalResult = PR_SUCCESS;
  73.  
  74.  
  75. static size_t dread (PRUintn device, char *buf, size_t bufSize)
  76. {
  77.     PRUintn    i;
  78.     
  79.     /* during first read call, initialize the stdinBuf buffer*/
  80.     if (stdinBufIdx == 0) {
  81.         for (i=0; i<SBSIZE; i++)
  82.             stdinBuf[i] = i;
  83.     }
  84.  
  85.     /* now copy data from stdinBuf to the given buffer upto bufSize */
  86.     for (i=0; i<bufSize; i++) {
  87.         if (stdinBufIdx == SBSIZE)
  88.             break;
  89.         buf[i] = stdinBuf[stdinBufIdx++];
  90.     }
  91.  
  92.     return i;
  93. }
  94.  
  95. static size_t dwrite (PRUintn device, char *buf, size_t bufSize)
  96. {
  97.     PRUintn    i, j;
  98.     
  99.     /* copy data from the given buffer upto bufSize to stdoutBuf */
  100.     for (i=0; i<bufSize; i++) {
  101.         if (stdoutBufIdx == SBSIZE)
  102.             break;
  103.         stdoutBuf[stdoutBufIdx++] = buf[i];
  104.     }
  105.  
  106.     /* during last write call, compare the two buffers */
  107.     if (stdoutBufIdx == SBSIZE)
  108.         for (j=0; j<SBSIZE; j++)
  109.             if (stdinBuf[j] != stdoutBuf[j]) {
  110.                 if (debug_mode) printf("data mismatch for index= %d \n", j);
  111.                 finalResult = PR_FAILURE;
  112.             }
  113.  
  114.     return i;
  115. }
  116.  
  117. /*------------------ Following is the real test program ---------*/
  118. /*
  119.     Program to copy standard input to standard output.  The program
  120.     uses two threads.  One reads the input and puts the data in a 
  121.     double buffer.  The other reads the buffer contents and writes 
  122.     it to standard output.
  123. */
  124.  
  125. PRSemaphore    *emptyBufs;    /* number of empty buffers */
  126. PRSemaphore *fullBufs;    /* number of buffers that are full */
  127.  
  128. #define BSIZE    100
  129.  
  130. struct {
  131.     char data[BSIZE];
  132.     PRUintn nbytes;        /* number of bytes in this buffer */
  133. } buf[2];
  134.  
  135. static void PR_CALLBACK reader(void *arg)
  136. {
  137.     PRUintn    i = 0;
  138.     size_t    nbytes;
  139.     
  140.     do {
  141.         (void) PR_WaitSem(emptyBufs);
  142.         nbytes = dread(0, buf[i].data, BSIZE);
  143.         buf[i].nbytes = nbytes;
  144.         PR_PostSem(fullBufs);
  145.         i = (i + 1) % 2;
  146.     } while (nbytes > 0);
  147. }
  148.  
  149. static void writer(void)
  150. {
  151.     PRUintn    i = 0;
  152.     size_t    nbytes;
  153.     
  154.     do {
  155.         (void) PR_WaitSem(fullBufs);
  156.         nbytes = buf[i].nbytes;
  157.         if (nbytes > 0) {
  158.             nbytes = dwrite(1, buf[i].data, nbytes);
  159.             PR_PostSem(emptyBufs);
  160.             i = (i + 1) % 2;
  161.         }
  162.     } while (nbytes > 0);
  163. }
  164.  
  165. int main(int argc, char **argv)
  166. {
  167.     PRThread *r;
  168.  
  169.     PR_STDIO_INIT();
  170.     PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
  171.  
  172.     {
  173.         /* The command line argument: -d is used to determine if the test is being run
  174.         in debug mode. The regress tool requires only one line output:PASS or FAIL.
  175.         All of the printfs associated with this test has been handled with a if (debug_mode)
  176.         test.
  177.         Usage: test_name -d
  178.         */
  179.         PLOptStatus os;
  180.         PLOptState *opt = PL_CreateOptState(argc, argv, "d:");
  181.         while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
  182.         {
  183.             if (PL_OPT_BAD == os) continue;
  184.             switch (opt->option)
  185.             {
  186.             case 'd':  /* debug mode */
  187.                 debug_mode = 1;
  188.                 break;
  189.              default:
  190.                 break;
  191.             }
  192.         }
  193.         PL_DestroyOptState(opt);
  194.     }        
  195.  
  196.  /* main test */
  197.  
  198. #ifdef XP_MAC
  199.     SetupMacPrintfLog("sem.log");
  200.     debug_mode = 1;
  201. #endif
  202.  
  203.     emptyBufs = PR_NewSem(2);    /* two empty buffers */
  204.  
  205.     fullBufs = PR_NewSem(0);    /* zero full buffers */
  206.  
  207.     /* create the reader thread */
  208.     
  209.     r = PR_CreateThread(PR_USER_THREAD,
  210.                       reader, 0, 
  211.                       PR_PRIORITY_NORMAL,
  212.                       PR_LOCAL_THREAD,
  213.                       PR_UNJOINABLE_THREAD,
  214.                       0);
  215.  
  216.     /* Do the writer operation in this thread */
  217.     writer();
  218.  
  219.     PR_DestroySem(emptyBufs);
  220.     PR_DestroySem(fullBufs);
  221.  
  222.     if (finalResult == PR_SUCCESS) {
  223.         if (debug_mode) printf("sem Test Passed.\n");
  224.     }
  225.     else{
  226.         if (debug_mode) printf("sem Test Failed.\n");
  227.         failed_already=1;
  228.     }
  229.     PR_Cleanup();
  230.     if(failed_already)    
  231.         return 1;
  232.     else
  233.         return 0;
  234. }
  235.