tor-browser

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

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 }