Back to index

lightning-sunbird  0.9+nobinonly
select2.c
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is the Netscape Portable Runtime (NSPR).
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1998-2000
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either the GNU General Public License Version 2 or later (the "GPL"), or
00026  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037 
00038 /***********************************************************************
00039 **
00040 ** Name: select2.c
00041 **
00042 ** Description: Measure PR_Select and Empty_Select performance.
00043 **
00044 ** Modification History:
00045 ** 20-May-97 AGarcia- Converted the test to accomodate the debug_mode flag.
00046 **              The debug mode will print all of the printfs associated with this test.
00047 **                    The regress mode will be the default mode. Since the regress tool limits
00048 **           the output to a one line status:PASS or FAIL,all of the printf statements
00049 **                    have been handled with an if (debug_mode) statement. 
00050 ***********************************************************************/
00051 
00052 /***********************************************************************
00053 ** Includes
00054 ***********************************************************************/
00055 /* Used to get the command line option */
00056 #include "plgetopt.h"
00057 #include "prttools.h"
00058 #include "primpl.h"
00059 
00060 #include <stdio.h>
00061 #include <stdlib.h>
00062 #include <string.h>
00063 #if defined(OS2)
00064 #include <sys/time.h>
00065 #endif
00066 
00067 #define PORT 8000
00068 #define DEFAULT_COUNT 10
00069 PRInt32 count;
00070 
00071 
00072 /***********************************************************************
00073 ** PRIVATE FUNCTION:    Test_Result
00074 ** DESCRIPTION: Used in conjunction with the regress tool, prints out the
00075 **                          status of the test case.
00076 ** INPUTS:      PASS/FAIL
00077 ** OUTPUTS:     None
00078 ** RETURN:      None
00079 ** SIDE EFFECTS:
00080 **      
00081 ** RESTRICTIONS:
00082 **      None
00083 ** MEMORY:      NA
00084 ** ALGORITHM:   Determine what the status is and print accordingly.
00085 **      
00086 ***********************************************************************/
00087 
00088 
00089 static void Test_Result (int result)
00090 {
00091        switch (result)
00092        {
00093               case PASS:
00094                      printf ("PASS\n");
00095                      break;
00096               case FAIL:
00097                      printf ("FAIL\n");
00098                      break;
00099               default:
00100                      printf ("NOSTATUS\n");
00101                      break;
00102        }
00103 }
00104 
00105 static void EmptyPRSelect(void)
00106 {
00107     PRInt32 index = count;
00108     PRInt32 rv;
00109 
00110     for (; index--;)
00111         rv = PR_Select(0, NULL, NULL, NULL, PR_INTERVAL_NO_WAIT);
00112 }
00113 
00114 static void EmptyNativeSelect(void)
00115 {
00116     PRInt32 rv;
00117     PRInt32 index = count;
00118     struct timeval timeout;
00119 
00120     timeout.tv_sec = timeout.tv_usec = 0;
00121     for (; index--;)
00122         rv = select(0, NULL, NULL, NULL, &timeout);
00123 }
00124 
00125 static void PRSelectTest(void)
00126 {
00127     PRFileDesc *listenSocket;
00128     PRNetAddr serverAddr;
00129 
00130     if ( (listenSocket = PR_NewTCPSocket()) == NULL) {
00131         if (debug_mode) printf("\tServer error creating listen socket\n");
00132         return;
00133     }
00134 
00135     memset(&serverAddr, 0, sizeof(PRNetAddr));
00136     serverAddr.inet.family = AF_INET;
00137     serverAddr.inet.port = PR_htons(PORT);
00138     serverAddr.inet.ip = PR_htonl(INADDR_ANY);
00139 
00140     if ( PR_Bind(listenSocket, &serverAddr) == PR_FAILURE) {
00141         if (debug_mode) printf("\tServer error binding to server address\n");
00142         PR_Close(listenSocket);
00143         return;
00144     }
00145 
00146     if ( PR_Listen(listenSocket, 128) == PR_FAILURE) {
00147         if (debug_mode) printf("\tServer error listening to server socket\n");
00148         PR_Close(listenSocket);
00149         return;
00150     }
00151     if (debug_mode) printf("Listening on port %d\n", PORT);
00152 
00153     {
00154         PRFileDesc *newSock;
00155         PRNetAddr rAddr;
00156         PRInt32 loops = 0;
00157         PR_fd_set rdset;
00158         PRInt32 rv;
00159         PRInt32 bytesRead;
00160         char buf[11];
00161 
00162         loops++;
00163 
00164         if (debug_mode) printf("Going into accept\n"); 
00165 
00166         newSock = PR_Accept(listenSocket, 
00167                               &rAddr,
00168                               PR_INTERVAL_NO_TIMEOUT);
00169 
00170        if (newSock) {
00171             if (debug_mode) printf("Got connection!\n");
00172         } else {
00173            if (debug_mode) printf("PR_Accept failed: error code %d\n", PR_GetError());
00174               else Test_Result (FAIL);
00175         }
00176 
00177         PR_FD_ZERO(&rdset);
00178         PR_FD_SET(newSock, &rdset);
00179 
00180         if (debug_mode) printf("Going into select \n");
00181 
00182         rv = PR_Select(0, &rdset, 0, 0, PR_INTERVAL_NO_TIMEOUT);
00183 
00184         if (debug_mode) printf("return from select is %d\n", rv);
00185 
00186         if (PR_FD_ISSET(newSock, &rdset)) {
00187             if (debug_mode) printf("I can't believe it- the socket is ready okay!\n");
00188         } else {
00189             if (debug_mode) printf("Damn; the select test failed...\n");
00190                      else Test_Result (FAIL);
00191         }
00192 
00193         strcpy(buf, "XXXXXXXXXX");
00194         bytesRead = PR_Recv(newSock, buf, 10, 0, PR_INTERVAL_NO_TIMEOUT);
00195        buf[10] = '\0';
00196 
00197         if (debug_mode) printf("Recv completed with %d bytes, %s\n", bytesRead, buf);
00198 
00199         PR_Close(newSock);
00200     }
00201 
00202 }
00203 
00204 #if defined(XP_UNIX)
00205 
00206 static void NativeSelectTest(void)
00207 {
00208     PRFileDesc *listenSocket;
00209     PRNetAddr serverAddr;
00210 
00211     if ( (listenSocket = PR_NewTCPSocket()) == NULL) {
00212         if (debug_mode) printf("\tServer error creating listen socket\n");
00213         return;
00214     }
00215 
00216     memset(&serverAddr, 0, sizeof(PRNetAddr));
00217     serverAddr.inet.family = AF_INET;
00218     serverAddr.inet.port = PR_htons(PORT);
00219     serverAddr.inet.ip = PR_htonl(INADDR_ANY);
00220 
00221     if ( PR_Bind(listenSocket, &serverAddr) == PR_FAILURE) {
00222         if (debug_mode) printf("\tServer error binding to server address\n");
00223         PR_Close(listenSocket);
00224         return;
00225     }
00226 
00227     if ( PR_Listen(listenSocket, 128) == PR_FAILURE) {
00228         if (debug_mode) printf("\tServer error listening to server socket\n");
00229         PR_Close(listenSocket);
00230         return;
00231     }
00232     if (debug_mode) printf("Listening on port %d\n", PORT);
00233 
00234     {
00235         PRIntn osfd;
00236         char buf[11];
00237         fd_set rdset;
00238         PRNetAddr rAddr;
00239         PRFileDesc *newSock;
00240         struct timeval timeout;
00241         PRInt32 bytesRead, rv, loops = 0;
00242 
00243         loops++;
00244 
00245         if (debug_mode) printf("Going into accept\n"); 
00246 
00247         newSock = PR_Accept(listenSocket, &rAddr, PR_INTERVAL_NO_TIMEOUT);
00248 
00249        if (newSock) {
00250             if (debug_mode) printf("Got connection!\n");
00251         } else {
00252            if (debug_mode) printf("PR_Accept failed: error code %d\n", PR_GetError());
00253               else Test_Result (FAIL);
00254         }
00255 
00256         osfd = PR_FileDesc2NativeHandle(newSock);
00257         FD_ZERO(&rdset);
00258         FD_SET(osfd, &rdset);
00259 
00260         if (debug_mode) printf("Going into select \n");
00261 
00262 
00263         timeout.tv_sec = 2; timeout.tv_usec = 0;
00264         rv = select(osfd + 1, &rdset, NULL, NULL, &timeout);
00265 
00266         if (debug_mode) printf("return from select is %d\n", rv);
00267 
00268         if (FD_ISSET(osfd, &rdset)) {
00269             if (debug_mode)
00270                 printf("I can't believe it- the socket is ready okay!\n");
00271         } else {
00272             if (debug_mode) printf("Damn; the select test failed...\n");
00273                      else Test_Result (FAIL);
00274         }
00275 
00276         strcpy(buf, "XXXXXXXXXX");
00277         bytesRead = PR_Recv(newSock, buf, 10, 0, PR_INTERVAL_NO_TIMEOUT);
00278        buf[10] = '\0';
00279 
00280         if (debug_mode) printf("Recv completed with %d bytes, %s\n", bytesRead, buf);
00281 
00282         PR_Close(newSock);
00283     }
00284 
00285 }  /* NativeSelectTest */
00286 
00287 #endif /* defined(XP_UNIX) */
00288 
00289 /************************************************************************/
00290 
00291 static void Measure(void (*func)(void), const char *msg)
00292 {
00293     PRIntervalTime start, stop;
00294     double d;
00295     PRInt32 tot;
00296 
00297     start = PR_IntervalNow();
00298     (*func)();
00299     stop = PR_IntervalNow();
00300 
00301     d = (double)PR_IntervalToMicroseconds(stop - start);
00302     tot = PR_IntervalToMilliseconds(stop-start);
00303 
00304     if (debug_mode) printf("%40s: %6.2f usec avg, %d msec total\n", msg, d / count, tot);
00305 }
00306 
00307 void main(int argc, char **argv)
00308 {
00309        
00310        /* The command line argument: -d is used to determine if the test is being run
00311        in debug mode. The regress tool requires only one line output:PASS or FAIL.
00312        All of the printfs associated with this test has been handled with a if (debug_mode)
00313        test.
00314        Usage: test_name -d
00315        */
00316        PLOptStatus os;
00317        PLOptState *opt = PL_CreateOptState(argc, argv, "d:");
00318        while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
00319     {
00320               if (PL_OPT_BAD == os) continue;
00321         switch (opt->option)
00322         {
00323         case 'd':  /* debug mode */
00324                      debug_mode = 1;
00325             break;
00326          default:
00327             break;
00328         }
00329     }
00330        PL_DestroyOptState(opt);
00331 
00332  /* main test */
00333        
00334     PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
00335     PR_STDIO_INIT();
00336 
00337     if (argc > 2) {
00338        count = atoi(argv[2]);
00339     } else {
00340        count = DEFAULT_COUNT;
00341     }
00342 
00343 #if defined(XP_UNIX)
00344     Measure(NativeSelectTest, "time to call 1 element select()");
00345 #endif
00346     Measure(EmptyPRSelect, "time to call Empty PR_select()");
00347     Measure(EmptyNativeSelect, "time to call Empty select()");
00348     Measure(PRSelectTest, "time to call 1 element PR_select()");
00349 
00350        if (!debug_mode) Test_Result (NOSTATUS);
00351     PR_Cleanup();
00352 
00353 
00354 }