select2.c (8665B)
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: select2.c 9 ** 10 ** Description: Measure PR_Select and Empty_Select performance. 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 ***********************************************************************/ 22 23 /*********************************************************************** 24 ** Includes 25 ***********************************************************************/ 26 /* Used to get the command line option */ 27 #include "plgetopt.h" 28 #include "prttools.h" 29 #include "primpl.h" 30 31 #include <stdio.h> 32 #include <stdlib.h> 33 #include <string.h> 34 35 #define PORT 8000 36 #define DEFAULT_COUNT 10 37 PRInt32 count; 38 39 /*********************************************************************** 40 ** PRIVATE FUNCTION: Test_Result 41 ** DESCRIPTION: Used in conjunction with the regress tool, prints out the 42 ** status of the test case. 43 ** INPUTS: PASS/FAIL 44 ** OUTPUTS: None 45 ** RETURN: None 46 ** SIDE EFFECTS: 47 ** 48 ** RESTRICTIONS: 49 ** None 50 ** MEMORY: NA 51 ** ALGORITHM: Determine what the status is and print accordingly. 52 ** 53 ***********************************************************************/ 54 55 static void Test_Result(int result) { 56 switch (result) { 57 case PASS: 58 printf("PASS\n"); 59 break; 60 case FAIL: 61 printf("FAIL\n"); 62 break; 63 default: 64 printf("NOSTATUS\n"); 65 break; 66 } 67 } 68 69 static void EmptyPRSelect(void) { 70 PRInt32 index = count; 71 PRInt32 rv; 72 73 for (; index--;) { 74 rv = PR_Select(0, NULL, NULL, NULL, PR_INTERVAL_NO_WAIT); 75 } 76 } 77 78 static void EmptyNativeSelect(void) { 79 PRInt32 rv; 80 PRInt32 index = count; 81 struct timeval timeout; 82 83 timeout.tv_sec = timeout.tv_usec = 0; 84 for (; index--;) { 85 rv = select(0, NULL, NULL, NULL, &timeout); 86 } 87 } 88 89 static void PRSelectTest(void) { 90 PRFileDesc* listenSocket; 91 PRNetAddr serverAddr; 92 93 if ((listenSocket = PR_NewTCPSocket()) == NULL) { 94 if (debug_mode) { 95 printf("\tServer error creating listen socket\n"); 96 } 97 return; 98 } 99 100 memset(&serverAddr, 0, sizeof(PRNetAddr)); 101 serverAddr.inet.family = AF_INET; 102 serverAddr.inet.port = PR_htons(PORT); 103 serverAddr.inet.ip = PR_htonl(INADDR_ANY); 104 105 if (PR_Bind(listenSocket, &serverAddr) == PR_FAILURE) { 106 if (debug_mode) { 107 printf("\tServer error binding to server address\n"); 108 } 109 PR_Close(listenSocket); 110 return; 111 } 112 113 if (PR_Listen(listenSocket, 128) == PR_FAILURE) { 114 if (debug_mode) { 115 printf("\tServer error listening to server socket\n"); 116 } 117 PR_Close(listenSocket); 118 return; 119 } 120 if (debug_mode) { 121 printf("Listening on port %d\n", PORT); 122 } 123 124 { 125 PRFileDesc* newSock; 126 PRNetAddr rAddr; 127 PRInt32 loops = 0; 128 PR_fd_set rdset; 129 PRInt32 rv; 130 PRInt32 bytesRead; 131 char buf[11]; 132 133 loops++; 134 135 if (debug_mode) { 136 printf("Going into accept\n"); 137 } 138 139 newSock = PR_Accept(listenSocket, &rAddr, PR_INTERVAL_NO_TIMEOUT); 140 141 if (newSock) { 142 if (debug_mode) { 143 printf("Got connection!\n"); 144 } 145 } else { 146 if (debug_mode) { 147 printf("PR_Accept failed: error code %d\n", PR_GetError()); 148 } else { 149 Test_Result(FAIL); 150 } 151 } 152 153 PR_FD_ZERO(&rdset); 154 PR_FD_SET(newSock, &rdset); 155 156 if (debug_mode) { 157 printf("Going into select \n"); 158 } 159 160 rv = PR_Select(0, &rdset, 0, 0, PR_INTERVAL_NO_TIMEOUT); 161 162 if (debug_mode) { 163 printf("return from select is %d\n", rv); 164 } 165 166 if (PR_FD_ISSET(newSock, &rdset)) { 167 if (debug_mode) { 168 printf("I can't believe it- the socket is ready okay!\n"); 169 } 170 } else { 171 if (debug_mode) { 172 printf("Damn; the select test failed...\n"); 173 } else { 174 Test_Result(FAIL); 175 } 176 } 177 178 strcpy(buf, "XXXXXXXXXX"); 179 bytesRead = PR_Recv(newSock, buf, 10, 0, PR_INTERVAL_NO_TIMEOUT); 180 buf[10] = '\0'; 181 182 if (debug_mode) { 183 printf("Recv completed with %d bytes, %s\n", bytesRead, buf); 184 } 185 186 PR_Close(newSock); 187 } 188 } 189 190 #if defined(XP_UNIX) 191 192 static void NativeSelectTest(void) { 193 PRFileDesc* listenSocket; 194 PRNetAddr serverAddr; 195 196 if ((listenSocket = PR_NewTCPSocket()) == NULL) { 197 if (debug_mode) { 198 printf("\tServer error creating listen socket\n"); 199 } 200 return; 201 } 202 203 memset(&serverAddr, 0, sizeof(PRNetAddr)); 204 serverAddr.inet.family = AF_INET; 205 serverAddr.inet.port = PR_htons(PORT); 206 serverAddr.inet.ip = PR_htonl(INADDR_ANY); 207 208 if (PR_Bind(listenSocket, &serverAddr) == PR_FAILURE) { 209 if (debug_mode) { 210 printf("\tServer error binding to server address\n"); 211 } 212 PR_Close(listenSocket); 213 return; 214 } 215 216 if (PR_Listen(listenSocket, 128) == PR_FAILURE) { 217 if (debug_mode) { 218 printf("\tServer error listening to server socket\n"); 219 } 220 PR_Close(listenSocket); 221 return; 222 } 223 if (debug_mode) { 224 printf("Listening on port %d\n", PORT); 225 } 226 227 { 228 PRIntn osfd; 229 char buf[11]; 230 fd_set rdset; 231 PRNetAddr rAddr; 232 PRFileDesc* newSock; 233 struct timeval timeout; 234 PRInt32 bytesRead, rv, loops = 0; 235 236 loops++; 237 238 if (debug_mode) { 239 printf("Going into accept\n"); 240 } 241 242 newSock = PR_Accept(listenSocket, &rAddr, PR_INTERVAL_NO_TIMEOUT); 243 244 if (newSock) { 245 if (debug_mode) { 246 printf("Got connection!\n"); 247 } 248 } else { 249 if (debug_mode) { 250 printf("PR_Accept failed: error code %d\n", PR_GetError()); 251 } else { 252 Test_Result(FAIL); 253 } 254 } 255 256 osfd = PR_FileDesc2NativeHandle(newSock); 257 FD_ZERO(&rdset); 258 FD_SET(osfd, &rdset); 259 260 if (debug_mode) { 261 printf("Going into select \n"); 262 } 263 264 timeout.tv_sec = 2; 265 timeout.tv_usec = 0; 266 rv = select(osfd + 1, &rdset, NULL, NULL, &timeout); 267 268 if (debug_mode) { 269 printf("return from select is %d\n", rv); 270 } 271 272 if (FD_ISSET(osfd, &rdset)) { 273 if (debug_mode) { 274 printf("I can't believe it- the socket is ready okay!\n"); 275 } 276 } else { 277 if (debug_mode) { 278 printf("Damn; the select test failed...\n"); 279 } else { 280 Test_Result(FAIL); 281 } 282 } 283 284 strcpy(buf, "XXXXXXXXXX"); 285 bytesRead = PR_Recv(newSock, buf, 10, 0, PR_INTERVAL_NO_TIMEOUT); 286 buf[10] = '\0'; 287 288 if (debug_mode) { 289 printf("Recv completed with %d bytes, %s\n", bytesRead, buf); 290 } 291 292 PR_Close(newSock); 293 } 294 295 } /* NativeSelectTest */ 296 297 #endif /* defined(XP_UNIX) */ 298 299 /************************************************************************/ 300 301 static void Measure(void (*func)(void), const char* msg) { 302 PRIntervalTime start, stop; 303 double d; 304 PRInt32 tot; 305 306 start = PR_IntervalNow(); 307 (*func)(); 308 stop = PR_IntervalNow(); 309 310 d = (double)PR_IntervalToMicroseconds(stop - start); 311 tot = PR_IntervalToMilliseconds(stop - start); 312 313 if (debug_mode) { 314 printf("%40s: %6.2f usec avg, %d msec total\n", msg, d / count, tot); 315 } 316 } 317 318 int main(int argc, char** argv) { 319 /* The command line argument: -d is used to determine if the test is being run 320 in debug mode. The regress tool requires only one line output:PASS or FAIL. 321 All of the printfs associated with this test has been handled with a if 322 (debug_mode) test. Usage: test_name -d 323 */ 324 PLOptStatus os; 325 PLOptState* opt = PL_CreateOptState(argc, argv, "d:"); 326 while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) { 327 if (PL_OPT_BAD == os) { 328 continue; 329 } 330 switch (opt->option) { 331 case 'd': /* debug mode */ 332 debug_mode = 1; 333 break; 334 default: 335 break; 336 } 337 } 338 PL_DestroyOptState(opt); 339 340 /* main test */ 341 342 PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); 343 344 if (argc > 2) { 345 count = atoi(argv[2]); 346 } else { 347 count = DEFAULT_COUNT; 348 } 349 350 #if defined(XP_UNIX) 351 Measure(NativeSelectTest, "time to call 1 element select()"); 352 #endif 353 Measure(EmptyPRSelect, "time to call Empty PR_select()"); 354 Measure(EmptyNativeSelect, "time to call Empty select()"); 355 Measure(PRSelectTest, "time to call 1 element PR_select()"); 356 357 if (!debug_mode) { 358 Test_Result(NOSTATUS); 359 } 360 PR_Cleanup(); 361 }