nsprpub/pr/tests/sem.c

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/nsprpub/pr/tests/sem.c	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,209 @@
     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 +**
    1.11 +** Name: sem.c
    1.12 +**
    1.13 +** Description: Tests Semaphonre functions.
    1.14 +**
    1.15 +** Modification History:
    1.16 +** 20-May-97 AGarcia- Converted the test to accomodate the debug_mode flag.
    1.17 +**	         The debug mode will print all of the printfs associated with this test.
    1.18 +**			 The regress mode will be the default mode. Since the regress tool limits
    1.19 +**           the output to a one line status:PASS or FAIL,all of the printf statements
    1.20 +**			 have been handled with an if (debug_mode) statement.
    1.21 +** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to
    1.22 +**			recognize the return code from tha main program.
    1.23 +***********************************************************************/
    1.24 +
    1.25 +/***********************************************************************
    1.26 +** Includes
    1.27 +***********************************************************************/
    1.28 +/* Used to get the command line option */
    1.29 +#include "plgetopt.h"
    1.30 +
    1.31 +#include "nspr.h"
    1.32 +#include "prpriv.h"
    1.33 +
    1.34 +#include <stdio.h>
    1.35 +#include <stdlib.h>
    1.36 +#include <string.h>
    1.37 +
    1.38 +PRIntn failed_already=0;
    1.39 +PRIntn debug_mode;
    1.40 +
    1.41 +/* 
    1.42 +	Since we don't have stdin, stdout everywhere, we will fake 
    1.43 +	it with our in-memory buffers called stdin and stdout.
    1.44 +*/
    1.45 +
    1.46 +#define SBSIZE 1024
    1.47 +
    1.48 +#include "obsolete/prsem.h"
    1.49 +
    1.50 +static char stdinBuf[SBSIZE];
    1.51 +static char stdoutBuf[SBSIZE];
    1.52 +
    1.53 +static PRUintn stdinBufIdx = 0;
    1.54 +static PRUintn stdoutBufIdx = 0;
    1.55 +static PRStatus finalResult = PR_SUCCESS;
    1.56 +
    1.57 +
    1.58 +static size_t dread (PRUintn device, char *buf, size_t bufSize)
    1.59 +{
    1.60 +	PRUintn	i;
    1.61 +	
    1.62 +	/* during first read call, initialize the stdinBuf buffer*/
    1.63 +	if (stdinBufIdx == 0) {
    1.64 +		for (i=0; i<SBSIZE; i++)
    1.65 +			stdinBuf[i] = i;
    1.66 +	}
    1.67 +
    1.68 +	/* now copy data from stdinBuf to the given buffer upto bufSize */
    1.69 +	for (i=0; i<bufSize; i++) {
    1.70 +		if (stdinBufIdx == SBSIZE)
    1.71 +			break;
    1.72 +		buf[i] = stdinBuf[stdinBufIdx++];
    1.73 +	}
    1.74 +
    1.75 +	return i;
    1.76 +}
    1.77 +
    1.78 +static size_t dwrite (PRUintn device, char *buf, size_t bufSize)
    1.79 +{
    1.80 +	PRUintn	i, j;
    1.81 +	
    1.82 +	/* copy data from the given buffer upto bufSize to stdoutBuf */
    1.83 +	for (i=0; i<bufSize; i++) {
    1.84 +		if (stdoutBufIdx == SBSIZE)
    1.85 +			break;
    1.86 +		stdoutBuf[stdoutBufIdx++] = buf[i];
    1.87 +	}
    1.88 +
    1.89 +	/* during last write call, compare the two buffers */
    1.90 +	if (stdoutBufIdx == SBSIZE)
    1.91 +		for (j=0; j<SBSIZE; j++)
    1.92 +			if (stdinBuf[j] != stdoutBuf[j]) {
    1.93 +				if (debug_mode) printf("data mismatch for index= %d \n", j);
    1.94 +				finalResult = PR_FAILURE;
    1.95 +			}
    1.96 +
    1.97 +	return i;
    1.98 +}
    1.99 +
   1.100 +/*------------------ Following is the real test program ---------*/
   1.101 +/*
   1.102 +	Program to copy standard input to standard output.  The program
   1.103 +	uses two threads.  One reads the input and puts the data in a 
   1.104 +	double buffer.  The other reads the buffer contents and writes 
   1.105 +	it to standard output.
   1.106 +*/
   1.107 +
   1.108 +PRSemaphore	*emptyBufs;	/* number of empty buffers */
   1.109 +PRSemaphore *fullBufs;	/* number of buffers that are full */
   1.110 +
   1.111 +#define BSIZE	100
   1.112 +
   1.113 +struct {
   1.114 +	char data[BSIZE];
   1.115 +	PRUintn nbytes;		/* number of bytes in this buffer */
   1.116 +} buf[2];
   1.117 +
   1.118 +static void PR_CALLBACK reader(void *arg)
   1.119 +{
   1.120 +	PRUintn	i = 0;
   1.121 +	size_t	nbytes;
   1.122 +	
   1.123 +	do {
   1.124 +		(void) PR_WaitSem(emptyBufs);
   1.125 +		nbytes = dread(0, buf[i].data, BSIZE);
   1.126 +		buf[i].nbytes = nbytes;
   1.127 +		PR_PostSem(fullBufs);
   1.128 +		i = (i + 1) % 2;
   1.129 +	} while (nbytes > 0);
   1.130 +}
   1.131 +
   1.132 +static void writer(void)
   1.133 +{
   1.134 +	PRUintn	i = 0;
   1.135 +	size_t	nbytes;
   1.136 +	
   1.137 +	do {
   1.138 +		(void) PR_WaitSem(fullBufs);
   1.139 +		nbytes = buf[i].nbytes;
   1.140 +		if (nbytes > 0) {
   1.141 +			nbytes = dwrite(1, buf[i].data, nbytes);
   1.142 +			PR_PostSem(emptyBufs);
   1.143 +			i = (i + 1) % 2;
   1.144 +		}
   1.145 +	} while (nbytes > 0);
   1.146 +}
   1.147 +
   1.148 +int main(int argc, char **argv)
   1.149 +{
   1.150 +	PRThread *r;
   1.151 +
   1.152 +    PR_STDIO_INIT();
   1.153 +    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
   1.154 +
   1.155 +    {
   1.156 +    	/* The command line argument: -d is used to determine if the test is being run
   1.157 +    	in debug mode. The regress tool requires only one line output:PASS or FAIL.
   1.158 +    	All of the printfs associated with this test has been handled with a if (debug_mode)
   1.159 +    	test.
   1.160 +    	Usage: test_name -d
   1.161 +    	*/
   1.162 +    	PLOptStatus os;
   1.163 +    	PLOptState *opt = PL_CreateOptState(argc, argv, "d:");
   1.164 +    	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
   1.165 +        {
   1.166 +    		if (PL_OPT_BAD == os) continue;
   1.167 +            switch (opt->option)
   1.168 +            {
   1.169 +            case 'd':  /* debug mode */
   1.170 +    			debug_mode = 1;
   1.171 +                break;
   1.172 +             default:
   1.173 +                break;
   1.174 +            }
   1.175 +        }
   1.176 +    	PL_DestroyOptState(opt);
   1.177 +    }        
   1.178 +
   1.179 + /* main test */
   1.180 +
   1.181 +    emptyBufs = PR_NewSem(2);	/* two empty buffers */
   1.182 +
   1.183 +    fullBufs = PR_NewSem(0);	/* zero full buffers */
   1.184 +
   1.185 +	/* create the reader thread */
   1.186 +	
   1.187 +	r = PR_CreateThread(PR_USER_THREAD,
   1.188 +				      reader, 0, 
   1.189 +				      PR_PRIORITY_NORMAL,
   1.190 +				      PR_LOCAL_THREAD,
   1.191 +    				  PR_UNJOINABLE_THREAD,
   1.192 +				      0);
   1.193 +
   1.194 +	/* Do the writer operation in this thread */
   1.195 +	writer();
   1.196 +
   1.197 +	PR_DestroySem(emptyBufs);
   1.198 +	PR_DestroySem(fullBufs);
   1.199 +
   1.200 +	if (finalResult == PR_SUCCESS) {
   1.201 +		if (debug_mode) printf("sem Test Passed.\n");
   1.202 +	}
   1.203 +	else{
   1.204 +		if (debug_mode) printf("sem Test Failed.\n");
   1.205 +		failed_already=1;
   1.206 +	}
   1.207 +    PR_Cleanup();
   1.208 +	if(failed_already)	
   1.209 +		return 1;
   1.210 +	else
   1.211 +		return 0;
   1.212 +}

mercurial