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 +}