tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

sem.c (5386B)


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