Home | History | Annotate | Download | only in src
      1 char    netlib_id[]="\
      2 @(#)netlib.c (c) Copyright 1993-2012 Hewlett-Packard Company. Version 2.6.0";
      3 
      4 
      5 /****************************************************************/
      6 /*                                                              */
      7 /*      netlib.c                                                */
      8 /*                                                              */
      9 /*      the common utility routines available to all...         */
     10 /*                                                              */
     11 /*      establish_control()     establish the control socket    */
     12 /*      calibrate_local_cpu()   do local cpu calibration        */
     13 /*      calibrate_remote_cpu()  do remote cpu calibration       */
     14 /*      send_request()          send a request to the remote    */
     15 /*      recv_response()         receive a response from remote  */
     16 /*      send_response()         send a response to the remote   */
     17 /*      recv_request()          recv a request from the remote  */
     18 /*      dump_request()          dump request contents           */
     19 /*      dump_response()         dump response contents          */
     20 /*      cpu_start()             start measuring cpu             */
     21 /*      cpu_stop()              stop measuring cpu              */
     22 /*      calc_cpu_util()         calculate the cpu utilization   */
     23 /*      calc_service_demand()   calculate the service demand    */
     24 /*      calc_thruput()          calulate the tput in units      */
     25 /*      calibrate()             really calibrate local cpu      */
     26 /*      identify_local()        print local host information    */
     27 /*      identify_remote()       print remote host information   */
     28 /*      format_number()         format the number (KB, MB,etc)  */
     29 /*      format_units()          return the format in english    */
     30 /*      msec_sleep()            sleep for some msecs            */
     31 /*      start_timer()           start a timer                   */
     32 /*      random_ip_address()     select a random IP address from */
     33 /*                              specified range                 */
     34 /*                                                              */
     35 /*      the routines you get when WANT_DLPI is defined...       */
     36 /*      ...all moved to src/nettest_dlpi.c                      */
     37 /*                                                              */
     38 /*      dl_open()               open a file descriptor and      */
     39 /*                              attach to the card              */
     40 /*      dl_mtu()                find the MTU of the card        */
     41 /*      dl_bind()               bind the sap do the card        */
     42 /*      dl_connect()            sender's have of connect        */
     43 /*      dl_accpet()             receiver's half of connect      */
     44 /*      dl_set_window()         set the window size             */
     45 /*      dl_stats()              retrieve statistics             */
     46 /*      dl_send_disc()          initiate disconnect (sender)    */
     47 /*      dl_recv_disc()          accept disconnect (receiver)    */
     48 /****************************************************************/
     49 
     50 /****************************************************************/
     51 /*                                                              */
     52 /*      Global include files                                    */
     53 /*                                                              */
     54 /****************************************************************/
     55 
     56 #ifdef HAVE_CONFIG_H
     57 #include <config.h>
     58 #endif
     59 
     60  /* It would seem that most of the includes being done here from
     61     "sys/" actually have higher-level wrappers at just /usr/include.
     62     This is based on a spot-check of a couple systems at my disposal.
     63     If you have trouble compiling you may want to add "sys/" raj
     64     10/95 */
     65 #include <limits.h>
     66 #include <signal.h>
     67 #ifdef HAVE_SYSCALL_H
     68 #include <syscall.h>
     69 #endif
     70 #ifdef MPE
     71 #  define NSIG _NSIG
     72 #endif /* MPE */
     73 #include <sys/types.h>
     74 #include <fcntl.h>
     75 #include <stdio.h>
     76 #include <stdlib.h>
     77 #include <math.h>
     78 #include <string.h>
     79 #include <assert.h>
     80 #ifdef HAVE_ENDIAN_H
     81 #include <endian.h>
     82 #endif
     83 
     84 
     85 #ifndef WIN32
     86  /* at some point, I would like to get rid of all these "sys/"
     87     includes where appropriate. if you have a system that requires/
     88     them, speak now, or your system may not compile later revisions of
     89     netperf. raj 1/96 */
     90 #include <unistd.h>
     91 #include <sys/stat.h>
     92 #include <sys/times.h>
     93 #ifndef MPE
     94 #include <time.h>
     95 #include <sys/time.h>
     96 #endif /* MPE */
     97 #include <sys/socket.h>
     98 #include <netinet/in.h>
     99 #include <arpa/inet.h>
    100 #include <netdb.h>
    101 #include <errno.h>
    102 #include <sys/utsname.h>
    103 #if !defined(MPE) && !defined(__VMS)
    104 #include <sys/param.h>
    105 #endif /* MPE */
    106 
    107 #else /* WIN32 */
    108 
    109 #include <process.h>
    110 #include <time.h>
    111 #include <winsock2.h>
    112 #define netperf_socklen_t socklen_t
    113 #include <windows.h>
    114 #include <mmsystem.h>
    115 /* the only time someone should need to define DONT_IPV6 in the
    116    "sources" file is if they are trying to compile on Windows 2000 or
    117    NT4 and I suspect this may not be their only problem :) */
    118 #ifndef DONT_IPV6
    119 #include <ws2tcpip.h>
    120 #endif
    121 
    122 #include <windows.h>
    123 
    124 #define SIGALRM (14)
    125 #define sleep(x) Sleep((x)*1000)
    126 
    127 #endif /* WIN32 */
    128 
    129 #ifdef HAVE_UNAME
    130 #include <sys/utsname.h>
    131 #endif
    132 
    133 #ifdef _AIX
    134 #include <sys/select.h>
    135 #include <sys/sched.h>
    136 #include <sys/pri.h>
    137 #define PRIORITY PRI_LOW
    138 #else/* _AIX */
    139 #ifdef __sgi
    140 #include <sys/prctl.h>
    141 #include <sys/schedctl.h>
    142 #define PRIORITY NDPLOMIN
    143 #endif /* __sgi */
    144 #endif /* _AIX */
    145 
    146 
    147 #ifdef HAVE_MPCTL
    148 #include <sys/mpctl.h>
    149 #endif
    150 
    151 #if !defined(HAVE_GETADDRINFO) || !defined(HAVE_GETNAMEINFO)
    152 # include "missing/getaddrinfo.h"
    153 #endif
    154 
    155 
    156 #include "hist.h"
    157 
    158 /****************************************************************/
    159 /*                                                              */
    160 /*      Local Include Files                                     */
    161 /*                                                              */
    162 /****************************************************************/
    163 #define NETLIB
    164 #include "netlib.h"
    165 #include "netsh.h"
    166 #include "netcpu.h"
    167 #include "netperf_version.h"
    168 
    169 /****************************************************************/
    170 /*                                                              */
    171 /*      Global constants, macros and variables                  */
    172 /*                                                              */
    173 /****************************************************************/
    174 
    175 #if defined(WIN32) || defined(__VMS)
    176 struct  timezone {
    177         int     dummy ;
    178         } ;
    179 #ifndef __VMS
    180 SOCKET     win_kludge_socket = INVALID_SOCKET;
    181 SOCKET     win_kludge_socket2 = INVALID_SOCKET;
    182 #endif /* __VMS */
    183 #endif /* WIN32 || __VMS */
    184 
    185 #ifndef LONG_LONG_MAX
    186 #define LONG_LONG_MAX 9223372036854775807LL
    187 #endif /* LONG_LONG_MAX */
    188 
    189  /* older versions of netperf knew about the HP kernel IDLE counter.
    190     this is now obsolete - in favor of either pstat(), times, or a
    191     process-level looper process. we also now require support for the
    192     "long" integer type. raj 4/95.  */
    193 
    194 int
    195   lib_num_loc_cpus,    /* the number of cpus in the system */
    196   lib_num_rem_cpus;    /* how many we think are in the remote */
    197 
    198 struct cpu_stats_struct
    199   lib_local_cpu_stats,
    200   lib_remote_cpu_stats;
    201 
    202 #define PAGES_PER_CHILD 2
    203 
    204 int     lib_use_idle;
    205 int     cpu_method;
    206 
    207 struct  timeval         time1, time2;
    208 struct  timezone        tz;
    209 float   lib_elapsed,
    210         lib_local_maxrate,
    211         lib_remote_maxrate;
    212 
    213 float   lib_local_per_cpu_util[MAXCPUS];
    214 int     lib_cpu_map[MAXCPUS];
    215 
    216 int     *request_array;
    217 int     *response_array;
    218 
    219 /* INVALID_SOCKET == INVALID_HANDLE_VALUE == (unsigned int)(~0) == -1 */
    220 SOCKET  netlib_control = INVALID_SOCKET;
    221 SOCKET  server_sock = INVALID_SOCKET;
    222 int     control_family = AF_UNSPEC;
    223 
    224 /* global variables to hold the value for processor affinity */
    225 int     local_proc_affinity = -1,remote_proc_affinity = -1;
    226 
    227 /* these are to allow netperf to be run easily through those evil,
    228    end-to-end breaking things known as firewalls */
    229 char local_data_port[10];
    230 char remote_data_port[10];
    231 
    232 char *local_data_address=NULL;
    233 char *remote_data_address=NULL;
    234 
    235 char *local_sysname, *remote_sysname;
    236 char *local_release, *remote_release;
    237 char *local_version, *remote_version;
    238 char *local_machine, *remote_machine;
    239 
    240 int local_data_family=AF_UNSPEC;
    241 int remote_data_family=AF_UNSPEC;
    242 
    243 char *netperf_version;
    244 
    245 enum netperf_output_modes netperf_output_mode = HUMAN;
    246 
    247 /* in the past, I was overlaying a structure on an array of ints. now
    248    I am going to have a "real" structure, and point an array of ints
    249    at it. the real structure will be forced to the same alignment as
    250    the type "double." this change will mean that pre-2.1 netperfs
    251    cannot be mixed with 2.1 and later. raj 11/95 */
    252 
    253 union   netperf_request_struct  netperf_request;
    254 union   netperf_response_struct netperf_response;
    255 
    256 FILE    *where;
    257 
    258 char    libfmt = '?';
    259 
    260 #ifdef WIN32
    261 HANDLE hAlarm = INVALID_HANDLE_VALUE;
    262 int timed_out=0;
    263 #endif
    264 
    265 int     times_up;
    266 
    267 #ifdef WIN32
    268  /* we use a getopt implementation from net.sources */
    269 /*
    270  * get option letter from argument vector
    271  */
    272 int
    273         opterr = 1,             /* should error messages be printed? */
    274         optind = 1,             /* index into parent argv vector */
    275         optopt;                 /* character checked for validity */
    276 char
    277         *optarg;                /* argument associated with option */
    278 
    279 #define EMSG    ""
    280 
    281 #endif /* WIN32 */
    282 
    283 static int measuring_cpu;
    284 int
    285 netlib_get_page_size(void) {
    286 
    287  /* not all systems seem to have the sysconf for page size. for
    288     those  which do not, we will assume that the page size is 8192
    289     bytes.  this should be more than enough to be sure that there is
    290     no page  or cache thrashing by looper processes on MP
    291     systems. otherwise  that's really just too bad - such systems
    292     should define  _SC_PAGE_SIZE - raj 4/95 */
    293 
    294 #ifndef _SC_PAGE_SIZE
    295 #ifdef WIN32
    296 
    297 SYSTEM_INFO SystemInfo;
    298 
    299  GetSystemInfo(&SystemInfo);
    300 
    301  return SystemInfo.dwPageSize;
    302 #else
    303  return(8192L);
    304 #endif  /* WIN32 */
    305 #else
    306  return(sysconf(_SC_PAGE_SIZE));
    307 #endif /* _SC_PAGE_SIZE */
    308 
    309 }
    310 
    311 
    312 
    314 #ifdef WANT_INTERVALS
    315 #ifdef WIN32
    316 HANDLE WinTimer;
    317 UINT timerRes;
    318 void stop_itimer()
    319 {
    320 	CancelWaitableTimer(WinTimer);
    321 	CloseHandle(WinTimer);
    322 	timeEndPeriod(timerRes);
    323 }
    324 #else
    325 static unsigned int usec_per_itvl;
    326 
    327 
    328 void
    329 stop_itimer()
    330 
    331 {
    332 
    333   struct itimerval new_interval;
    334   struct itimerval old_interval;
    335 
    336   new_interval.it_interval.tv_sec = 0;
    337   new_interval.it_interval.tv_usec = 0;
    338   new_interval.it_value.tv_sec = 0;
    339   new_interval.it_value.tv_usec = 0;
    340   if (setitimer(ITIMER_REAL,&new_interval,&old_interval) != 0) {
    341     /* there was a problem arming the interval timer */
    342     perror("netperf: setitimer");
    343     exit(1);
    344   }
    345   return;
    346 }
    347 #endif /* WIN32 */
    348 #endif /* WANT_INTERVALS */
    349 
    350 
    352 
    353 #ifdef WIN32
    355 static void
    356 error(char *pch)
    357 {
    358   if (!opterr) {
    359     return;             /* without printing */
    360     }
    361   fprintf(stderr, "%s: %s: %c\n",
    362           (NULL != program) ? program : "getopt", pch, optopt);
    363 }
    364 
    365 int
    366 getopt(int argc, char **argv, char *ostr)
    367 {
    368   static char *place = EMSG;    /* option letter processing */
    369   register char *oli;                   /* option letter list index */
    370 
    371   if (!*place) {
    372     /* update scanning pointer */
    373       if (optind >= argc || *(place = argv[optind]) != '-' || !*++place) {
    374         return EOF;
    375       }
    376     if (*place == '-') {
    377       /* found "--" */
    378         ++optind;
    379       place = EMSG ;    /* Added by shiva for Netperf */
    380         return EOF;
    381     }
    382   }
    383 
    384   /* option letter okay? */
    385   if ((optopt = (int)*place++) == (int)':'
    386       || !(oli = strchr(ostr, optopt))) {
    387     if (!*place) {
    388       ++optind;
    389     }
    390     error("illegal option");
    391     return BADCH;
    392   }
    393   if (*++oli != ':') {
    394     /* don't need argument */
    395     optarg = NULL;
    396     if (!*place)
    397       ++optind;
    398   } else {
    399     /* need an argument */
    400     if (*place) {
    401       optarg = place;           /* no white space */
    402     } else  if (argc <= ++optind) {
    403       /* no arg */
    404       place = EMSG;
    405       error("option requires an argument");
    406       return BADCH;
    407     } else {
    408       optarg = argv[optind];            /* white space */
    409     }
    410     place = EMSG;
    411     ++optind;
    412   }
    413   return optopt;                        /* return option letter */
    414 }
    415 #endif /* WIN32 */
    416 
    417 /*----------------------------------------------------------------------------
    418  * WIN32 implementation of perror, does not deal very well with WSA errors
    419  * The stdlib.h version of perror only deals with the ancient XENIX error codes.
    420  *
    421  * +*+SAF Why can't all WSA errors go through GetLastError?  Most seem to...
    422  *--------------------------------------------------------------------------*/
    423 
    424 #ifdef WIN32
    425 void PrintWin32Error(FILE *stream, LPSTR text)
    426 {
    427     LPSTR    szTemp;
    428     DWORD    dwResult;
    429     DWORD    dwError;
    430 
    431     dwError = GetLastError();
    432     dwResult = FormatMessage(
    433         FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM |FORMAT_MESSAGE_ARGUMENT_ARRAY,
    434         NULL,
    435         dwError,
    436         LANG_NEUTRAL,
    437         (LPTSTR)&szTemp,
    438         0,
    439         NULL );
    440 
    441     if (dwResult)
    442         fprintf(stream, "%s: %s\n", text, szTemp);
    443     else
    444         fprintf(stream, "%s: error 0x%x\n", text, dwError);
    445 	fflush(stream);
    446 
    447     if (szTemp)
    448         LocalFree((HLOCAL)szTemp);
    449 }
    450 #endif /* WIN32 */
    451 
    452 char *
    453 nsec_enabled_to_str(int enabled) {
    454   switch (enabled) {
    455   case NSEC_UNKNOWN:
    456     return("Unknown");
    457   case NSEC_DISABLED:
    458     return("Disabled");
    459   case NSEC_PERMISSIVE:
    460     return("Permissive");
    461   case NSEC_ENFORCING:
    462     return("Enforcing");
    463   default:
    464     return("UNKNOWN MODE");
    465   }
    466 }
    467 
    468 char * nsec_type_to_str(int type) {
    469   switch (type) {
    470   case NSEC_TYPE_UNKNOWN:
    471     return("Unknown");
    472   case NSEC_TYPE_SELINUX:
    473     return("SELinux");
    474   default:
    475     return("UNKNOWN TYPE");
    476   }
    477 }
    478 
    479 
    480 char *
    482 inet_ttos(int type)
    483 {
    484   switch (type) {
    485   case SOCK_DGRAM:
    486     return("SOCK_DGRAM");
    487     break;
    488   case SOCK_STREAM:
    489     return("SOCK_STREAM");
    490     break;
    491 #ifdef SOCK_DCCP
    492   case SOCK_DCCP:
    493     return("SOCK_DCCP");
    494 #endif
    495 #ifdef SOCK_SEQPACKET
    496   case SOCK_SEQPACKET:
    497     return("SOCK_SEQPACKET");
    498 #endif
    499   default:
    500     return("SOCK_UNKNOWN");
    501   }
    502 }
    503 
    504 
    505 
    506 
    508 char unknown[32];
    509 
    510 char *
    511 inet_ptos(int protocol) {
    512   switch (protocol) {
    513   case IPPROTO_TCP:
    514     return("IPPROTO_TCP");
    515     break;
    516   case IPPROTO_UDP:
    517     return("IPPROTO_UDP");
    518     break;
    519 #if defined(IPPROTO_SCTP)
    520   case IPPROTO_SCTP:
    521     return("IPPROTO_SCTP");
    522     break;
    523 #endif
    524 #if defined(IPPROTO_DCCP)
    525   case IPPROTO_DCCP:
    526     return "IPPROTO_DCCP";
    527     break;
    528 #endif
    529 #if defined(IPPROTO_UDPLITE)
    530   case IPPROTO_UDPLITE:
    531     return "IPPROTO_UDPLITE";
    532     break;
    533 #endif
    534   default:
    535     snprintf(unknown,sizeof(unknown),"IPPROTO_UNKNOWN(%d)",protocol);
    536     return(unknown);
    537   }
    538 }
    539 
    540 /* one of these days, this should not be required */
    541 #ifndef AF_INET_SDP
    542 #define AF_INET_SDP 27
    543 #define PF_INET_SDP AF_INET_SDP
    544 #endif
    545 
    546 char *
    547 inet_ftos(int family)
    548 {
    549   switch(family) {
    550   case AF_INET:
    551     return("AF_INET");
    552 #if defined(AF_INET6)
    553   case AF_INET6:
    554     return("AF_INET6");
    555 #endif
    556 #if defined(AF_INET_SDP)
    557   case AF_INET_SDP:
    558     return("AF_INET_SDP");
    559 #endif
    560 #if defined(AF_RDS)
    561   case AF_RDS:
    562     return("AF_RDS");
    563 #endif
    564   default:
    565     return("AF_UNSPEC");
    566   }
    567 }
    568 
    569 int
    570 inet_nton(int af, const void *src, char *dst, int cnt)
    571 
    572 {
    573 
    574   switch (af) {
    575   case AF_INET:
    576     /* magic constants again... :) */
    577     if (cnt >= 4) {
    578       memcpy(dst,src,4);
    579       return 4;
    580     }
    581     else {
    582       Set_errno(ENOSPC);
    583       return(-1);
    584     }
    585     break;
    586 #if defined(AF_INET6)
    587   case AF_INET6:
    588     if (cnt >= 16) {
    589       memcpy(dst,src,16);
    590       return(16);
    591     }
    592     else {
    593       Set_errno(ENOSPC);
    594       return(-1);
    595     }
    596     break;
    597 #endif
    598 #if defined(AF_RDS)
    599   case AF_RDS:
    600     if (cnt >= 4) {
    601       memcpy(dst,src,4);
    602       return 4;
    603     }
    604 #endif
    605   default:
    606     Set_errno(EAFNOSUPPORT);
    607     return(-1);
    608   }
    609 }
    610 
    611 double
    612 ntohd(double net_double)
    613 
    614 {
    615   /* we rely on things being nicely packed */
    616   union {
    617     double whole_thing;
    618     unsigned int words[2];
    619     unsigned char bytes[8];
    620   } conv_rec;
    621 
    622   unsigned char scratch;
    623   int i;
    624 
    625   /* on those systems where ntohl is a no-op, we want to return the
    626      original value, unchanged */
    627 
    628   if (ntohl(1L) == 1L) {
    629     return(net_double);
    630   }
    631 
    632   conv_rec.whole_thing = net_double;
    633 
    634   /* we know that in the message passing routines that ntohl will have
    635      been called on the 32 bit quantities. we need to put those back
    636      the way they belong before we swap */
    637   conv_rec.words[0] = htonl(conv_rec.words[0]);
    638   conv_rec.words[1] = htonl(conv_rec.words[1]);
    639 
    640   /* now swap */
    641   for (i=0; i<= 3; i++) {
    642     scratch = conv_rec.bytes[i];
    643     conv_rec.bytes[i] = conv_rec.bytes[7-i];
    644     conv_rec.bytes[7-i] = scratch;
    645   }
    646 
    647 #if defined(__FLOAT_WORD_ORDER) && defined(__BYTE_ORDER)
    648   if (__FLOAT_WORD_ORDER != __BYTE_ORDER) {
    649     /* Fixup mixed endian floating point machines */
    650     unsigned int scratch = conv_rec.words[0];
    651     conv_rec.words[0] = conv_rec.words[1];
    652     conv_rec.words[1] = scratch;
    653   }
    654 #endif
    655 
    656   return(conv_rec.whole_thing);
    657 
    658 }
    659 
    660 double
    661 htond(double host_double)
    662 
    663 {
    664   /* we rely on things being nicely packed */
    665   union {
    666     double whole_thing;
    667     unsigned int words[2];
    668     unsigned char bytes[8];
    669   } conv_rec;
    670 
    671   unsigned char scratch;
    672   int i;
    673 
    674   /* on those systems where ntohl is a no-op, we want to return the
    675      original value, unchanged */
    676 
    677   if (ntohl(1L) == 1L) {
    678     return(host_double);
    679   }
    680 
    681   conv_rec.whole_thing = host_double;
    682 
    683   /* now swap */
    684   for (i=0; i<= 3; i++) {
    685     scratch = conv_rec.bytes[i];
    686     conv_rec.bytes[i] = conv_rec.bytes[7-i];
    687     conv_rec.bytes[7-i] = scratch;
    688   }
    689 
    690 #if defined(__FLOAT_WORD_ORDER) && defined(__BYTE_ORDER)
    691   if (__FLOAT_WORD_ORDER != __BYTE_ORDER) {
    692     /* Fixup mixed endian floating point machines */
    693     unsigned int scratch = conv_rec.words[0];
    694     conv_rec.words[0] = conv_rec.words[1];
    695     conv_rec.words[1] = scratch;
    696   }
    697 #endif
    698 
    699   /* we know that in the message passing routines htonl will be called
    700      on the 32 bit quantities. we need to set things up so that when
    701      this happens, the proper order will go out on the network */
    702   conv_rec.words[0] = htonl(conv_rec.words[0]);
    703   conv_rec.words[1] = htonl(conv_rec.words[1]);
    704 
    705   return(conv_rec.whole_thing);
    706 
    707 }
    708 
    709 
    710 
    712 /* The original patch from Google used lrand48, but I have been
    713    informed that is not easily available under Windows. So, rather
    714    than have some #ifdefs here I'll just simplistically replace
    715    lrand48 with rand(), which should be "good enough" at some point it
    716    may be sufficient to just call rand() directly rather than call
    717    this raj 20101130 */
    718 
    719 unsigned int
    720 rand32(){
    721   return (unsigned int)rand() * 2 + rand() % 2;
    722 }
    723 
    724 /* this routine will set the ip address of the sockaddr in the
    725    addrinfo to a random number in range, based on the address
    726    family. for grins, we will sanity check the value of mask_len
    727    against the address family. initial version from google,
    728    enhancements by raj 20101129 */
    729 void
    730 random_ip_address(struct addrinfo *res, int mask_len)
    731 {
    732   switch(res->ai_family) {
    733   case AF_INET: {
    734     struct sockaddr_in *foo = (struct sockaddr_in *)res->ai_addr;
    735     unsigned int addr = ntohl(foo->sin_addr.s_addr);
    736     unsigned int mask = ((unsigned int)1 << (32 - mask_len)) - 1;
    737 
    738     if ((mask_len < 0) || (mask_len > 32)) {
    739       fprintf(where,
    740 	      "Mask length must be between 0 and 32 inclusive for AF_INET\n");
    741       fflush(where);
    742       exit(-1);
    743     }
    744 
    745     addr = ntohl(foo->sin_addr.s_addr);
    746     do {
    747       addr = (addr & ~mask) | (rand32() & mask);
    748     } while ((addr & 0xff) == 0xff);
    749     foo->sin_addr.s_addr = htonl(addr);
    750     break;
    751   }
    752 #if defined(AF_INET6)
    753   case AF_INET6: {
    754     struct sockaddr_in6 *foo = (struct sockaddr_in6 *)res->ai_addr;
    755 
    756     unsigned int i, len;
    757     unsigned int *addr = (unsigned int *)&(foo->sin6_addr.s6_addr);
    758     unsigned int mask;
    759 
    760     if ((mask_len < 0) || (mask_len > 128)) {
    761       fprintf(where,
    762 	      "Mask length must be between 0 and 128 inclusive for AF_INET\n");
    763       fflush(where);
    764       exit(-1);
    765     }
    766 
    767     for (i = 0; i < 4; i ++){
    768       addr[i] = ntohl(addr[i]);
    769       len = mask_len - i * 32;
    770       len = ((len < 32) ? len : 32);
    771       len = ((len > 0) ? len : 0);
    772       mask = ((unsigned int)1 << (32 - len)) - 1;
    773       addr[i] = (addr[i] & ~mask) | (rand32() & mask);
    774       addr[i] = htonl(addr[i]);
    775      }
    776     break;
    777   }
    778 #endif
    779   default:
    780     fprintf(where,
    781             "Unexpected Address Family of %u\n",res->ai_family);
    782     fflush(where);
    783     exit(-1);
    784   }
    785 }
    786 
    787 #if defined(HAVE_SENDFILE)
    789 int netperf_sendfile(SOCKET send_socket, struct ring_elt *send_ring) {
    790 
    791   int  len;
    792   int  ret = 0;
    793 
    794 #if defined(__linux) || defined(__sun)
    795   off_t     scratch_offset;   /* the linux sendfile() call will update
    796 				 the offset variable, which is
    797 				 something we do _not_ want to happen
    798 				 to the value in the send_ring! so, we
    799 				 have to use a scratch variable. */
    800 #endif /* __linux  || defined(__sun) */
    801 
    802 #if defined (__sun)
    803    size_t  scratch_len;	/* the sun sendfilev() needs a place to
    804 			   tell us how many bytes were written,
    805 			   even though it also returns the value */
    806    sendfilevec_t sv;
    807 #endif /* __sun */
    808 
    809       /* you can look at netlib.h for a description of the fields we
    810 	 are passing to sendfile(). 08/2000 */
    811 #if defined(__linux)
    812       scratch_offset = send_ring->offset;
    813       len=sendfile(send_socket,
    814 		   send_ring->fildes,
    815 		   &scratch_offset,   /* modified after the call! */
    816 		   send_ring->length);
    817 #elif defined (__sun)
    818       /* We must call with SFV_NOWAIT and a large file size (>= 16MB)
    819 	 to get zero-copy, as well as compiling with
    820 	 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 */
    821       sv.sfv_fd = send_ring->fildes;
    822       sv.sfv_flag = SFV_NOWAIT;
    823       sv.sfv_off = send_ring->offset;
    824       sv.sfv_len =  send_ring->length;
    825       len = sendfilev(send_socket, &sv, 1, &scratch_len);
    826 #elif defined(__FreeBSD__)
    827       /* so close to HP-UX and yet so far away... :) */
    828       ret = sendfile(send_ring->fildes,
    829 		     send_socket,
    830 		     send_ring->offset,
    831 		     send_ring->length,
    832 		     NULL,
    833 		     (off_t *)&len,
    834 		     send_ring->flags);
    835 #elif defined(USE_OSX)
    836       len = send_ring->length;
    837       ret = sendfile(send_ring->fildes,
    838 		     send_socket,
    839 		     send_ring->offset,
    840 		     (off_t *)&len,
    841 		     NULL,
    842 		     send_ring->flags);
    843 #else /* original sendile HP-UX */
    844       len=sendfile(send_socket,
    845 		   send_ring->fildes,
    846 		   send_ring->offset,
    847 		   send_ring->length,
    848 		   send_ring->hdtrl,
    849 		   send_ring->flags);
    850 #endif
    851 
    852       /* for OSX and FreeBSD, a non-zero ret means something failed.
    853 	 I would hope that the length fields are set to -1 or the
    854 	 like, but at the moment I do not know I can count on
    855 	 that. for other platforms, ret will be set to zero and we can
    856 	 rely directly on len. raj 2013-05-01 */
    857       if (ret != 0)
    858 	return -1;
    859       else
    860 	return len;
    861 
    862 }
    863 #endif
    864 
    865 
    867 /* one of these days, this should be abstracted-out just like the CPU
    868    util stuff.  raj 2005-01-27 */
    869 int
    870 get_num_cpus()
    871 
    872 {
    873 
    874   /* on HP-UX, even when we use the looper procs we need the pstat */
    875   /* call */
    876 
    877   int temp_cpus;
    878 
    879 #ifdef __hpux
    880 #include <sys/pstat.h>
    881 
    882   struct pst_dynamic psd;
    883 
    884   if (pstat_getdynamic((struct pst_dynamic *)&psd,
    885                        (size_t)sizeof(psd), (size_t)1, 0) != -1) {
    886     temp_cpus = psd.psd_proc_cnt;
    887   }
    888   else {
    889     temp_cpus = 1;
    890   }
    891 
    892 #else
    893   /* MW: <unistd.h> was included for non-Windows systems above. */
    894   /* Thus if _SC_NPROC_ONLN is defined, we should be able to use sysconf. */
    895 #ifdef _SC_NPROCESSORS_ONLN
    896   temp_cpus = sysconf(_SC_NPROCESSORS_ONLN);
    897 
    898 #ifdef USE_PERFSTAT
    899   temp_cpus = perfstat_cpu(NULL,NULL, sizeof(perfstat_cpu_t), 0);
    900 #endif /* USE_PERFSTAT */
    901 
    902 #else /* no _SC_NPROCESSORS_ONLN */
    903 
    904 #ifdef WIN32
    905   SYSTEM_INFO SystemInfo;
    906   GetSystemInfo(&SystemInfo);
    907 
    908   temp_cpus = SystemInfo.dwNumberOfProcessors;
    909 #else
    910   /* we need to know some other ways to do this, or just fall-back on
    911      a global command line option - raj 4/95 */
    912   temp_cpus = shell_num_cpus;
    913 #endif  /* WIN32 */
    914 #endif /* _SC_NPROCESSORS_ONLN */
    915 #endif /*  __hpux */
    916 
    917   if (temp_cpus > MAXCPUS) {
    918     fprintf(where,
    919             "Sorry, this system has more CPUs (%d) than I can handle (%d).\n"
    920             "Please alter MAXCPUS in netlib.h and recompile.\n",
    921             temp_cpus,
    922             MAXCPUS);
    923     fflush(where);
    924     exit(1);
    925   }
    926 
    927   return(temp_cpus);
    928 
    929 }
    930 
    931 #ifdef WIN32
    932 #ifdef __GNUC__
    933   #define S64_SUFFIX(x) x##LL
    934 #else
    935   #define S64_SUFFIX(x) x##i64
    936 #endif
    937 
    938 /*
    939  * Number of 100 nanosecond units from 1/1/1601 to 1/1/1970
    940  */
    941 #define EPOCH_BIAS  S64_SUFFIX(116444736000000000)
    942 
    943 /*
    944  * Union to facilitate converting from FILETIME to unsigned __int64
    945  */
    946 typedef union {
    947         unsigned __int64 ft_scalar;
    948         FILETIME ft_struct;
    949 } FT;
    950 
    951 void
    952 gettimeofday( struct timeval *tv , struct timezone *not_used )
    953 {
    954         FT nt_time;
    955         __int64 UnixTime;  /* microseconds since 1/1/1970 */
    956 
    957         GetSystemTimeAsFileTime( &(nt_time.ft_struct) );
    958 
    959         UnixTime = ((nt_time.ft_scalar - EPOCH_BIAS) / S64_SUFFIX(10));
    960         tv->tv_sec = (long)(time_t)(UnixTime / S64_SUFFIX(1000000));
    961         tv->tv_usec = (unsigned long)(UnixTime % S64_SUFFIX(1000000));
    962 }
    963 #endif /* WIN32 */
    964 
    965 
    966  /* this routine will disable any running timer */
    968 void
    969 stop_timer()
    970 {
    971 #ifndef WIN32
    972   alarm(0);
    973 #else
    974   /* at some point we may need some win32 equivalent */
    975   if (hAlarm != (HANDLE) INVALID_HANDLE_VALUE) {
    976     SetEvent(hAlarm);
    977   }
    978 #endif /* WIN32 */
    979 
    980 }
    981 
    982 
    983 
    985 /************************************************************************/
    986 /*                                                                      */
    987 /*      signal catcher                                                  */
    988 /*                                                                      */
    989 /************************************************************************/
    990 #ifndef WIN32
    991 void
    992 #if defined(__hpux)
    993 catcher(sig, code, scp)
    994      int sig;
    995      int code;
    996      struct sigcontext *scp;
    997 #else
    998 catcher(int sig)
    999 #endif /* __hpux || __VMS */
   1000 {
   1001 
   1002 #ifdef __hpux
   1003   if (debug > 2) {
   1004     fprintf(where,"caught signal %d ",sig);
   1005     if (scp) {
   1006       fprintf(where,"while in syscall %d\n",
   1007               scp->sc_syscall);
   1008     }
   1009     else {
   1010       fprintf(where,"null scp\n");
   1011     }
   1012     fflush(where);
   1013   }
   1014 #endif /* RAJ_DEBUG */
   1015 
   1016   switch(sig) {
   1017 
   1018   case SIGINT:
   1019     times_up = 1;
   1020     break;
   1021   case SIGALRM:
   1022    if (--test_len_ticks == 0) {
   1023       /* the test is over */
   1024       if (times_up != 0) {
   1025         fprintf(where,"catcher: timer popped with times_up != 0\n");
   1026         fflush(where);
   1027       }
   1028       times_up = 1;
   1029 #if defined(WANT_INTERVALS) && !defined(WANT_SPIN)
   1030       stop_itimer();
   1031       /* we should also stop the normal test timer lest it fire at an
   1032 	 inopportune moment - we do not know if we got here off the
   1033 	 interval timer or the test timer... */
   1034       stop_timer();
   1035 #endif /* WANT_INTERVALS */
   1036       break;
   1037     }
   1038     else {
   1039 #ifdef WANT_INTERVALS
   1040 #ifdef __hpux
   1041       /* the test is not over yet and we must have been using the
   1042 	 interval timer. if we were in SYS_SIGSUSPEND we want to
   1043 	 re-start the system call. Otherwise, we want to get out of
   1044 	 the sigsuspend call. I NEED TO KNOW HOW TO DO THIS FOR OTHER
   1045 	 OPERATING SYSTEMS. If you know how, please let me know. rick
   1046 	 jones <rick.jones2 (at) hp.com> */
   1047       if (scp->sc_syscall != SYS_SIGSUSPEND) {
   1048         if (debug > 2) {
   1049           fprintf(where,
   1050                   "catcher: Time to send burst > interval!\n");
   1051           fflush(where);
   1052         }
   1053         scp->sc_syscall_action = SIG_RESTART;
   1054       }
   1055 #endif /* __hpux */
   1056 #else /* WANT_INTERVALS */
   1057       fprintf(where,
   1058               "catcher: interval timer running unexpectedly!\n");
   1059       fflush(where);
   1060       times_up = 1;
   1061 #endif /* WANT_INTERVALS */
   1062       break;
   1063     }
   1064   }
   1065   return;
   1066 }
   1067 #endif /* WIN32 */
   1068 
   1069 void
   1070 install_signal_catchers()
   1071 
   1072 {
   1073   /* just a simple little routine to catch a bunch of signals */
   1074 
   1075 #ifndef WIN32
   1076   struct sigaction action;
   1077   int i;
   1078 
   1079   fprintf(where,"installing catcher for all signals\n");
   1080   fflush(where);
   1081 
   1082   sigemptyset(&(action.sa_mask));
   1083   action.sa_handler = catcher;
   1084 
   1085 #ifdef SA_INTERRUPT
   1086   action.sa_flags = SA_INTERRUPT;
   1087 #else /* SA_INTERRUPT */
   1088   action.sa_flags = 0;
   1089 #endif /* SA_INTERRUPT */
   1090 
   1091 
   1092   for (i = 1; i <= NSIG; i++) {
   1093     switch (i) {
   1094     case SIGALRM:
   1095     case SIGPROF:
   1096     case SIGSTOP:
   1097     case SIGKILL:
   1098       break;
   1099     default:
   1100       if (sigaction(i,&action,NULL) != 0) {
   1101         fprintf(where,
   1102                 "Could not install signal catcher for sig %d, errno %d\n",
   1103                 i,
   1104                 errno);
   1105         fflush(where);
   1106 
   1107       }
   1108     }
   1109   }
   1110 #else
   1111   return;
   1112 #endif /* WIN32 */
   1113 }
   1114 
   1115 
   1117 #ifdef WIN32
   1118 #define SIGALRM (14)
   1119 void
   1120 emulate_alarm( int seconds )
   1121 {
   1122   DWORD ErrorCode;
   1123   DWORD HandlesClosedFlags = 0;
   1124 
   1125   /* Wait on this event for parm seconds. */
   1126 
   1127   ErrorCode = WaitForSingleObject(hAlarm, seconds*1000);
   1128   if (ErrorCode == WAIT_FAILED)
   1129     {
   1130       perror("WaitForSingleObject failed");
   1131       exit(1);
   1132     }
   1133 
   1134   if (ErrorCode == WAIT_TIMEOUT)
   1135     {
   1136       /* WaitForSingleObject timed out; this means the timer
   1137 	 wasn't canceled. */
   1138 
   1139       times_up = 1;
   1140 
   1141       /* Give the other threads time to notice that times_up has
   1142 	 changed state before taking the harsh step of closing the
   1143 	 sockets. */
   1144       timed_out=0;
   1145       if (WaitForSingleObject(hAlarm, PAD_TIME/2*1000) ==
   1146 	  WAIT_TIMEOUT) {
   1147         timed_out=1;
   1148 	/* We have yet to find a good way to fully emulate
   1149 	   the effects of signals and getting EINTR from
   1150 	   system calls under winsock, so what we do here is
   1151 	   close the socket out from under the other thread.
   1152 	   It is rather kludgy, but should be sufficient to
   1153 	   get this puppy shipped.  The concept can be
   1154 	   attributed/blamed :) on Robin raj 1/96 */
   1155 
   1156 	if (win_kludge_socket != INVALID_SOCKET) {
   1157 	  HandlesClosedFlags |= 1;
   1158 	  closesocket(win_kludge_socket);
   1159 	}
   1160 	if (win_kludge_socket2 != INVALID_SOCKET) {
   1161 	  HandlesClosedFlags |= 2;
   1162 	  closesocket(win_kludge_socket2);
   1163 	}
   1164       }
   1165       if(debug) {
   1166 	fprintf(where,
   1167 		"emulate_alarm - HandlesClosedFlags: %x\n",
   1168 		HandlesClosedFlags);
   1169 	fflush(where);
   1170       }
   1171     }
   1172 }
   1173 
   1174 
   1175 #endif /* WIN32 */
   1176 
   1177 void
   1178 start_timer(int time)
   1179 {
   1180 
   1181 #ifdef WIN32
   1182   /*+*+SAF What if StartTimer is called twice without the first timer */
   1183   /*+*+SAF expiring? */
   1184 
   1185   DWORD  thread_id ;
   1186   HANDLE tHandle;
   1187 
   1188   if (hAlarm == (HANDLE) INVALID_HANDLE_VALUE)
   1189     {
   1190       /* Create the Alarm event object */
   1191       hAlarm = CreateEvent(
   1192 			   (LPSECURITY_ATTRIBUTES) NULL, /* no security */
   1193 			   FALSE,	 /* auto reset event */
   1194 			   FALSE,   /* init. state = reset */
   1195 			   (void *)NULL);  /* unnamed event object */
   1196       if (hAlarm == (HANDLE) INVALID_HANDLE_VALUE)
   1197 	{
   1198 	  perror("CreateEvent failure");
   1199 	  exit(1);
   1200 	}
   1201     }
   1202   else
   1203     {
   1204       ResetEvent(hAlarm);
   1205     }
   1206 
   1207 
   1208   tHandle = CreateThread(0,
   1209 			 0,
   1210 			 (LPTHREAD_START_ROUTINE)emulate_alarm,
   1211 			 (LPVOID)(ULONG_PTR)time,
   1212 			 0,
   1213 			 &thread_id ) ;
   1214   CloseHandle(tHandle);
   1215 
   1216 #else /* not WIN32 */
   1217 
   1218 struct sigaction action;
   1219 int ret;
   1220 
   1221 if (debug) {
   1222   fprintf(where,"About to start a timer for %d seconds.\n",time);
   1223   fflush(where);
   1224 }
   1225 
   1226   action.sa_handler = catcher;
   1227 
   1228 #ifdef SA_INTERRUPT
   1229   /* on some systems (SunOS 4.blah), system calls are restarted. we do */
   1230   /* not want that */
   1231   action.sa_flags = SA_INTERRUPT;
   1232 #else /* SA_INTERRUPT */
   1233   action.sa_flags = 0;
   1234 #endif /* SA_INTERRUPT */
   1235 
   1236   sigemptyset(&(action.sa_mask));
   1237   sigaddset(&(action.sa_mask),SIGALRM);
   1238   if (sigaction(SIGALRM, &action, NULL) < 0) {
   1239     fprintf(where,
   1240 	    "start_timer: error installing alarm handler errno %d\n",
   1241 	    errno);
   1242     fflush(where);
   1243     exit(-1);
   1244   }
   1245 
   1246   sigemptyset(&(action.sa_mask));
   1247   sigaddset(&(action.sa_mask),SIGINT);
   1248   if (sigaction(SIGINT, &action, NULL) < 0) {
   1249     fprintf(where,
   1250 	    "start_timer: error installing SIGINT handler errno %d\n",
   1251 	    errno);
   1252     fflush(where);
   1253     exit(-1);
   1254   }
   1255 
   1256   /* this is the easy case - just set the timer for so many seconds */
   1257   ret = alarm(time);
   1258   if (ret != 0) {
   1259     fprintf(where,
   1260             "error starting alarm timer, ret %d errno %d\n",
   1261 	    ret,
   1262             errno);
   1263     fflush(where);
   1264     exit(-1);
   1265   }
   1266 #endif /* WIN32 */
   1267 
   1268   test_len_ticks = 1;
   1269 
   1270 }
   1271 
   1272 
   1273 
   1274 #ifdef WANT_INTERVALS
   1276 /* this routine will enable the interval timer and set things up so
   1277    that for a timed test the test will end at the proper time. it
   1278    should detect the presence of POSIX.4 timer_* routines one of these
   1279    days */
   1280 void
   1281 start_itimer(unsigned int interval_len_msec )
   1282 {
   1283 #ifdef WIN32
   1284     LARGE_INTEGER liDueTime;
   1285 	TIMECAPS ptc;
   1286 	MMRESULT mmr;
   1287 
   1288 	/* make sure timer resolution is at least as small as interval length */
   1289 	timerRes=interval_len_msec;
   1290 	mmr=timeGetDevCaps(&ptc, sizeof (ptc));
   1291 	if (mmr==TIMERR_NOERROR){
   1292 	  if (interval_len_msec<ptc.wPeriodMin){
   1293 		timerRes=ptc.wPeriodMin;
   1294 		fprintf(where, "Timer cannot be set to %dmsec.  Minimum timer resolution: %d\n", interval_len_msec, ptc.wPeriodMin);
   1295 		fflush(where);
   1296 	  }
   1297 	}
   1298 	/* timeBeginPeriod() affects a global Windows setting.
   1299 	Windows uses the lowest value (that is, highest resolution) requested by any process. */
   1300 	mmr=timeBeginPeriod(timerRes);
   1301 	/* Create a waitable timer. */
   1302     WinTimer = CreateWaitableTimer(NULL, FALSE, "IntervalTimer");
   1303     if (NULL == WinTimer)
   1304     {
   1305         fprintf(where, "CreateWaitableTimer failed (%d)\n", GetLastError());
   1306         fflush(where);
   1307 		exit(1);
   1308     }
   1309  	/*The time after which the state of the timer is to be set to signaled the first time,
   1310 	in 100 nanosecond intervals.  Negative values indicate relative time. */
   1311     liDueTime.QuadPart=-10000LL*interval_len_msec;
   1312    /* Set the timer to wait for interval_len_msec and periodically signal every interval_len_msec */
   1313     if (!SetWaitableTimer(WinTimer, &liDueTime, interval_len_msec, NULL, NULL, TRUE))
   1314     {
   1315         fprintf(where,"SetWaitableTimer failed (%d)\n", GetLastError());
   1316         fflush(where);
   1317 		exit(1);
   1318     }
   1319 #else
   1320   unsigned int ticks_per_itvl;
   1321 
   1322   struct itimerval new_interval;
   1323   struct itimerval old_interval;
   1324 
   1325   /* if -DWANT_INTERVALS was used, we will use the ticking of the
   1326      itimer to tell us when the test is over. while the user will be
   1327      specifying some number of milliseconds, we know that the interval
   1328      timer is really in units of 1/HZ. so, to prevent the test from
   1329      running "long" it would be necessary to keep this in mind when
   1330      calculating the number of itimer events */
   1331 
   1332   ticks_per_itvl = ((interval_wate * sysconf(_SC_CLK_TCK) * 1000) /
   1333                     1000000);
   1334 
   1335   if (ticks_per_itvl == 0) ticks_per_itvl = 1;
   1336 
   1337   /* how many usecs in each interval? */
   1338   usec_per_itvl = ticks_per_itvl * (1000000 / sysconf(_SC_CLK_TCK));
   1339 
   1340   /* how many times will the timer pop before the test is over? */
   1341   if (test_time > 0) {
   1342     /* this was a timed test */
   1343     test_len_ticks = (test_time * 1000000) / usec_per_itvl;
   1344   }
   1345   else {
   1346     /* this was not a timed test, use MAXINT */
   1347     test_len_ticks = INT_MAX;
   1348   }
   1349 
   1350   if (debug) {
   1351     fprintf(where,
   1352 	    "setting the interval timer to %d sec %d usec test len %d ticks\n",
   1353             usec_per_itvl / 1000000,
   1354             usec_per_itvl % 1000000,
   1355             test_len_ticks);
   1356     fflush(where);
   1357   }
   1358 
   1359   /* if this was not a timed test, then we really aught to enable the
   1360      signal catcher raj 2/95 */
   1361 
   1362   new_interval.it_interval.tv_sec = usec_per_itvl / 1000000;
   1363   new_interval.it_interval.tv_usec = usec_per_itvl % 1000000;
   1364   new_interval.it_value.tv_sec = usec_per_itvl / 1000000;
   1365   new_interval.it_value.tv_usec = usec_per_itvl % 1000000;
   1366   if (setitimer(ITIMER_REAL,&new_interval,&old_interval) != 0) {
   1367     /* there was a problem arming the interval timer */
   1368     perror("netperf: setitimer");
   1369     exit(1);
   1370   }
   1371  #endif /* WIN32*/
   1372 }
   1373 #endif /* WANT_INTERVALS */
   1374 
   1375 void
   1376 netlib_init_cpu_map() {
   1377 
   1378   int i;
   1379 #ifdef HAVE_MPCTL
   1380   int num;
   1381   i = 0;
   1382   /* I go back and forth on whether this should be the system-wide set
   1383      of calls, or if the processor set versions (sans the _SYS) should
   1384      be used.  at the moment I believe that the system-wide version
   1385      should be used. raj 2006-04-03 */
   1386   num = mpctl(MPC_GETNUMSPUS_SYS,0,0);
   1387   lib_cpu_map[i] = mpctl(MPC_GETFIRSTSPU_SYS,0,0);
   1388   for (i = 1;((i < num) && (i < MAXCPUS)); i++) {
   1389     lib_cpu_map[i] = mpctl(MPC_GETNEXTSPU_SYS,lib_cpu_map[i-1],0);
   1390   }
   1391   /* from here, we set them all to -1 because if we launch more
   1392      loopers than actual CPUs, well, I'm not sure why :) */
   1393   for (; i < MAXCPUS; i++) {
   1394     lib_cpu_map[i] = -1;
   1395   }
   1396 
   1397 #else
   1398   /* we assume that there is indeed a contiguous mapping */
   1399   for (i = 0; i < MAXCPUS; i++) {
   1400     lib_cpu_map[i] = i;
   1401   }
   1402 #endif
   1403 }
   1404 
   1405 
   1406 
   1407 /****************************************************************/
   1409 /*                                                              */
   1410 /*      netlib_init()                                           */
   1411 /*                                                              */
   1412 /*      initialize the performance library...                   */
   1413 /*                                                              */
   1414 /****************************************************************/
   1415 
   1416 void
   1417 netlib_init()
   1418 {
   1419   int i;
   1420 
   1421   where = stdout;
   1422 
   1423   request_array = (int *)(&netperf_request);
   1424   response_array = (int *)(&netperf_response);
   1425 
   1426   for (i = 0; i < MAXCPUS; i++) {
   1427     lib_local_per_cpu_util[i] = -1.0;
   1428   }
   1429 
   1430   lib_local_cpu_stats.peak_cpu_id = -1;
   1431   lib_local_cpu_stats.peak_cpu_util = -1.0;
   1432   lib_remote_cpu_stats.peak_cpu_id = -1;
   1433   lib_remote_cpu_stats.peak_cpu_util = -1.0;
   1434 
   1435   netperf_version = strdup(NETPERF_VERSION);
   1436 
   1437   /* on those systems where we know that CPU numbers may not start at
   1438      zero and be contiguous, we provide a way to map from a
   1439      contiguous, starting from 0 CPU id space to the actual CPU ids.
   1440      at present this is only used for the netcpu_looper stuff because
   1441      we ass-u-me that someone setting processor affinity from the
   1442      netperf commandline will provide a "proper" CPU identifier. raj
   1443      2006-04-03 */
   1444 
   1445   netlib_init_cpu_map();
   1446 
   1447   if (debug) {
   1448     fprintf(where,
   1449             "netlib_init: request_array at %p\n"
   1450             "netlib_init: response_array at %p\n",
   1451             request_array,
   1452             response_array);
   1453     fflush(where);
   1454   }
   1455 
   1456   /* some functionality might want to use random numbers, so we should
   1457      initialize the random number generator */
   1458   srand(getpid());
   1459 
   1460 }
   1461 
   1462 /* this routine will conver the string into an unsigned integer. it is
   1464    used primarily for the command-line options taking a number (such
   1465    as the socket size) which could be rather large. If someone enters
   1466    32M, then the number will be converted to 32 * 1024 * 1024.  If
   1467    they inter 32m, the number will be converted to 32 * 1000 * 1000 */
   1468 unsigned int
   1469 convert(char *string)
   1470 
   1471 {
   1472   unsigned int base;
   1473   base = atoi(string);
   1474   if (strstr(string,"K")) {
   1475     base *= 1024;
   1476   }
   1477   if (strstr(string,"M")) {
   1478     base *= (1024 * 1024);
   1479   }
   1480   if (strstr(string,"G")) {
   1481     base *= (1024 * 1024 * 1024);
   1482   }
   1483   if (strstr(string,"k")) {
   1484     base *= (1000);
   1485   }
   1486   if (strstr(string,"m")) {
   1487     base *= (1000 * 1000);
   1488   }
   1489   if (strstr(string,"g")) {
   1490     base *= (1000 * 1000 * 1000);
   1491   }
   1492   return(base);
   1493 }
   1494 
   1495 /* this routine is like convert, but it is used for an interval time
   1496    specification instead of stuff like socket buffer or send sizes.
   1497    it converts everything to microseconds for internal use.  if there
   1498    is an 'm' at the end it assumes the user provided milliseconds, s
   1499    will imply seconds, u will imply microseconds.  in the future n
   1500    will imply nanoseconds but for now it will be ignored. if there is
   1501    no suffix or an unrecognized suffix, it will be assumed the user
   1502    provided milliseconds, which was the long-time netperf default. one
   1503    of these days, we should probably revisit that nanosecond business
   1504    wrt the return value being just an int rather than a uint64_t or
   1505    something.  raj 2006-02-06 */
   1506 
   1507 unsigned int
   1508 convert_timespec(char *string) {
   1509 
   1510   unsigned int base;
   1511   base = atoi(string);
   1512   if (strstr(string,"m")) {
   1513     base *= 1000;
   1514   }
   1515   else if (strstr(string,"u")) {
   1516     base *= (1);
   1517   }
   1518   else if (strstr(string,"s")) {
   1519     base *= (1000 * 1000);
   1520   }
   1521   else {
   1522     base *= (1000);
   1523   }
   1524   return(base);
   1525 }
   1526 
   1527 
   1528 /* this routine will allocate a circular list of buffers for either
   1530    send or receive operations. each of these buffers will be aligned
   1531    and offset as per the users request. the circumference of this ring
   1532    will be controlled by the setting of width. the buffers will be
   1533    filled with data from the file specified in fill_file. if fill_file
   1534    is an empty string, the buffers will be filled from "default_fill"
   1535    which will be "netperf" so anyone sniffing the traffic will have a
   1536    better idea what this traffic happens to be. */
   1537 
   1538 struct ring_elt *
   1539 allocate_buffer_ring(int width, int buffer_size, int alignment, int offset)
   1540 {
   1541 
   1542   struct ring_elt *first_link = NULL;
   1543   struct ring_elt *temp_link  = NULL;
   1544   struct ring_elt *prev_link;
   1545 
   1546   int i;
   1547   int malloc_size;
   1548   int bytes_left;
   1549   int bytes_read;
   1550   int do_fill;
   1551 
   1552   FILE *fill_source;
   1553   char default_fill[] = "netperf";
   1554   int  fill_cursor = 0;
   1555 
   1556   malloc_size = buffer_size + alignment + offset;
   1557 
   1558   /* did the user wish to have the buffers pre-filled with data from a */
   1559   /* particular source? */
   1560   if (strcmp(local_fill_file,"") == 0) {
   1561     do_fill = 0;
   1562     fill_source = NULL;
   1563   }
   1564   else {
   1565     do_fill = 1;
   1566     fill_source = (FILE *)fopen(local_fill_file,"r");
   1567     if (fill_source == (FILE *)NULL) {
   1568       fprintf(where,"Could not open requested fill file: %s\n",
   1569 	      strerror(errno));
   1570       fflush(where);
   1571     }
   1572   }
   1573 
   1574   assert(width >= 1);
   1575 
   1576   prev_link = NULL;
   1577   for (i = 1; i <= width; i++) {
   1578     /* get the ring element */
   1579     temp_link = (struct ring_elt *)malloc(sizeof(struct ring_elt));
   1580     if (temp_link == NULL) {
   1581       fprintf(where,
   1582 	      "malloc(%u) failed!\n",
   1583 	      (unsigned int)sizeof(struct ring_elt));
   1584       exit(-1);
   1585     }
   1586     temp_link->completion_ptr = NULL;
   1587     /* remember the first one so we can close the ring at the end */
   1588     if (i == 1) {
   1589       first_link = temp_link;
   1590     }
   1591     temp_link->buffer_base = (char *)malloc(malloc_size);
   1592     if (temp_link->buffer_base == NULL) {
   1593       fprintf(where,
   1594 	      "malloc(%d) failed!\n",
   1595 	      malloc_size);
   1596       exit(-1);
   1597     }
   1598 
   1599 #ifndef WIN32
   1600     temp_link->buffer_ptr = (char *)(( (long)(temp_link->buffer_base) +
   1601                           (long)alignment - 1) &
   1602                          ~((long)alignment - 1));
   1603 #else
   1604     temp_link->buffer_ptr = (char *)(( (ULONG_PTR)(temp_link->buffer_base) +
   1605                           (ULONG_PTR)alignment - 1) &
   1606                          ~((ULONG_PTR)alignment - 1));
   1607 #endif
   1608     temp_link->buffer_ptr += offset;
   1609     /* is where the buffer fill code goes. */
   1610     if (do_fill) {
   1611       char *bufptr = temp_link->buffer_ptr;
   1612       bytes_left = buffer_size;
   1613       while (bytes_left) {
   1614         if (((bytes_read = (int)fread(bufptr,
   1615 				      1,
   1616 				      bytes_left,
   1617 				      fill_source)) == 0) &&
   1618             (feof(fill_source))){
   1619           rewind(fill_source);
   1620         }
   1621 	bufptr += bytes_read;
   1622         bytes_left -= bytes_read;
   1623       }
   1624     }
   1625     else {
   1626       /* use the default fill to ID our data traffic on the
   1627 	 network. it ain't exactly pretty, but it should work */
   1628       int j;
   1629       char *bufptr = temp_link->buffer_ptr;
   1630       for (j = 0; j < buffer_size; j++) {
   1631 	bufptr[j] = default_fill[fill_cursor];
   1632 	fill_cursor += 1;
   1633 	/* the Windows DDK compiler with an x86_64 target wants a cast
   1634 	   here */
   1635 	if (fill_cursor >  (int)strlen(default_fill)) {
   1636 	  fill_cursor = 0;
   1637 	}
   1638       }
   1639 
   1640     }
   1641     temp_link->next = prev_link;
   1642     prev_link = temp_link;
   1643   }
   1644   if (first_link) {  /* SAF Prefast made me do it... */
   1645     first_link->next = temp_link;
   1646   }
   1647 
   1648   return(first_link); /* it's a circle, doesn't matter which we return */
   1649 }
   1650 
   1651 /* this routine will dirty the first dirty_count bytes of the
   1652    specified buffer and/or read clean_count bytes from the buffer. it
   1653    will go N bytes at a time, the only question is how large should N
   1654    be and if we should be going continguously, or based on some
   1655    assumption of cache line size */
   1656 
   1657 void
   1658 access_buffer(char *buffer_ptr,int length, int dirty_count, int clean_count) {
   1659 
   1660   char *temp_buffer;
   1661   char *limit;
   1662   int  i, dirty_totals;
   1663 
   1664   temp_buffer = buffer_ptr;
   1665   limit = temp_buffer + length;
   1666   dirty_totals = 0;
   1667 
   1668   for (i = 0;
   1669        ((i < dirty_count) && (temp_buffer < limit));
   1670        i++) {
   1671     *temp_buffer += (char)i;
   1672     dirty_totals += *temp_buffer;
   1673     temp_buffer++;
   1674   }
   1675 
   1676   for (i = 0;
   1677        ((i < clean_count) && (temp_buffer < limit));
   1678        i++) {
   1679     dirty_totals += *temp_buffer;
   1680     temp_buffer++;
   1681   }
   1682 
   1683   if (debug > 100) {
   1684     fprintf(where,
   1685 	    "This was here to try to avoid dead-code elimination %d\n",
   1686 	    dirty_totals);
   1687     fflush(where);
   1688   }
   1689 }
   1690 
   1691 
   1693 #ifdef HAVE_ICSC_EXS
   1694 
   1695 #include <sys/mman.h>
   1696 #include <sys/exs.h>
   1697 
   1698 /* this routine will allocate a circular list of buffers for either
   1699    send or receive operations. each of these buffers will be aligned
   1700    and offset as per the users request. the circumference of this ring
   1701    will be controlled by the setting of send_width. the buffers will
   1702    be filled with data from the file specified in local_fill_file. if
   1703    local_fill_file is an empty string, the buffers will not be filled with
   1704    any particular data */
   1705 
   1706 struct ring_elt *
   1707 allocate_exs_buffer_ring (int width, int buffer_size, int alignment, int offset, exs_mhandle_t *mhandlep)
   1708 {
   1709 
   1710     struct ring_elt *first_link;
   1711     struct ring_elt *temp_link;
   1712     struct ring_elt *prev_link;
   1713 
   1714     int i;
   1715     int malloc_size;
   1716     int bytes_left;
   1717     int bytes_read;
   1718     int do_fill;
   1719 
   1720     FILE *fill_source;
   1721 
   1722     int mmap_size;
   1723     char *mmap_buffer, *mmap_buffer_aligned;
   1724 
   1725     malloc_size = buffer_size + alignment + offset;
   1726 
   1727     /* did the user wish to have the buffers pre-filled with data from a */
   1728     /* particular source? */
   1729     if (strcmp (local_fill_file, "") == 0) {
   1730         do_fill = 0;
   1731         fill_source = NULL;
   1732     } else {
   1733         do_fill = 1;
   1734         fill_source = (FILE *) fopen (local_fill_file, "r");
   1735         if (fill_source == (FILE *) NULL) {
   1736             perror ("Could not open requested fill file");
   1737             exit (1);
   1738         }
   1739     }
   1740 
   1741     assert (width >= 1);
   1742 
   1743     if (debug) {
   1744         fprintf (where,
   1745 		 "allocate_exs_buffer_ring: "
   1746                  "width=%d buffer_size=%d alignment=%d offset=%d\n",
   1747                  width, buffer_size, alignment, offset);
   1748     }
   1749 
   1750     /* allocate shared memory */
   1751     mmap_size = width * malloc_size;
   1752     mmap_buffer = (char *) mmap ((caddr_t)NULL, mmap_size+NBPG-1,
   1753                                  PROT_READ|PROT_WRITE,
   1754                                  MAP_SHARED|MAP_ANONYMOUS, -1, 0);
   1755     if (mmap_buffer == NULL) {
   1756         perror ("allocate_exs_buffer_ring: mmap failed");
   1757         exit (1);
   1758     }
   1759     mmap_buffer_aligned = (char *) ((uintptr_t)mmap_buffer & ~(NBPG-1));
   1760     if (debug) {
   1761         fprintf (where,
   1762 		 "allocate_exs_buffer_ring: "
   1763                  "mmap buffer size=%d address=0x%p aligned=0x%p\n",
   1764                  mmap_size, mmap_buffer, mmap_buffer_aligned);
   1765     }
   1766 
   1767     /* register shared memory */
   1768     *mhandlep = exs_mregister ((void *)mmap_buffer_aligned, (size_t)mmap_size, 0);
   1769     if (*mhandlep == EXS_MHANDLE_INVALID) {
   1770         perror ("allocate_exs_buffer_ring: exs_mregister failed");
   1771         exit (1);
   1772     }
   1773     if (debug) {
   1774         fprintf (where, "allocate_exs_buffer_ring: mhandle=%d\n",
   1775                  *mhandlep);
   1776     }
   1777 
   1778     /* allocate ring elements */
   1779     first_link = (struct ring_elt *) malloc (width * sizeof (struct ring_elt));
   1780     if (first_link == NULL) {
   1781         printf ("malloc(%d) failed!\n", width * sizeof (struct ring_elt));
   1782         exit (1);
   1783     }
   1784 
   1785     /* initialize buffer ring */
   1786     prev_link = first_link + width - 1;
   1787 
   1788     for (i = 0, temp_link = first_link; i < width; i++, temp_link++) {
   1789 
   1790         temp_link->buffer_base = (char *) mmap_buffer_aligned + (i*malloc_size);
   1791 #ifndef WIN32
   1792         temp_link->buffer_ptr = (char *)
   1793             (((long)temp_link->buffer_base + (long)alignment - 1) &
   1794              ~((long)alignment - 1));
   1795 #else
   1796         temp_link->buffer_ptr = (char *)
   1797             (((ULONG_PTR)temp_link->buffer_base + (ULONG_PTR)alignment - 1) &
   1798              ~((ULONG_PTR)alignment - 1));
   1799 #endif
   1800         temp_link->buffer_ptr += offset;
   1801 
   1802         if (debug) {
   1803             fprintf (where, "allocate_exs_buffer_ring: "
   1804                      "buffer: index=%d base=0x%p ptr=0x%p\n",
   1805                      i, temp_link->buffer_base, temp_link->buffer_ptr);
   1806         }
   1807 
   1808         /* is where the buffer fill code goes. */
   1809         if (do_fill) {
   1810             bytes_left = buffer_size;
   1811             while (bytes_left) {
   1812                 if (((bytes_read = (int) fread (temp_link->buffer_ptr,
   1813                                                 1,
   1814                                                 bytes_left,
   1815                                                 fill_source)) == 0) &&
   1816                     (feof (fill_source))) {
   1817                     rewind (fill_source);
   1818                 }
   1819                 bytes_left -= bytes_read;
   1820             }
   1821         }
   1822 
   1823         /* do linking */
   1824         prev_link->next = temp_link;
   1825         prev_link = temp_link;
   1826     }
   1827 
   1828     return (first_link);  /* it is a circle, doesn't matter which we return */
   1829 }
   1830 
   1831 #endif /* HAVE_ICSC_EXS */
   1832 
   1833 
   1834 
   1836 #ifdef HAVE_SENDFILE
   1837 /* this routine will construct a ring of sendfile_ring_elt structs
   1838    that the routine sendfile_tcp_stream() will use to get parameters
   1839    to its calls to sendfile(). It will setup the ring to point at the
   1840    file specified in the global -F option that is already used to
   1841    pre-fill buffers in the send() case. 08/2000
   1842 
   1843    if there is no file specified in a global -F option, we will create
   1844    a tempoarary file and fill it with random data and use that
   1845    instead.  raj 2007-08-09 */
   1846 
   1847 struct ring_elt *
   1848 alloc_sendfile_buf_ring(int width,
   1849                         int buffer_size,
   1850                         int alignment,
   1851                         int offset)
   1852 
   1853 {
   1854 
   1855   struct ring_elt *first_link = NULL;
   1856   struct ring_elt *temp_link  = NULL;
   1857   struct ring_elt *prev_link;
   1858 
   1859   int i;
   1860   int fildes;
   1861   struct stat statbuf;
   1862 
   1863   /* if the user has not specified a file with the -F option, we will
   1864      fail the test. otherwise, go ahead and try to open the
   1865      file. 08/2000 */
   1866   if (strcmp(local_fill_file,"") == 0) {
   1867     /* use an temp file for the fill file */
   1868     char temp_file[] = {"netperfXXXXXX\0"};
   1869     int *temp_buffer;
   1870 
   1871     /* make sure we have at least an ints worth, even if the user is
   1872        using an insane buffer size for a sendfile test. we are
   1873        ass-u-me-ing that malloc will return something at least aligned
   1874        on an int boundary... */
   1875     temp_buffer = (int *) malloc(buffer_size + sizeof(int));
   1876     if (temp_buffer) {
   1877       /* ok, we have the buffer we are going to write, lets get a
   1878 	 temporary filename */
   1879       fildes = mkstemp(temp_file);
   1880       /* no need to call open because mkstemp did it */
   1881 	if (-1 != fildes) {
   1882 	  int count;
   1883 	  int *int_ptr;
   1884 
   1885 	  /* we initialize the random number generator in
   1886 	     netlib_init() now. raj 20110111 */
   1887 
   1888 	  /* unlink the file so it goes poof when we
   1889 	     exit. unless/until shown to be a problem we will
   1890 	     blissfully ignore the return value. raj 2007-08-09 */
   1891 	  unlink(temp_file);
   1892 
   1893 	  /* now fill-out the file with at least buffer_size * width bytes */
   1894 	  for (count = 0; count < width; count++) {
   1895 	    /* fill the buffer with random data.  it doesn't have to be
   1896 	       really random, just "random enough" :) we do this here rather
   1897 	       than up above because we want each write to the file to be
   1898 	       different random data */
   1899 	    int_ptr = temp_buffer;
   1900 	    for (i = 0; i <= buffer_size/sizeof(int); i++) {
   1901 	      *int_ptr = rand();
   1902 	      int_ptr++;
   1903 	    }
   1904 	    if (write(fildes,temp_buffer,buffer_size+sizeof(int)) !=
   1905 		buffer_size + sizeof(int)) {
   1906 	      perror("allocate_sendfile_buf_ring: incomplete write");
   1907 	      exit(-1);
   1908 	    }
   1909 	  }
   1910       }
   1911       else {
   1912 	perror("alloc_sendfile_buf_ring: could not allocate temp name");
   1913 	exit(-1);
   1914       }
   1915     }
   1916     else {
   1917       perror("alloc_sendfile_buf_ring: could not allocate buffer for file");
   1918       exit(-1);
   1919     }
   1920   }
   1921   else {
   1922     /* the user pointed us at a file, so try it */
   1923     fildes = open(local_fill_file , O_RDONLY);
   1924     if (fildes == -1){
   1925       perror("alloc_sendfile_buf_ring: Could not open requested file");
   1926       exit(1);
   1927     }
   1928     /* make sure there is enough file there to allow us to make a
   1929        complete ring. that way we do not need additional logic in the
   1930        ring setup to deal with wrap-around issues. we might want that
   1931        someday, but not just now. 08/2000 */
   1932     if (stat(local_fill_file,&statbuf) != 0) {
   1933       perror("alloc_sendfile_buf_ring: could not stat file");
   1934       exit(1);
   1935     }
   1936     if (statbuf.st_size < (width * buffer_size)) {
   1937       /* the file is too short */
   1938       fprintf(stderr,
   1939 	      "alloc_sendfile_buf_ring: specified file too small.\n"
   1940 	      "file must be larger than send_width * send_size\n");
   1941       fflush(stderr);
   1942       exit(1);
   1943     }
   1944   }
   1945 
   1946   /* so, at this point we know that fildes is a descriptor which
   1947      references a file of sufficient size for our nefarious
   1948      porpoises. raj 2007-08-09 */
   1949 
   1950   prev_link = NULL;
   1951   for (i = 1; i <= width; i++) {
   1952     /* get the ring element. we should probably make sure the malloc()
   1953        was successful, but for now we'll just let the code bomb
   1954        mysteriously. 08/2000 */
   1955 
   1956     temp_link = (struct ring_elt *)
   1957       malloc(sizeof(struct ring_elt));
   1958     if (temp_link == NULL) {
   1959       fprintf(where,
   1960 	      "malloc(%u) failed!\n",
   1961 	      (unsigned int) sizeof(struct ring_elt));
   1962       exit(1);
   1963     }
   1964 
   1965     /* remember the first one so we can close the ring at the end */
   1966 
   1967     if (i == 1) {
   1968       first_link = temp_link;
   1969     }
   1970 
   1971     /* now fill-in the fields of the structure with the apropriate
   1972        stuff. just how should we deal with alignment and offset I
   1973        wonder? until something better comes-up, I think we will just
   1974        ignore them. 08/2000 */
   1975 
   1976     temp_link->fildes = fildes;      /* from which file do we send? */
   1977     temp_link->offset = offset;      /* starting at which offset? */
   1978     offset += buffer_size;           /* get ready for the next elt */
   1979     temp_link->length = buffer_size; /* how many bytes to send */
   1980     temp_link->hdtrl = NULL;         /* no header or trailer */
   1981     temp_link->flags = 0;            /* no flags */
   1982 
   1983     /* is where the buffer fill code went. */
   1984 
   1985     temp_link->next = prev_link;
   1986     prev_link = temp_link;
   1987   }
   1988   /* close the ring */
   1989   first_link->next = temp_link;
   1990 
   1991   return(first_link); /* it's a dummy ring */
   1992 }
   1993 
   1994 #endif /* HAVE_SENDFILE */
   1995 
   1996 
   1997  /***********************************************************************/
   1999  /*                                                                     */
   2000  /*     dump_request()                                                  */
   2001  /*                                                                     */
   2002  /* display the contents of the request array to the user. it will      */
   2003  /* display the contents in decimal, hex, and ascii, with four bytes    */
   2004  /* per line.                                                           */
   2005  /*                                                                     */
   2006  /***********************************************************************/
   2007 
   2008 void
   2009 dump_request()
   2010 {
   2011 int counter = 0;
   2012 fprintf(where,"request contents:\n");
   2013 for (counter = 0; counter < ((sizeof(netperf_request)/4)-3); counter += 4) {
   2014   fprintf(where,"%d:\t%8x %8x %8x %8x \t|%4.4s| |%4.4s| |%4.4s| |%4.4s|\n",
   2015           counter,
   2016           request_array[counter],
   2017           request_array[counter+1],
   2018           request_array[counter+2],
   2019           request_array[counter+3],
   2020           (char *)&request_array[counter],
   2021           (char *)&request_array[counter+1],
   2022           (char *)&request_array[counter+2],
   2023           (char *)&request_array[counter+3]);
   2024 }
   2025 fflush(where);
   2026 }
   2027 
   2028 
   2029  /***********************************************************************/
   2030  /*                                                                     */
   2031  /*     dump_response()                                                 */
   2032  /*                                                                     */
   2033  /* display the content of the response array to the user. it will      */
   2034  /* display the contents in decimal, hex, and ascii, with four bytes    */
   2035  /* per line.                                                           */
   2036  /*                                                                     */
   2037  /***********************************************************************/
   2038 
   2039 void
   2040 dump_response()
   2041 {
   2042 int counter = 0;
   2043 
   2044 fprintf(where,"response contents\n");
   2045 for (counter = 0; counter < ((sizeof(netperf_response)/4)-3); counter += 4) {
   2046   fprintf(where,"%d:\t%8x %8x %8x %8x \t>%4.4s< >%4.4s< >%4.4s< >%4.4s<\n",
   2047           counter,
   2048           response_array[counter],
   2049           response_array[counter+1],
   2050           response_array[counter+2],
   2051           response_array[counter+3],
   2052           (char *)&response_array[counter],
   2053           (char *)&response_array[counter+1],
   2054           (char *)&response_array[counter+2],
   2055           (char *)&response_array[counter+3]);
   2056 }
   2057 fflush(where);
   2058 }
   2059 
   2060  /*
   2061 
   2062       format_number()
   2063 
   2064   return a pointer to a formatted string containing the value passed
   2065   translated into the units specified. It assumes that the base units
   2066   are bytes. If the format calls for bits, it will use SI units (10^)
   2067   if the format calls for bytes, it will use CS units (2^)...  This
   2068   routine should look familiar to uses of the latest ttcp...
   2069 
   2070   we would like to use "t" or "T" for transactions, but probably
   2071   should leave those for terabits and terabytes respectively, so for
   2072   transactions, we will use "x" which will, by default, do absolutely
   2073   nothing to the result.  why?  so we don't have to special case code
   2074   elsewhere such as in the TCP_RR-as-bidirectional test case.
   2075 
   2076  */
   2077 
   2078 
   2079 char *
   2080 format_number(double number)
   2081 {
   2082   static  char    fmtbuf[64];
   2083 
   2084   switch (libfmt) {
   2085   case 'B':
   2086     snprintf(fmtbuf, sizeof(fmtbuf),  "%-7.2f" , number);
   2087     break;
   2088   case 'K':
   2089     snprintf(fmtbuf, sizeof(fmtbuf),  "%-7.2f" , number / 1024.0);
   2090     break;
   2091   case 'M':
   2092     snprintf(fmtbuf, sizeof(fmtbuf),  "%-7.2f", number / 1024.0 / 1024.0);
   2093     break;
   2094   case 'G':
   2095     snprintf(fmtbuf, sizeof(fmtbuf),  "%-7.2f", number / 1024.0 / 1024.0 / 1024.0);
   2096     break;
   2097   case 'b':
   2098     snprintf(fmtbuf, sizeof(fmtbuf),  "%-7.2f" , number * 8);
   2099     break;
   2100   case 'k':
   2101     snprintf(fmtbuf, sizeof(fmtbuf),  "%-7.2f", number * 8 / 1000.0);
   2102     break;
   2103   case 'm':
   2104     snprintf(fmtbuf, sizeof(fmtbuf),  "%-7.2f", number * 8 / 1000.0 / 1000.0);
   2105     break;
   2106   case 'g':
   2107     snprintf(fmtbuf, sizeof(fmtbuf),  "%-7.2f", number * 8 / 1000.0 / 1000.0 / 1000.0);
   2108     break;
   2109   case 'x':
   2110     snprintf(fmtbuf, sizeof(fmtbuf),  "%-7.2f", number);
   2111     break;
   2112   default:
   2113     snprintf(fmtbuf, sizeof(fmtbuf),  "%-7.2f", number / 1024.0);
   2114   }
   2115 
   2116   return fmtbuf;
   2117 }
   2118 
   2119 char
   2120 format_cpu_method(int method)
   2121 {
   2122 
   2123   char method_char;
   2124 
   2125   switch (method) {
   2126   case CPU_UNKNOWN:
   2127     method_char = 'U';
   2128     break;
   2129   case HP_IDLE_COUNTER:
   2130     method_char = 'I';
   2131     break;
   2132   case PSTAT:
   2133     method_char = 'P';
   2134     break;
   2135   case KSTAT:
   2136     method_char = 'K';
   2137     break;
   2138   case KSTAT_10:
   2139     method_char = 'M';
   2140     break;
   2141   case PERFSTAT:
   2142     method_char = 'E';
   2143     break;
   2144   case TIMES:             /* historical only, completely unsuitable
   2145 			     for netperf's purposes */
   2146     method_char = 'T';
   2147     break;
   2148   case GETRUSAGE:         /* historical only, completely unsuitable
   2149 			     for netperf;s purposes */
   2150     method_char = 'R';
   2151     break;
   2152   case LOOPER:
   2153     method_char = 'L';
   2154     break;
   2155   case NT_METHOD:
   2156     method_char = 'N';
   2157     break;
   2158   case PROC_STAT:
   2159     method_char = 'S';
   2160     break;
   2161   case SYSCTL:
   2162     method_char = 'C';
   2163     break;
   2164   case OSX:
   2165     method_char = 'O';
   2166     break;
   2167   default:
   2168     method_char = '?';
   2169   }
   2170 
   2171   return method_char;
   2172 
   2173 }
   2174 
   2175 char *
   2176 format_units()
   2177 {
   2178   static        char    unitbuf[64];
   2179 
   2180   switch (libfmt) {
   2181   case 'B':
   2182     strcpy(unitbuf, "Bytes");
   2183     break;
   2184   case 'K':
   2185     strcpy(unitbuf, "KBytes");
   2186     break;
   2187   case 'M':
   2188     strcpy(unitbuf, "MBytes");
   2189     break;
   2190   case 'G':
   2191     strcpy(unitbuf, "GBytes");
   2192     break;
   2193   case 'b':
   2194     strcpy(unitbuf, "10^0bits");
   2195     break;
   2196   case 'k':
   2197     strcpy(unitbuf, "10^3bits");
   2198     break;
   2199   case 'm':
   2200     strcpy(unitbuf, "10^6bits");
   2201     break;
   2202   case 'g':
   2203     strcpy(unitbuf, "10^9bits");
   2204     break;
   2205   case 'x':
   2206     strcpy(unitbuf, "Trans");
   2207     break;
   2208   case 'u':
   2209     strcpy(unitbuf,"Usec");
   2210     break;
   2211 
   2212   default:
   2213     strcpy(unitbuf, "KBytes");
   2214   }
   2215 
   2216   return unitbuf;
   2217 }
   2218 
   2219 
   2221 /****************************************************************/
   2222 /*                                                              */
   2223 /*      shutdown_control()                                      */
   2224 /*                                                              */
   2225 /* tear-down the control connection between me and the server.  */
   2226 /****************************************************************/
   2227 
   2228 void
   2229 shutdown_control()
   2230 {
   2231 
   2232   char  *buf = (char *)&netperf_response;
   2233   int   buflen = sizeof(netperf_response);
   2234 
   2235   /* stuff for select, use fd_set for better compliance */
   2236   fd_set        readfds;
   2237   struct        timeval timeout;
   2238 
   2239   if (debug) {
   2240     fprintf(where,
   2241             "shutdown_control: shutdown of control connection requested.\n");
   2242     fflush(where);
   2243   }
   2244 
   2245   /* first, we say that we will be sending no more data on the */
   2246   /* connection */
   2247   if (shutdown(netlib_control,1) == SOCKET_ERROR) {
   2248     Print_errno(where,
   2249             "shutdown_control: error in shutdown");
   2250     fflush(where);
   2251     exit(1);
   2252   }
   2253 
   2254   /* Now, we hang on a select waiting for the socket to become
   2255      readable to receive the shutdown indication from the remote. this
   2256      will be "just" like the recv_response() code
   2257 
   2258      we only select once. it is assumed that if the response is split
   2259      (which should not be happening, that we will receive the whole
   2260      thing and not have a problem ;-) */
   2261 
   2262   FD_ZERO(&readfds);
   2263   FD_SET(netlib_control,&readfds);
   2264   timeout.tv_sec  = 60; /* wait one minute then punt */
   2265   timeout.tv_usec = 0;
   2266 
   2267   /* select had better return one, or there was either a problem or a
   2268      timeout... */
   2269   if (select(FD_SETSIZE,
   2270              &readfds,
   2271              0,
   2272              0,
   2273              &timeout) != 1) {
   2274     Print_errno(where,
   2275             "shutdown_control: no response received");
   2276     fflush(where);
   2277     exit(1);
   2278   }
   2279 
   2280   /* we now assume that the socket has come ready for reading */
   2281   recv(netlib_control, buf, buflen,0);
   2282 
   2283 }
   2284 
   2285 /*
   2286   bind_to_specific_processor will bind the calling process to the
   2287   processor in "processor"  It has lots of ugly ifdefs to deal with
   2288   all the different ways systems do processor affinity.  this is a
   2289   generalization of work initially done by stephen burger.  raj
   2290   2004/12/13 */
   2291 
   2292 void
   2293 bind_to_specific_processor(int processor_affinity, int use_cpu_map)
   2294 {
   2295 
   2296   int mapped_affinity;
   2297 
   2298   /* this is in place because the netcpu_looper processor affinity
   2299      ass-u-me-s a contiguous CPU id space starting with 0. for the
   2300      regular netperf/netserver affinity, we ass-u-me the user has used
   2301      a suitable CPU id even when the space is not contiguous and
   2302      starting from zero */
   2303   if (use_cpu_map) {
   2304     mapped_affinity = lib_cpu_map[processor_affinity];
   2305   }
   2306   else {
   2307     mapped_affinity = processor_affinity;
   2308   }
   2309 
   2310 #ifdef HAVE_MPCTL
   2311   /* indeed, at some point it would be a good idea to check the return
   2312      status and pass-along notification of error... raj 2004/12/13 */
   2313   mpctl(MPC_SETPROCESS_FORCE, mapped_affinity, getpid());
   2314 #elif HAVE_PROCESSOR_BIND
   2315 #include <sys/types.h>
   2316 #include <sys/processor.h>
   2317 #include <sys/procset.h>
   2318   processor_bind(P_PID,P_MYID,mapped_affinity,NULL);
   2319 #elif HAVE_BINDPROCESSOR
   2320 #include <sys/processor.h>
   2321   /* this is the call on AIX.  It takes a "what" of BINDPROCESS or
   2322      BINDTHRAD, then "who" and finally "where" which is a CPU number
   2323      or it seems PROCESSOR_CLASS_ANY there also seems to be a mycpu()
   2324      call to return the current CPU assignment.  this is all based on
   2325      the sys/processor.h include file.  from empirical testing, it
   2326      would seem that the my_cpu() call returns the current CPU on
   2327      which we are running rather than the CPU binding, so it's return
   2328      value will not tell you if you are bound vs unbound. */
   2329   bindprocessor(BINDPROCESS,getpid(),(cpu_t)mapped_affinity);
   2330 #elif HAVE_SCHED_SETAFFINITY
   2331 #include <sched.h>
   2332   /* in theory this should cover systems with more CPUs than bits in a
   2333      long, without having to specify __USE_GNU.  we "cheat" by taking
   2334      defines from /usr/include/bits/sched.h, which we ass-u-me is
   2335      included by <sched.h>.  If they are not there we will just
   2336      fall-back on what we had before, which is to use just the size of
   2337      an unsigned long. raj 2006-09-14 */
   2338 
   2339 #if defined(__CPU_SETSIZE)
   2340 #define NETPERF_CPU_SETSIZE __CPU_SETSIZE
   2341 #if defined(__CPU_SET_S)
   2342 #define NETPERF_CPU_SET(cpu, cpusetp)  __CPU_SET_S(cpu, sizeof (cpu_set_t), cpusetp)
   2343 #define NETPERF_CPU_ZERO(cpusetp)      __CPU_ZERO_S (sizeof (cpu_set_t), cpusetp)
   2344 #else
   2345 #define NETPERF_CPU_SET(cpu, cpusetp)  __CPU_SET(cpu, cpusetp)
   2346 #define NETPERF_CPU_ZERO(cpusetp)      __CPU_ZERO (cpusetp)
   2347 #endif
   2348   typedef cpu_set_t netperf_cpu_set_t;
   2349 #else
   2350 #define NETPERF_CPU_SETSIZE sizeof(unsigned long)
   2351 #define NETPERF_CPU_SET(cpu, cpusetp) *cpusetp = 1 << cpu
   2352 #define NETPERF_CPU_ZERO(cpusetp) *cpusetp = (unsigned long)0
   2353   typedef unsigned long netperf_cpu_set_t;
   2354 #endif
   2355 
   2356   netperf_cpu_set_t   netperf_cpu_set;
   2357   unsigned int        len = sizeof(netperf_cpu_set);
   2358 
   2359   if (mapped_affinity < 8*sizeof(netperf_cpu_set)) {
   2360     NETPERF_CPU_ZERO(&netperf_cpu_set);
   2361     NETPERF_CPU_SET(mapped_affinity,&netperf_cpu_set);
   2362 
   2363     if (sched_setaffinity(getpid(), len, &netperf_cpu_set)) {
   2364       if (debug) {
   2365 	fprintf(stderr, "failed to set PID %d's CPU affinity errno %d\n",
   2366 		getpid(),errno);
   2367 	fflush(stderr);
   2368       }
   2369     }
   2370   }
   2371   else {
   2372     if (debug) {
   2373 	fprintf(stderr,
   2374 		"CPU number larger than pre-compiled limits. Consider a recompile.\n");
   2375 	fflush(stderr);
   2376       }
   2377   }
   2378 
   2379 #elif HAVE_BIND_TO_CPU_ID
   2380   /* this is the one for Tru64 */
   2381 #include <sys/types.h>
   2382 #include <sys/resource.h>
   2383 #include <sys/processor.h>
   2384 
   2385   /* really should be checking a return code one of these days. raj
   2386      2005/08/31 */
   2387 
   2388   bind_to_cpu_id(getpid(), mapped_affinity,0);
   2389 
   2390 #elif WIN32
   2391 
   2392   {
   2393     ULONG_PTR AffinityMask;
   2394     ULONG_PTR ProcessAffinityMask;
   2395     ULONG_PTR SystemAffinityMask;
   2396 
   2397     if ((mapped_affinity < 0) ||
   2398 	(mapped_affinity > MAXIMUM_PROCESSORS)) {
   2399       fprintf(where,
   2400 	      "Invalid processor_affinity specified: %d\n", mapped_affinity);      fflush(where);
   2401       return;
   2402     }
   2403 
   2404     if (!GetProcessAffinityMask(
   2405 				GetCurrentProcess(),
   2406 				&ProcessAffinityMask,
   2407 				&SystemAffinityMask))
   2408       {
   2409 	perror("GetProcessAffinityMask failed");
   2410 	fflush(stderr);
   2411 	exit(1);
   2412       }
   2413 
   2414     AffinityMask = (ULONG_PTR)1 << mapped_affinity;
   2415 
   2416     if (AffinityMask & ProcessAffinityMask) {
   2417       if (!SetThreadAffinityMask( GetCurrentThread(), AffinityMask)) {
   2418 	perror("SetThreadAffinityMask failed");
   2419 	fflush(stderr);
   2420       }
   2421     } else if (debug) {
   2422       fprintf(where,
   2423 	      "Processor affinity set to CPU# %d\n", mapped_affinity);
   2424       fflush(where);
   2425     }
   2426   }
   2427 
   2428 #else
   2429   if (debug) {
   2430     fprintf(where,
   2431 	    "Processor affinity not available for this platform!\n");
   2432     fflush(where);
   2433   }
   2434 #endif
   2435 }
   2436 
   2437 
   2438 /*
   2440  * Sets a socket to non-blocking operation.
   2441  */
   2442 int
   2443 set_nonblock (SOCKET sock)
   2444 {
   2445 #ifdef WIN32
   2446   unsigned long flags = 1;
   2447   return (ioctlsocket(sock, FIONBIO, &flags) != SOCKET_ERROR);
   2448 #else
   2449   return (fcntl(sock, F_SETFL, O_NONBLOCK) != -1);
   2450 #endif
   2451 }
   2452 
   2453 
   2454 
   2456 /* send a request, only converting the first n ints-worth of the
   2457    test-specific data via htonl() before sending on the
   2458    connection. the first two ints, which are before the test-specific
   2459    portion are always converted. raj 2008-02-05 */
   2460 
   2461 void
   2462 send_request_n(int n)
   2463 {
   2464 
   2465   int   counter,count;
   2466 
   2467   if (n < 0) count = sizeof(netperf_request)/4;
   2468   else count = 2 + n;
   2469 
   2470   /* silently truncate if the caller called for more than we have */
   2471   if (count > sizeof(netperf_request)/4) {
   2472     if (debug > 1) {
   2473       fprintf(where,
   2474 	      "WARNING, htonl conversion count of %d was larger than netperf_request\n",
   2475 	      count - 2);
   2476       fflush(where);
   2477     }
   2478     count = sizeof(netperf_request)/4;
   2479   }
   2480 
   2481   /* display the contents of the request if the debug level is high
   2482      enough. otherwise, just send the darned thing ;-) */
   2483 
   2484   if (debug > 1) {
   2485     fprintf(where,
   2486 	    "entered send_request_n...contents before %d htonls:\n",
   2487 	    count);
   2488     dump_request();
   2489   }
   2490 
   2491   /* pass the processor affinity request value to netserver this is a
   2492      kludge and I know it.  sgb 8/11/04. we keep this here to deal
   2493      with there being two paths to this place - direct and via
   2494      send_request()  */
   2495 
   2496   netperf_request.content.dummy = remote_proc_affinity;
   2497 
   2498   /* put the entire request array into network order. We do this
   2499      arbitrarily rather than trying to figure-out just how much of the
   2500      request array contains real information. this should be simpler,
   2501      and at any rate, the performance of sending control messages for
   2502      this benchmark is not of any real concern. */
   2503 
   2504   for (counter = 0; counter < count; counter++) {
   2505     request_array[counter] = htonl(request_array[counter]);
   2506   }
   2507 
   2508   if (debug > 1) {
   2509     fprintf(where,"send_request_n...contents after %d htonls:\n",
   2510 	    count);
   2511     dump_request();
   2512 
   2513     fprintf(where,
   2514             "\nsend_request: about to send %u bytes from %p\n",
   2515             (unsigned int) sizeof(netperf_request),
   2516             &netperf_request);
   2517     fflush(where);
   2518   }
   2519 
   2520   if (send(netlib_control,
   2521            (char *)&netperf_request,
   2522            sizeof(netperf_request),
   2523            0) != sizeof(netperf_request)) {
   2524     perror("send_request: send call failure");
   2525 
   2526     exit(1);
   2527   }
   2528 }
   2529 
   2530  /***********************************************************************/
   2531  /*                                                                     */
   2532  /*     send_request()                                                  */
   2533  /*                                                                     */
   2534  /* send a netperf request on the control socket to the remote half of  */
   2535  /* the connection. to get us closer to intervendor interoperability,   */
   2536  /* we will call htonl on each of the int that compose the message to   */
   2537  /* be sent. the server-half of the connection will call the ntohl      */
   2538  /* routine to undo any changes that may have been made...              */
   2539  /*                                                                     */
   2540  /***********************************************************************/
   2541 
   2542 void
   2543 send_request()
   2544 {
   2545 
   2546   /* pass the processor affinity request value to netserver this is a
   2547      kludge and I know it.  sgb 8/11/04  */
   2548 
   2549   netperf_request.content.dummy = remote_proc_affinity;
   2550 
   2551   /* call send_request_n telling it to convert everything */
   2552 
   2553   send_request_n(-1);
   2554 
   2555 }
   2556 
   2557 /* send a response, only converting the first n ints-worth of the
   2558    test-specific data via htonl() before sending on the
   2559    connection. the first two ints, which are before the test-specific
   2560    portion are always converted. raj 2008-02-05 */
   2561 
   2562 void
   2563 send_response_n(int n)
   2564 {
   2565   int   counter, count;
   2566   int	bytes_sent;
   2567 
   2568   if (n < 0) count = sizeof(netperf_request)/4;
   2569   else count = 2 + n;
   2570 
   2571   /* silently truncate if the caller called for more than we have */
   2572   if (count > sizeof(netperf_request)/4) {
   2573     if (debug > 1) {
   2574       fprintf(where,
   2575 	      "WARNING, htonl conversion count of %d was larger than netperf_request\n",
   2576 	      count - 2);
   2577       fflush(where);
   2578     }
   2579     count = sizeof(netperf_request)/4;
   2580   }
   2581 
   2582   /* display the contents of the request if the debug level is high */
   2583   /* enough. otherwise, just send the darned thing ;-) */
   2584 
   2585   if (debug > 1) {
   2586     fprintf(where,
   2587             "send_response_n: contents of %u ints before %d htonl,\n",
   2588             (unsigned int) sizeof(netperf_response)/4,
   2589 	    count);
   2590     dump_response();
   2591   }
   2592 
   2593   /* put the entire response_array into network order. We do this
   2594      arbitrarily rather than trying to figure-out just how much of the
   2595      request array contains real information. this should be simpler,
   2596      and at any rate, the performance of sending control messages for
   2597      this benchmark is not of any real concern. */
   2598 
   2599   for (counter = 0; counter < count; counter++) {
   2600     response_array[counter] = htonl(response_array[counter]);
   2601   }
   2602 
   2603   if (debug > 1) {
   2604     fprintf(where,
   2605             "send_response_n: contents after htonl\n");
   2606     dump_response();
   2607     fprintf(where,
   2608             "about to send %u bytes from %p\n",
   2609             (unsigned int) sizeof(netperf_response),
   2610             &netperf_response);
   2611     fflush(where);
   2612   }
   2613 
   2614   /*KC*/
   2615   if ((bytes_sent = send(server_sock,
   2616 			 (char *)&netperf_response,
   2617 			 sizeof(netperf_response),
   2618 			 0)) != sizeof(netperf_response)) {
   2619     perror("send_response_n: send call failure");
   2620     fprintf(where, "BytesSent: %d\n", bytes_sent);
   2621     exit(1);
   2622   }
   2623 
   2624 }
   2625 
   2626 /***********************************************************************/
   2627  /*                                                                     */
   2628  /*     send_response()                                                 */
   2629  /*                                                                     */
   2630  /* send a netperf response on the control socket to the remote half of */
   2631  /* the connection. to get us closer to intervendor interoperability,   */
   2632  /* we will call htonl on each of the int that compose the message to   */
   2633  /* be sent. the other half of the connection will call the ntohl       */
   2634  /* routine to undo any changes that may have been made...              */
   2635  /*                                                                     */
   2636  /***********************************************************************/
   2637 
   2638 void
   2639 send_response()
   2640 {
   2641 
   2642   send_response_n(-1);
   2643 
   2644 }
   2645 
   2646 /* go back and "undo" the ntohl that recv_request() did, starting with
   2647    the specified point and going to the end of the request array */
   2648 void
   2649 fixup_request_n(int n)
   2650 {
   2651   int i;
   2652   int limit;
   2653 
   2654   limit = sizeof(netperf_request) / 4;
   2655   /* we must remember that the request_array also contains two ints of
   2656      "other" stuff, so we start the fixup two in - at least I think we
   2657      should.  raj 2012-04-02 */
   2658   for (i = n + 2; i < limit; i++) {
   2659     request_array[i] = htonl(request_array[i]);
   2660   }
   2661   if (debug > 1) {
   2662     fprintf(where,
   2663 	    "%s: request contents after fixup at the %d th int\n",
   2664 	    __FUNCTION__,
   2665 	    n);
   2666     dump_request();
   2667     fflush(where);
   2668   }
   2669 }
   2670 
   2671 /* receive a request, only converting the first n ints-worth of the
   2672    test-specific data via htonl() before sending on the
   2673    connection. the first two ints, which are before the test-specific
   2674    portion are always converted. raj 2008-02-05 */
   2675 
   2676 int
   2677 recv_request_timed_n(int n, int seconds)
   2678 {
   2679   int     tot_bytes_recvd,
   2680     bytes_recvd,
   2681     bytes_left;
   2682   char    *buf = (char *)&netperf_request;
   2683   int     buflen = sizeof(netperf_request);
   2684   int     counter,count;
   2685 
   2686   fd_set  readfds;
   2687   struct timeval timeout;
   2688 
   2689   if (n < 0) count = sizeof(netperf_request)/4;
   2690   else count = 2 + n;
   2691 
   2692   /* silently truncate if the caller called for more than we have */
   2693   if (count > sizeof(netperf_request)/4) {
   2694     if (debug > 1) {
   2695       fprintf(where,
   2696 	      "WARNING, htonl conversion count of %d was larger than netperf_request\n",
   2697 	      count - 2);
   2698       fflush(where);
   2699     }
   2700     count = sizeof(netperf_request)/4;
   2701   }
   2702 
   2703   /* for the time being, we rather rely on select decrementing timeout
   2704      each time to preclude someone with nefarious intent from just
   2705      dribbling data to us piecemeal.  of course, who knows what
   2706      someone with nefarious intent might come-up with. raj 2012-01-23 */
   2707   tot_bytes_recvd = 0;
   2708   bytes_recvd = 0;     /* nt_lint; bytes_recvd uninitialized if buflen == 0 */
   2709   bytes_left      = buflen;
   2710   timeout.tv_sec = seconds;
   2711   timeout.tv_usec = 0;
   2712   do {
   2713     FD_ZERO(&readfds);
   2714     FD_SET(server_sock,&readfds);
   2715     if (select(FD_SETSIZE,
   2716 	       &readfds,
   2717 	       0,
   2718 	       0,
   2719 	       (seconds > 0) ? &timeout : NULL) != 1) {
   2720       fprintf(where,
   2721 	      "Issue receiving request on control connection. Errno %d (%s)\n",
   2722 	      errno,
   2723 	      strerror(errno));
   2724       fflush(where);
   2725       close(server_sock);
   2726       return -1;
   2727     }
   2728 
   2729     if ((bytes_recvd = recv(server_sock, buf, bytes_left, 0)) > 0) {
   2730       tot_bytes_recvd += bytes_recvd;
   2731       buf             += bytes_recvd;
   2732       bytes_left      -= bytes_recvd;
   2733     }
   2734   }  while ((tot_bytes_recvd != buflen) &&
   2735 	    (bytes_recvd > 0 ));
   2736 
   2737   /* put the request into host order */
   2738 
   2739   for (counter = 0; counter < count; counter++) {
   2740     request_array[counter] = ntohl(request_array[counter]);
   2741   }
   2742 
   2743   if (debug) {
   2744     fprintf(where,
   2745 	    "recv_request: received %d bytes of request.\n",
   2746 	    tot_bytes_recvd);
   2747     fflush(where);
   2748   }
   2749 
   2750   if (bytes_recvd == SOCKET_ERROR) {
   2751     Print_errno(where,
   2752 		"recv_request: error on recv");
   2753     fflush(where);
   2754     close(server_sock);
   2755     return -1;
   2756   }
   2757 
   2758   if (bytes_recvd == 0) {
   2759     /* the remote has shutdown the control connection, we should shut
   2760        it down as well and return */
   2761     if (debug) {
   2762       fprintf(where,
   2763 	      "recv_request: remote requested shutdown of control\n");
   2764       fflush(where);
   2765     }
   2766 
   2767     close(server_sock);
   2768     return 0;
   2769   }
   2770 
   2771   if (tot_bytes_recvd < buflen) {
   2772     if (debug > 1)
   2773       dump_request();
   2774 
   2775     fprintf(where,
   2776 	    "recv_request: partial request received of %d bytes\n",
   2777 	    tot_bytes_recvd);
   2778     fflush(where);
   2779     close(server_sock);
   2780     return -1;
   2781   }
   2782 
   2783   if (debug > 1) {
   2784     dump_request();
   2785   }
   2786 
   2787   /* get the processor affinity request value from netperf this is a
   2788      kludge and I know it.  sgb 8/11/04  */
   2789 
   2790   local_proc_affinity = netperf_request.content.dummy;
   2791 
   2792   if (local_proc_affinity != -1) {
   2793     bind_to_specific_processor(local_proc_affinity,0);
   2794   }
   2795 
   2796   return buflen;
   2797 }
   2798 
   2799 /* receive a request, only converting the first n ints-worth of the
   2800    test-specific data via htonl() before sending on the
   2801    connection. the first two ints, which are before the test-specific
   2802    portion are always converted. raj 2008-02-05 */
   2803 
   2804 int
   2805 recv_request_n(int n)
   2806 {
   2807 
   2808   return recv_request_timed_n(n,0);
   2809 
   2810 }
   2811 
   2812  /***********************************************************************/
   2813  /*                                                                     */
   2814  /*     recv_request()                                                  */
   2815  /*                                                                     */
   2816  /* receive the remote's request on the control socket. we will put     */
   2817  /* the entire response into host order before giving it to the         */
   2818  /* calling routine. hopefully, this will go most of the way to         */
   2819  /* insuring intervendor interoperability. if there are any problems,   */
   2820  /* we will just punt the entire situation.                             */
   2821  /*                                                                     */
   2822  /***********************************************************************/
   2823 
   2824 int
   2825 recv_request()
   2826 {
   2827 
   2828   return recv_request_n(-1);
   2829 
   2830 }
   2831 
   2832 void
   2833 recv_response_timed_n(int addl_time, int n)
   2834 {
   2835   int     tot_bytes_recvd,
   2836           bytes_recvd = 0,
   2837           bytes_left;
   2838   char    *buf = (char *)&netperf_response;
   2839   int     buflen = sizeof(netperf_response);
   2840   int     counter,count;
   2841 
   2842   /* stuff for select, use fd_set for better compliance */
   2843   fd_set  readfds;
   2844   struct  timeval timeout;
   2845 
   2846   tot_bytes_recvd = 0;
   2847   bytes_left      = buflen;
   2848 
   2849   if (n < 0) count = sizeof(netperf_request)/4;
   2850   else count = 2 + n;
   2851 
   2852   /* silently truncate if the caller called for more than we have */
   2853   if (count > sizeof(netperf_request)/4) {
   2854     if (debug > 1) {
   2855       fprintf(where,
   2856 	      "WARNING, htonl conversion count of %d was larger than netperf_response\n",
   2857 	      count - 2);
   2858       fflush(where);
   2859     }
   2860     count = sizeof(netperf_request)/4;
   2861   }
   2862 
   2863   /* zero out the response structure */
   2864 
   2865   /* BUG FIX SJB 2/4/93 - should be < not <= */
   2866   for (counter = 0;
   2867        counter < sizeof(netperf_response)/sizeof(int);
   2868        counter++) {
   2869     response_array[counter] = 0;
   2870   }
   2871 
   2872   /* we only select once. it is assumed that if the response is split
   2873      (which should not be happening, that we will receive the whole
   2874      thing and not have a problem ;-) */
   2875 
   2876   FD_ZERO(&readfds);
   2877   FD_SET(netlib_control,&readfds);
   2878   timeout.tv_sec  = 120 + addl_time;  /* wait at least two minutes
   2879 					 before punting - the
   2880 					 USE_LOOPER CPU stuff may
   2881 					 cause remote's to have a bit
   2882 					 longer time of it than 60
   2883 					 seconds would allow.
   2884 					 triggered by fix from Jeff
   2885 					 Dwork. */
   2886   timeout.tv_usec = 0;
   2887 
   2888   /* select had better return one, or there was either a problem or a */
   2889   /* timeout... */
   2890 
   2891   if ((counter = select(FD_SETSIZE,
   2892 			&readfds,
   2893 			0,
   2894 			0,
   2895 			&timeout)) != 1) {
   2896     fprintf(where,
   2897 	    "%s: no response received. errno %d counter %d\n",
   2898 	    __FUNCTION__,
   2899 	    errno,
   2900 	    counter);
   2901     exit(1);
   2902   }
   2903 
   2904   while ((tot_bytes_recvd != buflen) &&
   2905 	 ((bytes_recvd = recv(netlib_control, buf, bytes_left,0)) > 0 )) {
   2906     tot_bytes_recvd += bytes_recvd;
   2907     buf             += bytes_recvd;
   2908     bytes_left      -= bytes_recvd;
   2909   }
   2910 
   2911   if (debug) {
   2912     fprintf(where,"recv_response: received a %d byte response\n",
   2913 	    tot_bytes_recvd);
   2914     fflush(where);
   2915   }
   2916 
   2917   /* put the desired quantity of the response into host order */
   2918 
   2919   for (counter = 0; counter < count; counter++) {
   2920     response_array[counter] = ntohl(response_array[counter]);
   2921   }
   2922 
   2923   if (bytes_recvd == SOCKET_ERROR) {
   2924     perror("recv_response");
   2925     exit(1);
   2926   }
   2927   if (tot_bytes_recvd < buflen) {
   2928     fprintf(stderr,
   2929 	    "recv_response: partial response received: %d bytes\n",
   2930 	    tot_bytes_recvd);
   2931     fflush(stderr);
   2932     if (debug > 1)
   2933       dump_response();
   2934     exit(1);
   2935   }
   2936   if (debug > 1) {
   2937     dump_response();
   2938   }
   2939 }
   2940 
   2941 /*
   2942 
   2943   recv_response_timed()
   2944 
   2945   receive the remote's response on the control socket. we will put the
   2946   entire response into host order before giving it to the calling
   2947   routine. hopefully, this will go most of the way to insuring
   2948   intervendor interoperability. if there are any problems, we will
   2949   just punt the entire situation.
   2950 
   2951   The call to select at the beginning is to get us out of hang
   2952   situations where the remote gives-up but we don't find-out about
   2953   it. This seems to happen only rarely, but it would be nice to be
   2954   somewhat robust ;-)
   2955 
   2956   The "_timed" part is to allow the caller to add (or I suppose
   2957   subtract) from the length of timeout on the select call. this was
   2958   added since not all the CPU utilization mechanisms require a 40
   2959   second calibration, and we used to have an aribtrary 40 second sleep
   2960   in "calibrate_remote_cpu" - since we don't _always_ need that, we
   2961   want to simply add 40 seconds to the select() timeout from that
   2962   call, but don't want to change all the "recv_response" calls in the
   2963   code right away.  sooo, we push the functionality of the old
   2964   recv_response() into a new recv_response_timed(addl_timout) call,
   2965   and have recv_response() call recv_response_timed(0).  raj
   2966   2005-05-16
   2967 
   2968  */
   2969 
   2970 
   2971 void
   2972 recv_response_timed(int addl_time)
   2973 {
   2974 
   2975   /* -1 => convert all the test-specific data via ntohl */
   2976   recv_response_timed_n(addl_time,-1);
   2977 
   2978 }
   2979 
   2980 void
   2981 recv_response()
   2982 {
   2983   /* 0 => no additional time, -1 => convert all test-specific data */
   2984   recv_response_timed_n(0,-1);
   2985 }
   2986 
   2987 void
   2988 recv_response_n(int n)
   2989 {
   2990   recv_response_timed_n(0,n);
   2991 }
   2992 
   2993 
   2994 
   2995 
   2997 #if defined(USE_PSTAT) || defined (USE_SYSCTL)
   2998 int
   2999 hi_32(big_int)
   3000      long long *big_int;
   3001 {
   3002   union overlay_u {
   3003     long long  dword;
   3004     long       words[2];
   3005   } *overlay;
   3006 
   3007   overlay = (union overlay_u *)big_int;
   3008   /* on those systems which are byte swapped, we really wish to return
   3009      words[1] - at least I think so - raj 4/95 */
   3010   if (htonl(1L) == 1L) {
   3011     /* we are a "normal" :) machine */
   3012     return(overlay->words[0]);
   3013   }
   3014   else {
   3015     return(overlay->words[1]);
   3016   }
   3017 }
   3018 
   3019 int
   3020 lo_32(big_int)
   3021      long long *big_int;
   3022 {
   3023   union overlay_u {
   3024     long long  dword;
   3025     long       words[2];
   3026   } *overlay;
   3027 
   3028   overlay = (union overlay_u *)big_int;
   3029   /* on those systems which are byte swapped, we really wish to return
   3030      words[0] - at least I think so - raj 4/95 */
   3031   if (htonl(1L) == 1L) {
   3032     /* we are a "normal" :) machine */
   3033     return(overlay->words[1]);
   3034   }
   3035   else {
   3036     return(overlay->words[0]);
   3037   }
   3038 }
   3039 
   3040 #endif /* USE_PSTAT || USE_SYSCTL */
   3041 
   3042 
   3044 void libmain()
   3045 {
   3046 fprintf(where,"hello world\n");
   3047 fprintf(where,"debug: %d\n",debug);
   3048 }
   3049 
   3050 
   3051 void
   3053 get_sock_buffer (SOCKET sd, enum sock_buffer which, int *effective_sizep)
   3054 {
   3055 #ifdef SO_SNDBUF
   3056   int optname = (which == SEND_BUFFER) ? SO_SNDBUF : SO_RCVBUF;
   3057   netperf_socklen_t sock_opt_len;
   3058 
   3059   sock_opt_len = sizeof(*effective_sizep);
   3060   if (getsockopt(sd, SOL_SOCKET, optname, (char *)effective_sizep,
   3061 		 &sock_opt_len) < 0) {
   3062     fprintf(where, "netperf: get_sock_buffer: getsockopt %s: errno %d\n",
   3063 	    (which == SEND_BUFFER) ? "SO_SNDBUF" : "SO_RCVBUF", errno);
   3064     fflush(where);
   3065     *effective_sizep = -1;
   3066   }
   3067 
   3068   if (debug) {
   3069     fprintf(where, "netperf: get_sock_buffer: "
   3070 	    "%s socket size determined to be %d\n",
   3071 	    (which == SEND_BUFFER) ? "send" : "receive", *effective_sizep);
   3072     fflush(where);
   3073   }
   3074 
   3075 #else
   3076   *effective_sizep = -1;
   3077 #endif
   3078 }
   3079 
   3080 void
   3081 set_sock_buffer (SOCKET sd, enum sock_buffer which, int requested_size, int *effective_sizep)
   3082 {
   3083 #ifdef SO_SNDBUF
   3084 
   3085   int optname = (which == SEND_BUFFER) ? SO_SNDBUF : SO_RCVBUF;
   3086 
   3087   /* seems that under Windows, setting a value of zero is how one
   3088      tells the stack you wish to enable copy-avoidance. Knuth only
   3089      knows what it will do on other stacks, but it might be
   3090      interesting to find-out, so we won't bother #ifdef'ing the change
   3091      to allow asking for 0 bytes. Courtesy of SAF, 2007-05 raj
   3092      2007-05-31 */
   3093   if (requested_size >= 0) {
   3094     if (setsockopt(sd, SOL_SOCKET, optname,
   3095 		   (char *)&requested_size, sizeof(int)) < 0) {
   3096       fprintf(where, "netperf: set_sock_buffer: %s option: errno %d (%s)\n",
   3097 	      (which == SEND_BUFFER) ? "SO_SNDBUF" : "SO_RCVBUF",
   3098 	      errno,
   3099 	      strerror(errno));
   3100       fflush(where);
   3101       exit(1);
   3102     }
   3103     if (debug > 1) {
   3104       fprintf(where, "netperf: set_sock_buffer: %s of %d requested.\n",
   3105 	      (which == SEND_BUFFER) ? "SO_SNDBUF" : "SO_RCVBUF",
   3106 	      requested_size);
   3107       fflush(where);
   3108     }
   3109   }
   3110 
   3111   /* the getsockopt() call that used to be here has been hoisted into
   3112      its own routine to be used on those platforms where the socket
   3113      buffer sizes might change from the beginning to the end of the
   3114      run. raj 2008-01-15 */
   3115 
   3116   get_sock_buffer(sd, which, effective_sizep);
   3117 
   3118 #else /* SO_SNDBUF */
   3119   *effective_sizep = -1;
   3120 #endif /* SO_SNDBUF */
   3121 }
   3122 
   3123 void
   3124 dump_addrinfo(FILE *dumploc, struct addrinfo *info,
   3125               const char *host, char *port, int family)
   3126 {
   3127   struct sockaddr *ai_addr;
   3128   struct addrinfo *temp;
   3129   temp=info;
   3130 
   3131   fprintf(dumploc,
   3132 	  "getaddrinfo returned the following for host '%s' port '%s' "
   3133 	  " family %s\n",
   3134 	  host,
   3135 	  port,
   3136 	  inet_ftos(family));
   3137 
   3138   while (temp) {
   3139     /* seems that Solaris 10 GA bits will not give a canonical name
   3140        for ::0 or 0.0.0.0, and their fprintf() cannot deal with a null
   3141        pointer, so we have to check for a null pointer.  probably a
   3142        safe thing to do anyway, eventhough it was not necessary on
   3143        linux or hp-ux. raj 2005-02-09 */
   3144     fprintf(dumploc,
   3145 	    "\tcannonical name: '%s'\n"
   3146             "\tflags: %x family: %s: socktype: %s protocol %s addrlen %d\n",
   3147 	    (temp->ai_canonname) ? temp->ai_canonname : "(nil)",
   3148             temp->ai_flags,
   3149             inet_ftos(temp->ai_family),
   3150             inet_ttos(temp->ai_socktype),
   3151             inet_ptos(temp->ai_protocol),
   3152             temp->ai_addrlen);
   3153     ai_addr = temp->ai_addr;
   3154     if (ai_addr != NULL) {
   3155       int i;
   3156       fprintf(dumploc,
   3157               "\tsa_family: %s sadata:",
   3158               inet_ftos(ai_addr->sa_family));
   3159       for (i = 0; i < (int) temp->ai_addrlen; i++) {
   3160 	fprintf(dumploc,
   3161 		(temp->ai_family == AF_INET) ? " %d" : " %.2x",
   3162 		(u_char)ai_addr->sa_data[i]);
   3163       }
   3164       fprintf(dumploc,"\n");
   3165     }
   3166     temp = temp->ai_next;
   3167   }
   3168   fflush(dumploc);
   3169 }
   3170 
   3171 struct addrinfo *
   3172 resolve_host(char *hostname,
   3173 	     char *port,
   3174 	     int   family)
   3175 {
   3176   struct addrinfo   hints;
   3177   struct addrinfo  *ai;
   3178   int count;
   3179   int error;
   3180 
   3181   if (debug) {
   3182     fprintf(where,
   3183             "resolve_host called with host '%s' port '%s' family %s\n",
   3184             hostname,
   3185             port,
   3186             inet_ftos(family));
   3187     fflush(where);
   3188   }
   3189 
   3190   memset(&hints, 0, sizeof(hints));
   3191   hints.ai_family = family;
   3192   hints.ai_socktype = SOCK_STREAM;
   3193   hints.ai_protocol = IPPROTO_TCP;
   3194   hints.ai_flags = AI_CANONNAME | AI_ADDRCONFIG;
   3195   count = 0;
   3196   do {
   3197     error = getaddrinfo((char *)hostname,
   3198                         (char *)port,
   3199                         &hints,
   3200                         &ai);
   3201     count += 1;
   3202     if (error == EAI_AGAIN) {
   3203       if (debug) {
   3204         fprintf(where,"Sleeping on getaddrinfo EAI_AGAIN\n");
   3205         fflush(where);
   3206       }
   3207       sleep(1);
   3208     }
   3209   } while ((error == EAI_AGAIN) && (count <= 5));
   3210 
   3211   if (error) {
   3212     printf("%s: could not resolve host '%s' port '%s' af %s"
   3213 	   "\n\tgetaddrinfo returned %d %s\n",
   3214 	   __FUNCTION__,
   3215            hostname,
   3216            port,
   3217            inet_ftos(family),
   3218            error,
   3219            gai_strerror(error));
   3220     return(NULL);
   3221   }
   3222 
   3223   if (debug) {
   3224     dump_addrinfo(where, ai, hostname, port, family);
   3225   }
   3226 
   3227   return (ai);
   3228 }
   3229 
   3230 /*
   3231   establish_control()
   3232 
   3233   set-up the control connection between netperf and the netserver so
   3234   we can actually run some tests. if we cannot establish the control
   3235   connection, that may or may not be a good thing, so we will let the
   3236   caller decide what to do.
   3237 
   3238   to assist with pesky end-to-end-unfriendly things like firewalls, we
   3239   allow the caller to specify both the remote hostname and port, and
   3240   the local addressing info.  i believe that in theory it is possible
   3241 
   3242   another, but for the time being, we are only going to take-in one
   3243   requested address family parameter. this means that the only way
   3244   (iirc) that we might get a mixed-mode connection would be if the
   3245   address family is specified as AF_UNSPEC, and getaddrinfo() returns
   3246   different families for the local and server names.
   3247 
   3248   the "names" can also be IP addresses in ASCII string form.
   3249 
   3250   raj 2003-02-27 */
   3251 
   3252 SOCKET
   3253 establish_control_internal(char *hostname,
   3254 			   char *port,
   3255 			   int   remfam,
   3256 			   char *localhost,
   3257 			   char *localport,
   3258 			   int   locfam)
   3259 {
   3260   int not_connected;
   3261   SOCKET control_sock;
   3262 
   3263   struct addrinfo  *local_res;
   3264   struct addrinfo  *remote_res;
   3265   struct addrinfo  *local_res_temp;
   3266   struct addrinfo  *remote_res_temp;
   3267 
   3268   remote_res = resolve_host(hostname, port, remfam);
   3269   if (!remote_res)
   3270     return(INVALID_SOCKET);
   3271 
   3272   local_res = resolve_host(localhost, localport, locfam);
   3273   if (!local_res)
   3274     return(INVALID_SOCKET);
   3275 
   3276   if (debug) {
   3277     fprintf(where,
   3278             "establish_control called with host '%s' port '%s' remfam %s\n"
   3279             "\t\tlocal '%s' port '%s' locfam %s\n",
   3280             hostname,
   3281             port,
   3282             inet_ftos(remfam),
   3283             localhost,
   3284             localport,
   3285             inet_ftos(locfam));
   3286     fflush(where);
   3287   }
   3288 
   3289   not_connected = 1;
   3290   local_res_temp = local_res;
   3291   remote_res_temp = remote_res;
   3292   /* we want to loop through all the possibilities. looping on the
   3293      local addresses will be handled within the while loop.  I suppose
   3294      these is some more "C-expert" way to code this, but it has not
   3295      lept to mind just yet :) raj 2003-02024 */
   3296 
   3297   while (remote_res_temp != NULL) {
   3298 
   3299     /* I am guessing that we should use the address family of the
   3300        local endpoint, and we will not worry about mixed family types
   3301        - presumeably the stack or other transition mechanisms will be
   3302        able to deal with that for us. famous last words :) raj
   3303        2003-02-26 */
   3304     control_sock = socket(local_res_temp->ai_family,
   3305                           SOCK_STREAM,
   3306                           0);
   3307     if (control_sock == INVALID_SOCKET) {
   3308       /* at some point we'll need a more generic "display error"
   3309          message for when/if we use GUIs and the like. unlike a bind
   3310          or connect failure, failure to allocate a socket is
   3311          "immediately fatal" and so we return to the caller. raj
   3312          2003-02-24 */
   3313       if (debug) {
   3314         perror("establish_control: unable to allocate control socket");
   3315       }
   3316       return(INVALID_SOCKET);
   3317     }
   3318 
   3319     /* if we are going to control the local enpoint addressing, we
   3320        need to call bind. of course, we should probably be setting one
   3321        of the SO_REUSEmumble socket options? raj 2005-02-04 */
   3322     if (bind(control_sock,
   3323 	     local_res_temp->ai_addr,
   3324 	     local_res_temp->ai_addrlen) == 0) {
   3325       if (debug) {
   3326 	fprintf(where,
   3327 		"bound control socket to %s and %s\n",
   3328 		localhost,
   3329 		localport);
   3330       }
   3331 
   3332       if (connect(control_sock,
   3333 		  remote_res_temp->ai_addr,
   3334 		  remote_res_temp->ai_addrlen) == 0) {
   3335 	/* we have successfully connected to the remote netserver */
   3336 	if (debug) {
   3337 	  fprintf(where,
   3338 		  "successful connection to remote netserver at %s and %s\n",
   3339 		  hostname,
   3340 		  port);
   3341 	}
   3342 	not_connected = 0;
   3343 	/* this should get us out of the while loop */
   3344 	break;
   3345       } else {
   3346 	/* the connect call failed */
   3347 	if (debug) {
   3348 	  fprintf(where,
   3349 		  "establish_control: connect failed, errno %d %s\n"
   3350 		  "    trying next address combination\n",
   3351 		  errno,
   3352 		  strerror(errno));
   3353 	  fflush(where);
   3354 	}
   3355       }
   3356     }
   3357     else {
   3358       /* the bind failed */
   3359       if (debug) {
   3360 	fprintf(where,
   3361 		"establish_control: bind failed, errno %d %s\n"
   3362 		"    trying next address combination\n",
   3363 		errno,
   3364 		strerror(errno));
   3365 	fflush(where);
   3366       }
   3367     }
   3368 
   3369     if ((local_res_temp = local_res_temp->ai_next) == NULL) {
   3370       /* wrap the local and move to the next server, don't forget to
   3371          close the current control socket. raj 2003-02-24 */
   3372       local_res_temp = local_res;
   3373       /* the outer while conditions will deal with the case when we
   3374          get to the end of all the possible remote addresses. */
   3375       remote_res_temp = remote_res_temp->ai_next;
   3376       /* it is simplest here to just close the control sock. since
   3377          this is not a performance critical section of code, we
   3378          don't worry about overheads for socket allocation or
   3379          close. raj 2003-02-24 */
   3380     }
   3381     close(control_sock);
   3382   }
   3383 
   3384   control_family = local_res_temp->ai_family;
   3385 
   3386   /* we no longer need the addrinfo stuff */
   3387   freeaddrinfo(local_res);
   3388   freeaddrinfo(remote_res);
   3389 
   3390   /* so, we are either connected or not */
   3391   if (not_connected) {
   3392     fprintf(where,
   3393 	    "establish control: are you sure there is a netserver "
   3394 	    "listening on %s at port %s?\n",
   3395 	    hostname,
   3396 	    port);
   3397     fflush(where);
   3398     control_family = AF_UNSPEC;
   3399     return(INVALID_SOCKET);
   3400   }
   3401   /* at this point, we are connected.  we probably want some sort of
   3402      version check with the remote at some point. raj 2003-02-24 */
   3403   return(control_sock);
   3404 }
   3405 
   3406 void
   3407 establish_control(char *hostname,
   3408 		  char *port,
   3409 		  int   remfam,
   3410 		  char *localhost,
   3411 		  char *localport,
   3412 		  int   locfam)
   3413 
   3414 {
   3415 
   3416   netlib_control = establish_control_internal(hostname,
   3417 					      port,
   3418 					      remfam,
   3419 					      localhost,
   3420 					      localport,
   3421 					      locfam);
   3422   if (netlib_control == INVALID_SOCKET) {
   3423     fprintf(where,
   3424 	    "establish_control could not establish the control"
   3425 	    " connection from %s port %s address family %s to %s"
   3426 	    " port %s address family %s\n",
   3427 	    localhost,localport,inet_ftos(locfam),
   3428 	    hostname,port,inet_ftos(remfam));
   3429     fflush(where);
   3430     exit(INVALID_SOCKET);
   3431   }
   3432 }
   3433 
   3434 
   3435 
   3437 
   3438  /***********************************************************************/
   3439  /*                                                                     */
   3440  /*     get_id()                                                        */
   3441  /*                                                                     */
   3442  /* Return a string to the calling routine that contains the            */
   3443  /* identifying information for the host we are running on. This        */
   3444  /* information will then either be displayed locally, or returned to   */
   3445  /* a remote caller for display there.                                  */
   3446  /*                                                                     */
   3447  /***********************************************************************/
   3448 
   3449 char *
   3450 get_id()
   3451 {
   3452 	static char id_string[80];
   3453 #ifdef WIN32
   3454 char                    system_name[MAX_COMPUTERNAME_LENGTH+1] ;
   3455 DWORD                   name_len = MAX_COMPUTERNAME_LENGTH + 1 ;
   3456 #else
   3457 struct  utsname         system_name;
   3458 #endif /* WIN32 */
   3459 
   3460 #ifdef WIN32
   3461  SYSTEM_INFO SystemInfo;
   3462  GetSystemInfo( &SystemInfo ) ;
   3463  if ( !GetComputerName(system_name , &name_len) )
   3464    strcpy(system_name , "no_name") ;
   3465 #else
   3466  if (uname(&system_name) <0) {
   3467    perror("identify_local: uname");
   3468    exit(1);
   3469  }
   3470 #endif /* WIN32 */
   3471 
   3472  snprintf(id_string, sizeof(id_string),
   3473 #ifdef WIN32
   3474 	  "%-15s%-15s%d.%d%d",
   3475 	  "Windows NT",
   3476 	  system_name ,
   3477 	  GetVersion() & 0xFF ,
   3478 	  GetVersion() & 0xFF00 ,
   3479 	  SystemInfo.dwProcessorType
   3480 
   3481 #else
   3482 	  "%-15s%-15s%-15s%-15s%-15s",
   3483 	  system_name.sysname,
   3484 	  system_name.nodename,
   3485 	  system_name.release,
   3486 	  system_name.version,
   3487 	  system_name.machine
   3488 #endif /* WIN32 */
   3489 	  );
   3490  return (id_string);
   3491 }
   3492 
   3493 
   3494  /***********************************************************************/
   3495  /*                                                                     */
   3496  /*     identify_local()                                                */
   3497  /*                                                                     */
   3498  /* Display identifying information about the local host to the user.   */
   3499  /* At first release, this information will be the same as that which   */
   3500  /* is returned by the uname -a command, with the exception of the      */
   3501  /* idnumber field, which seems to be a non-POSIX item, and hence       */
   3502  /* non-portable.                                                       */
   3503  /*                                                                     */
   3504  /***********************************************************************/
   3505 
   3506 void
   3507 identify_local()
   3508 {
   3509 
   3510 char *local_id;
   3511 
   3512 local_id = get_id();
   3513 
   3514 fprintf(where,"Local Information \n\
   3515 Sysname       Nodename       Release        Version        Machine\n");
   3516 
   3517 fprintf(where,"%s\n",
   3518        local_id);
   3519 
   3520 }
   3521 
   3522 
   3523  /***********************************************************************/
   3524  /*                                                                     */
   3525  /*     identify_remote()                                               */
   3526  /*                                                                     */
   3527  /* Display identifying information about the remote host to the user.  */
   3528  /* At first release, this information will be the same as that which   */
   3529  /* is returned by the uname -a command, with the exception of the      */
   3530  /* idnumber field, which seems to be a non-POSIX item, and hence       */
   3531  /* non-portable. A request is sent to the remote side, which will      */
   3532  /* return a string containing the utsname information in a             */
   3533  /* pre-formatted form, which is then displayed after the header.       */
   3534  /*                                                                     */
   3535  /***********************************************************************/
   3536 
   3537 void
   3538 identify_remote()
   3539 {
   3540 
   3541   char    *remote_id="";
   3542 
   3543   /* send a request for node info to the remote */
   3544   netperf_request.content.request_type = NODE_IDENTIFY;
   3545 
   3546   send_request();
   3547 
   3548   /* and now wait for the reply to come back */
   3549 
   3550   recv_response();
   3551 
   3552   if (netperf_response.content.serv_errno) {
   3553     Set_errno(netperf_response.content.serv_errno);
   3554     perror("identify_remote: on remote");
   3555     exit(1);
   3556   }
   3557 
   3558   fprintf(where,"Remote Information \n\
   3559 Sysname       Nodename       Release        Version        Machine\n");
   3560 
   3561   fprintf(where,"%s",
   3562 	  remote_id);
   3563 }
   3564 
   3565 void
   3566 cpu_start(int measure_cpu)
   3567 {
   3568 
   3569   gettimeofday(&time1,
   3570                &tz);
   3571 
   3572   if (measure_cpu) {
   3573     cpu_util_init();
   3574     measuring_cpu = 1;
   3575     cpu_method = get_cpu_method();
   3576     cpu_start_internal();
   3577   }
   3578 }
   3579 
   3580 
   3581 void
   3583 cpu_stop(int measure_cpu, float *elapsed)
   3584 
   3585 {
   3586 
   3587   int     sec,
   3588     usec;
   3589 
   3590   if (measure_cpu) {
   3591     cpu_stop_internal();
   3592     cpu_util_terminate();
   3593   }
   3594 
   3595   gettimeofday(&time2,
   3596 	       &tz);
   3597 
   3598   if (time2.tv_usec < time1.tv_usec) {
   3599     time2.tv_usec += 1000000;
   3600     time2.tv_sec  -= 1;
   3601   }
   3602 
   3603   sec     = time2.tv_sec - time1.tv_sec;
   3604   usec    = time2.tv_usec - time1.tv_usec;
   3605   lib_elapsed     = (float)sec + ((float)usec/(float)1000000.0);
   3606 #ifdef WIN32
   3607   if (timed_out) lib_elapsed-=PAD_TIME/2;
   3608 #endif
   3609   *elapsed = lib_elapsed;
   3610 
   3611 }
   3612 
   3613 
   3614 double
   3615 calc_thruput_interval(double units_received,double elapsed)
   3616 
   3617 {
   3618   double        divisor;
   3619 
   3620   /* We will calculate the thruput in libfmt units/second */
   3621   switch (libfmt) {
   3622   case 'K':
   3623     divisor = 1024.0;
   3624     break;
   3625   case 'M':
   3626     divisor = 1024.0 * 1024.0;
   3627     break;
   3628   case 'G':
   3629     divisor = 1024.0 * 1024.0 * 1024.0;
   3630     break;
   3631   case 'k':
   3632     divisor = 1000.0 / 8.0;
   3633     break;
   3634   case 'm':
   3635     divisor = 1000.0 * 1000.0 / 8.0;
   3636     break;
   3637   case 'g':
   3638     divisor = 1000.0 * 1000.0 * 1000.0 / 8.0;
   3639     break;
   3640   case 'x':
   3641   case 'b':
   3642   case 'B':
   3643     divisor = 1.0;
   3644     break;
   3645   case 'u':
   3646     /* latency in microseconds a bit squirrely but we don't want to
   3647        really muck with things for the default return statement.
   3648        invert transactions per second and multiply to get microseconds
   3649        per transaction */
   3650     return (1 / (units_received / elapsed)) * 1000000.0;
   3651 
   3652   default:
   3653     divisor = 1024.0;
   3654   }
   3655 
   3656   return (units_received / divisor / elapsed);
   3657 
   3658 }
   3659 
   3660 double
   3661 calc_thruput(double units_received)
   3662 
   3663 {
   3664   return(calc_thruput_interval(units_received,lib_elapsed));
   3665 }
   3666 
   3667 /* these "_omni" versions are ones which understand 'x' as a unit,
   3668    meaning transactions/s.  we have a separate routine rather than
   3669    convert the existing routine so we don't have to go and change
   3670    _all_ the nettest_foo.c files at one time.  raj 2007-06-08 */
   3671 
   3672 double
   3673 calc_thruput_interval_omni(double units_received,double elapsed)
   3674 
   3675 {
   3676   double        divisor;
   3677 
   3678   /* We will calculate the thruput in libfmt units/second */
   3679   switch (libfmt) {
   3680   case 'K':
   3681     divisor = 1024.0;
   3682     break;
   3683   case 'M':
   3684     divisor = 1024.0 * 1024.0;
   3685     break;
   3686   case 'G':
   3687     divisor = 1024.0 * 1024.0 * 1024.0;
   3688     break;
   3689   case 'k':
   3690     divisor = 1000.0 / 8.0;
   3691     break;
   3692   case 'm':
   3693     divisor = 1000.0 * 1000.0 / 8.0;
   3694     break;
   3695   case 'g':
   3696     divisor = 1000.0 * 1000.0 * 1000.0 / 8.0;
   3697     break;
   3698   case 'x':
   3699   case 'b':
   3700   case 'B':
   3701     divisor = 1.0;
   3702     break;
   3703   case 'u':
   3704     /* latency in microseconds a bit squirrely but we don't want to
   3705        really muck with things for the default return statement.
   3706        invert transactions per second and multiply to get microseconds
   3707        per transaction */
   3708     return (1 / (units_received / elapsed)) * 1000000.0;
   3709 
   3710   default:
   3711     fprintf(where,
   3712 	    "WARNING calc_throughput_internal_omni: unknown units %c\n",
   3713 	    libfmt);
   3714     fflush(where);
   3715     divisor = 1024.0;
   3716   }
   3717 
   3718   return (units_received / divisor / elapsed);
   3719 
   3720 }
   3721 
   3722 double
   3723 calc_thruput_omni(double units_received)
   3724 
   3725 {
   3726   return(calc_thruput_interval_omni(units_received,lib_elapsed));
   3727 }
   3728 
   3729 
   3730 
   3732 
   3733 
   3734 float
   3735 calc_cpu_util(float elapsed_time)
   3736 {
   3737   float temp_util;
   3738   int i;
   3739   temp_util = calc_cpu_util_internal(elapsed_time);
   3740 
   3741   /* now, what was the most utilized CPU and its util? */
   3742   for (i = 0; i < MAXCPUS; i++) {
   3743     if (lib_local_per_cpu_util[i] > lib_local_cpu_stats.peak_cpu_util) {
   3744       lib_local_cpu_stats.peak_cpu_util = lib_local_per_cpu_util[i];
   3745       lib_local_cpu_stats.peak_cpu_id = lib_cpu_map[i];
   3746     }
   3747   }
   3748 
   3749   return temp_util;
   3750 }
   3751 
   3752 float
   3753 calc_service_demand_internal(double unit_divisor,
   3754 			     double units_sent,
   3755 			     float elapsed_time,
   3756 			     float cpu_utilization,
   3757 			     int num_cpus)
   3758 
   3759 {
   3760 
   3761   double service_demand;
   3762   double thruput;
   3763 
   3764   if (debug) {
   3765     fprintf(where,
   3766 	    "calc_service_demand called:  units_sent = %f\n"
   3767 	    "                             elapsed_time = %f\n"
   3768 	    "                             cpu_util = %f\n"
   3769 	    "                             num cpu = %d\n",
   3770             units_sent,
   3771             elapsed_time,
   3772             cpu_utilization,
   3773             num_cpus);
   3774     fflush(where);
   3775   }
   3776 
   3777   if (num_cpus == 0) num_cpus = lib_num_loc_cpus;
   3778 
   3779   if (elapsed_time == 0.0) {
   3780     elapsed_time = lib_elapsed;
   3781   }
   3782   if (cpu_utilization == 0.0) {
   3783     cpu_utilization = lib_local_cpu_stats.cpu_util;
   3784   }
   3785 
   3786   thruput = (units_sent /
   3787              (double) unit_divisor /
   3788              (double) elapsed_time);
   3789 
   3790   /* on MP systems, it is necessary to multiply the service demand by
   3791      the number of CPU's. at least, I believe that to be the case:)
   3792      raj 10/95 */
   3793 
   3794   /* thruput has a "per second" component. if we were using 100% (
   3795      100.0) of the CPU in a second, that would be 1 second, or 1
   3796      millisecond, so we multiply cpu_utilization by 10 to go to
   3797      milliseconds, or 10,000 to go to micro seconds. With revision
   3798      2.1, the service demand measure goes to microseconds per unit.
   3799      raj 12/95 */
   3800   service_demand = (cpu_utilization*10000.0/thruput) *
   3801     (float) num_cpus;
   3802 
   3803   if (debug) {
   3804     fprintf(where,
   3805 	    "calc_service_demand using:   units_sent = %f\n"
   3806 	    "                             elapsed_time = %f\n"
   3807 	    "                             cpu_util = %f\n"
   3808 	    "                             num cpu = %d\n"
   3809 	    "calc_service_demand got:     thruput = %f\n"
   3810 	    "                             servdem = %f\n",
   3811             units_sent,
   3812             elapsed_time,
   3813             cpu_utilization,
   3814             num_cpus,
   3815             thruput,
   3816             service_demand);
   3817     fflush(where);
   3818   }
   3819   return (float)service_demand;
   3820 }
   3821 
   3822 float calc_service_demand(double units_sent,
   3823                           float elapsed_time,
   3824                           float cpu_utilization,
   3825                           int num_cpus)
   3826 
   3827 {
   3828 
   3829   double unit_divisor = (double)1024.0;
   3830 
   3831   return(calc_service_demand_internal(unit_divisor,
   3832 				      units_sent,
   3833 				      elapsed_time,
   3834 				      cpu_utilization,
   3835 				      num_cpus));
   3836 }
   3837 
   3838 /* use the value of libfmt to determine the unit_divisor */
   3839 float calc_service_demand_fmt(double units_sent,
   3840 			      float elapsed_time,
   3841 			      float cpu_utilization,
   3842 			      int num_cpus)
   3843 
   3844 {
   3845   double unit_divisor;
   3846 
   3847   if ('x' == libfmt) unit_divisor = 1.0;
   3848   else unit_divisor = 1024.0;
   3849 
   3850   return(calc_service_demand_internal(unit_divisor,
   3851 				      units_sent,
   3852 				      elapsed_time,
   3853 				      cpu_utilization,
   3854 				      num_cpus));
   3855 }
   3856 
   3857 
   3858 
   3860 float
   3861 calibrate_local_cpu(float local_cpu_rate)
   3862 {
   3863 
   3864   lib_num_loc_cpus = get_num_cpus();
   3865 
   3866   lib_use_idle = 0;
   3867 #ifdef USE_LOOPER
   3868   cpu_util_init();
   3869   lib_use_idle = 1;
   3870 #endif /* USE_LOOPER */
   3871 
   3872   if (local_cpu_rate > 0) {
   3873     /* The user think that he knows what the cpu rate is. We assume
   3874        that all the processors of an MP system are essentially the
   3875        same - for this reason we do not have a per processor maxrate.
   3876        if the machine has processors which are different in
   3877        performance, the CPU utilization will be skewed. raj 4/95 */
   3878     lib_local_maxrate = local_cpu_rate;
   3879   }
   3880   else {
   3881     /* if neither USE_LOOPER nor USE_PSTAT are defined, we return a
   3882        0.0 to indicate that times or getrusage should be used. raj
   3883        4/95 */
   3884     lib_local_maxrate = (float)0.0;
   3885 #if defined(USE_PROC_STAT) || defined(USE_LOOPER) || defined(USE_PSTAT) || defined(USE_KSTAT) || defined(USE_PERFSTAT) || defined(USE_SYSCTL)
   3886     lib_local_maxrate = calibrate_idle_rate(4,10);
   3887 #endif
   3888   }
   3889   return lib_local_maxrate;
   3890 }
   3891 
   3892 
   3893 float
   3894 calibrate_remote_cpu()
   3895 {
   3896   float remrate;
   3897 
   3898   netperf_request.content.request_type = CPU_CALIBRATE;
   3899   send_request();
   3900   /* we know that calibration will last at least 40 seconds, so go to
   3901      sleep for that long so the 60 second select in recv_response will
   3902      not pop. raj 7/95 */
   3903 
   3904   /* we know that CPU calibration may last as long as 40 seconds, so
   3905      make sure we "select" for at least that long while looking for
   3906      the response. raj 2005-05-16 */
   3907   recv_response_timed(40);
   3908 
   3909   if (netperf_response.content.serv_errno) {
   3910     /* initially, silently ignore remote errors and pass back a zero
   3911        to the caller this should allow us to mix rev 1.0 and rev 1.1
   3912        netperfs... */
   3913     return((float)0.0);
   3914   }
   3915   else {
   3916     /* the rate is the first word of the test_specific data */
   3917     bcopy((char *)netperf_response.content.test_specific_data,
   3918           (char *)&remrate,
   3919           sizeof(remrate));
   3920     bcopy((char *)netperf_response.content.test_specific_data + sizeof(remrate),
   3921 	  (char *)&lib_num_rem_cpus,
   3922 	  sizeof(lib_num_rem_cpus));
   3923 /*    remrate = (float) netperf_response.content.test_specific_data[0]; */
   3924     return(remrate);
   3925   }
   3926 }
   3927 
   3928 
   3929 
   3930 #ifndef WIN32
   3932 /* WIN32 requires that at least one of the file sets to select be
   3933    non-null.  Since msec_sleep routine is only called by nettest_dlpi
   3934    & nettest_unix, let's duck this issue. */
   3935 
   3936 int
   3937 msec_sleep( int msecs )
   3938 {
   3939   int           rval ;
   3940 
   3941   struct timeval timeout;
   3942 
   3943   timeout.tv_sec = msecs / 1000;
   3944   timeout.tv_usec = (msecs - (msecs/1000) *1000) * 1000;
   3945   if ((rval = select(0,
   3946              0,
   3947              0,
   3948              0,
   3949              &timeout))) {
   3950     if ( SOCKET_EINTR(rval) ) {
   3951       return(1);
   3952     }
   3953     perror("msec_sleep: select");
   3954     exit(1);
   3955   }
   3956   return(0);
   3957 }
   3958 #endif /* WIN32 */
   3959 
   3960 #if defined(WANT_INTERVALS) || defined(WANT_DEMO)
   3961 
   3962 int demo_mode;                    /* are we actually in demo mode? = 0
   3963 				     == not in demo mode; 1 == classic
   3964 				     unit based demo mode; 2 == always
   3965 				     timestamp demo mode */
   3966 double demo_interval = 1000000.0; /* what is the desired interval to
   3967 				     display interval results. default
   3968 				     is one second in units of
   3969 				     microseconds */
   3970 double demo_units = 0.0;          /* what is our current best guess as
   3971 				     to how many work units must be
   3972 				     done to be near the desired
   3973 				     reporting interval? */
   3974 
   3975 double units_this_tick;
   3976 #endif
   3977 
   3978 #ifdef WANT_DEMO
   3979 #ifdef HAVE_GETHRTIME
   3980 static hrtime_t demo_one;
   3981 static hrtime_t demo_two;
   3982 static hrtime_t *demo_one_ptr = &demo_one;
   3983 static hrtime_t *demo_two_ptr = &demo_two;
   3984 static hrtime_t *temp_demo_ptr = &demo_one;
   3985 #elif defined(WIN32)
   3986 static LARGE_INTEGER demo_one;
   3987 static LARGE_INTEGER demo_two;
   3988 static LARGE_INTEGER *demo_one_ptr = &demo_one;
   3989 static LARGE_INTEGER *demo_two_ptr = &demo_two;
   3990 static LARGE_INTEGER *temp_demo_ptr = &demo_one;
   3991 #else
   3992 static struct timeval demo_one;
   3993 static struct timeval demo_two;
   3994 static struct timeval *demo_one_ptr = &demo_one;
   3995 static struct timeval *demo_two_ptr = &demo_two;
   3996 static struct timeval *temp_demo_ptr = &demo_one;
   3997 #endif
   3998 
   3999 void demo_first_timestamp() {
   4000   HIST_timestamp(demo_one_ptr);
   4001 }
   4002 
   4003 void demo_reset() {
   4004   if (debug) {
   4005     fprintf(where,
   4006 	    "Resetting interim results\n");
   4007     fflush(where);
   4008   }
   4009   units_this_tick = 0;
   4010   demo_first_timestamp();
   4011 }
   4012 
   4013 /* for a _STREAM test, "a" should be lss_size and "b" should be
   4014    rsr_size. for a _MAERTS test, "a" should be lsr_size and "b" should
   4015    be rss_size. raj 2005-04-06 */
   4016 void demo_stream_setup(uint32_t a, uint32_t b) {
   4017   if ((demo_mode) && (demo_units == 0)) {
   4018     /* take our default value of demo_units to be the larger of
   4019        twice the remote's SO_RCVBUF or twice our SO_SNDBUF */
   4020     if (a > b) {
   4021       demo_units = 2*a;
   4022     }
   4023     else {
   4024       demo_units = 2*b;
   4025     }
   4026   }
   4027 }
   4028 
   4029 #ifdef WIN32
   4030 __forceinline void demo_interval_display(double actual_interval)
   4031 #else
   4032   inline void demo_interval_display(double actual_interval)
   4033 #endif
   4034 {
   4035   static int count = 0;
   4036   struct timeval now;
   4037 
   4038   gettimeofday(&now,NULL);
   4039   switch (netperf_output_mode) {
   4040   case HUMAN:
   4041     fprintf(where,
   4042 	    "Interim result: %7.2f %s/s over %.3f seconds ending at %ld.%.3ld\n",
   4043 	    calc_thruput_interval(units_this_tick,
   4044 				  actual_interval/1000000.0),
   4045 	    format_units(),
   4046 	    actual_interval/1000000.0,
   4047 	    now.tv_sec,
   4048 	    (long) now.tv_usec/1000);
   4049     break;
   4050   case CSV:
   4051     fprintf(where,
   4052 	    "%7.2f,%s/s,%.3f,%ld.%.3ld\n",
   4053 	    calc_thruput_interval(units_this_tick,
   4054 				  actual_interval/1000000.0),
   4055 	    format_units(),
   4056 	    actual_interval/1000000.0,
   4057 	    now.tv_sec,
   4058 	    (long) now.tv_usec/1000);
   4059     break;
   4060   case KEYVAL:
   4061     fprintf(where,
   4062 	    "NETPERF_INTERIM_RESULT[%d]=%.2f\n"
   4063 	    "NETPERF_UNITS[%d]=%s/s\n"
   4064 	    "NETPERF_INTERVAL[%d]=%.3f\n"
   4065 	    "NETPERF_ENDING[%d]=%ld.%.3ld\n",
   4066 	    count,
   4067 	    calc_thruput_interval(units_this_tick,
   4068 				  actual_interval/1000000.0),
   4069 	    count,
   4070 	    format_units(),
   4071 	    count,
   4072 	    actual_interval/1000000.0,
   4073 	    count,
   4074 	    now.tv_sec,
   4075 	    (long) now.tv_usec/1000);
   4076     count += 1;
   4077     break;
   4078   default:
   4079     fprintf(where,
   4080 	    "Hey Ricky you not fine, theres a bug at demo time. Hey Ricky!");
   4081     fflush(where);
   4082     exit(-1);
   4083   }
   4084   fflush(where);
   4085 }
   4086 
   4087 /* this has gotten long enough to warrant being an inline function
   4088    rather than a macro, and it has been enough years since all the
   4089    important compilers have supported such a construct so it should
   4090    not be a big deal. raj 2012-01-23 */
   4091 
   4092 #ifdef WIN32
   4093 /* It would seem that the Microsoft compiler will not inline across
   4094    source files. So there is little point in having an inline
   4095    directive in that situation.  Of course that makes me wonder if an
   4096    inline directive has to appear in netlib.h... */
   4097 void demo_interval_tick(uint32_t units)
   4098 #else
   4099   inline void demo_interval_tick(uint32_t units)
   4100 #endif
   4101 {
   4102   double actual_interval = 0.0;
   4103 
   4104   switch (demo_mode) {
   4105   case 0:
   4106     return;
   4107   case 1: /* use the unit accumulation first */
   4108     units_this_tick += units;
   4109     if (units_this_tick >= demo_units) {
   4110       /* time to possibly update demo_units and maybe output an
   4111 	 interim result */
   4112       HIST_timestamp(demo_two_ptr);
   4113       actual_interval = delta_micro(demo_one_ptr,demo_two_ptr);
   4114       /* we always want to fine-tune demo_units here whether we emit
   4115 	 an interim result or not.  if we are short, this will
   4116 	 lengthen demo_units.  if we are long, this will shorten it */
   4117       demo_units = demo_units * (demo_interval / actual_interval);
   4118     }
   4119     else
   4120       return;
   4121     break;
   4122   case 2:  /* Always timestamp */
   4123     units_this_tick += units;
   4124     HIST_timestamp(demo_two_ptr);
   4125     actual_interval = delta_micro(demo_one_ptr,demo_two_ptr);
   4126 
   4127     break;
   4128   default:
   4129     fprintf(where,
   4130 	    "Unexpected value of demo_mode of %d. Please report this as a bug.\n",
   4131 	    demo_mode);
   4132     fflush(where);
   4133     exit(-1);
   4134   }
   4135 
   4136 
   4137 
   4138   /* units == 0 will be when we have completed a test.  we want to
   4139      emit a final interim results if there is anything to report */
   4140   if (actual_interval >= demo_interval) {
   4141     /* time to emit an interim result, giving the current time to the
   4142        millisecond for compatability with RRD  */
   4143     demo_interval_display(actual_interval);
   4144     units_this_tick = 0.0;
   4145     /* now get a new starting timestamp.  we could be clever
   4146        and swap pointers - the math we do probably does not
   4147        take all that long, but for now this will suffice */
   4148     temp_demo_ptr = demo_one_ptr;
   4149     demo_one_ptr = demo_two_ptr;
   4150     demo_two_ptr = temp_demo_ptr;
   4151 
   4152   }
   4153 }
   4154 
   4155 void demo_interval_final() {
   4156   double actual_interval;
   4157 
   4158   switch (demo_mode) {
   4159   case 0:
   4160     return;
   4161   case 1:
   4162   case 2:
   4163     if (units_this_tick > 0.0) {
   4164       HIST_timestamp(demo_two_ptr);
   4165       actual_interval = delta_micro(demo_one_ptr,demo_two_ptr);
   4166       demo_interval_display(actual_interval);
   4167       units_this_tick = 0.0;
   4168     }
   4169   }
   4170 }
   4171 
   4172 void demo_stream_interval(uint32_t units) {
   4173   demo_interval_tick(units);
   4174 }
   4175 
   4176 void demo_rr_setup(uint32_t a) {
   4177   if ((demo_mode) && (demo_units == 0)) {
   4178     /* take whatever we are given */
   4179     demo_units = a;
   4180   }
   4181 }
   4182 
   4183 void demo_rr_interval(uint32_t units) {
   4184   demo_interval_tick(units);
   4185 }
   4186 
   4187 #endif
   4188 
   4189 /* hist.c
   4190 
   4191    Given a time difference in microseconds, increment one of 61
   4192    different buckets:
   4193 
   4194    0 - 9 in increments of 1 usec
   4195    0 - 9 in increments of 10 usecs
   4196    0 - 9 in increments of 100 usecs
   4197    1 - 9 in increments of 1 msec
   4198    1 - 9 in increments of 10 msecs
   4199    1 - 9 in increments of 100 msecs
   4200    1 - 9 in increments of 1 sec
   4201    1 - 9 in increments of 10 sec
   4202    > 100 secs
   4203 
   4204    This will allow any time to be recorded to within an accuracy of
   4205    10%, and provides a compact representation for capturing the
   4206    distribution of a large number of time differences (e.g.
   4207    request-response latencies).
   4208 
   4209    Colin Low  10/6/93
   4210    Rick Jones 2004-06-15 extend to unit and ten usecs
   4211 */
   4212 
   4213 /* #include "sys.h" */
   4214 
   4215 /*#define HIST_TEST*/
   4216 
   4217 HIST
   4218 HIST_new_n(int max_outstanding) {
   4219   HIST h;
   4220 
   4221   if((h = (HIST) malloc(sizeof(struct histogram_struct))) == NULL) {
   4222     perror("HIST_new_n - histogram_struct malloc failed");
   4223     exit(1);
   4224   }
   4225   HIST_clear(h);
   4226 
   4227   /* we never want to have a full queue, so will trade a little space
   4228      for that. one day we may still have to check for a full queue */
   4229   h->limit = max_outstanding + 1;
   4230 
   4231   /* now allocate the time_ones based on h->limit */
   4232 #ifdef HAVE_GETHRTIME
   4233   h->time_ones = (hrtime_t *) malloc(h->limit * sizeof(hrtime_t));
   4234 #elif HAVE_GET_HRT
   4235   h->time_ones = (hrt_t *) malloc(h->limit * sizeof(hrt_t));
   4236 #elif defined(WIN32)
   4237   h->time_ones = (LARGE_INTEGER *) malloc(h->limit *
   4238 					  sizeof(LARGE_INTEGER));
   4239 #else
   4240   h->time_ones = (struct timeval *) malloc(h->limit *
   4241 					   sizeof(struct timeval));
   4242 #endif /* HAVE_GETHRTIME */
   4243   if (h->time_ones == NULL) {
   4244     perror("HIST_new_n - time_ones malloc failed");
   4245     exit(1);
   4246   }
   4247 
   4248   return h;
   4249 }
   4250 
   4251 HIST
   4252 HIST_new(void){
   4253   return HIST_new_n(0);
   4254 }
   4255 
   4256 
   4257 void
   4258 HIST_clear(HIST h){
   4259    int i;
   4260    for(i = 0; i < HIST_NUM_OF_BUCKET; i++){
   4261       h->unit_usec[i] = 0;
   4262       h->ten_usec[i] = 0;
   4263       h->hundred_usec[i] = 0;
   4264       h->unit_msec[i] = 0;
   4265       h->ten_msec[i] = 0;
   4266       h->hundred_msec[i] = 0;
   4267       h->unit_sec[i] = 0;
   4268       h->ten_sec[i] = 0;
   4269    }
   4270    h->ridiculous = 0;
   4271    h->total = 0;
   4272    h->sum = 0;
   4273    h->sumsquare = 0;
   4274    h->hmin = 0;
   4275    h->hmax = 0;
   4276    h->limit = 0;
   4277    h->count = 0;
   4278    h->producer = 0;
   4279    h->consumer = 0;
   4280    h->time_ones = NULL;
   4281 }
   4282 
   4283 void
   4284 HIST_purge(HIST h) {
   4285   h->count = 0;
   4286   h->producer = 0;
   4287   h->consumer = 0;
   4288 }
   4289 
   4290 void
   4291 HIST_add(register HIST h, int time_delta){
   4292    register float val;
   4293    register int base = HIST_NUM_OF_BUCKET / 10;
   4294 
   4295    /* check for < 0 added via VMware ESX patches. */
   4296 
   4297    /* hoisted up to the top because we do not want to count any
   4298       ridiculous values in the actual statistics. right? raj
   4299       2011-07-28 */
   4300    if (time_delta < 0) {
   4301      h->ridiculous++;
   4302      return;
   4303    }
   4304 
   4305    if (!h->total)
   4306       h->hmin = h->hmax = time_delta;
   4307    h->total++;
   4308    h->sum += time_delta;
   4309    /* am I just being paranoid about the overhead of pow() when we
   4310       aren't all that interested in the statistics derived from it?
   4311       raj 20100914 */
   4312    if (keep_statistics) {
   4313      h->sumsquare += pow(time_delta, 2);
   4314    }
   4315    h->hmin = ((h->hmin < time_delta) ? h->hmin : time_delta);
   4316    h->hmax = ((h->hmax > time_delta) ? h->hmax : time_delta);
   4317    val = (float) time_delta;
   4318    if(val < 10) h->unit_usec[(int)(val * base)]++;
   4319    else {
   4320      val /= 10;
   4321      if(val < 10) h->ten_usec[(int)(val * base)]++;
   4322      else {
   4323        val /= 10;
   4324        if(val < 10) h->hundred_usec[(int)(val * base)]++;
   4325        else {
   4326 	 val /= 10;
   4327 	 if(val < 10) h->unit_msec[(int)(val * base)]++;
   4328 	 else {
   4329 	   val /= 10;
   4330 	   if(val < 10) h->ten_msec[(int)(val * base)]++;
   4331 	   else {
   4332 	     val /= 10;
   4333 	     if(val < 10) h->hundred_msec[(int)(val * base)]++;
   4334 	     else {
   4335                val /= 10;
   4336                if(val < 10) h->unit_sec[(int)(val * base)]++;
   4337                else {
   4338 		 val /= 10;
   4339 		 if(val < 10) h->ten_sec[(int)(val * base)]++;
   4340 		 else h->ridiculous++;
   4341                }
   4342 	     }
   4343 	   }
   4344 	 }
   4345        }
   4346      }
   4347    }
   4348 }
   4349 
   4350 void
   4351 output_row(FILE *fd, char *title, int *row){
   4352   register int i;
   4353   register int j;
   4354   register int base =  HIST_NUM_OF_BUCKET / 10;
   4355   register int sum;
   4356   fprintf(where,"%s", title);
   4357   for(i = 0; i < 10; i++){
   4358     sum = 0;
   4359     for (j = i * base; j <  (i + 1) * base; j++) {
   4360       sum += row[j];
   4361     }
   4362     fprintf(where,": %4d", sum);
   4363   }
   4364   fprintf(where,"\n");
   4365 }
   4366 
   4367 int
   4368 sum_row(int *row) {
   4369   int sum = 0;
   4370   int i;
   4371   for (i = 0; i < HIST_NUM_OF_BUCKET; i++) sum += row[i];
   4372   return(sum);
   4373 }
   4374 
   4375 void
   4376 HIST_report(HIST h){
   4377 #ifndef OLD_HISTOGRAM
   4378    output_row(stdout, "UNIT_USEC     ", h->unit_usec);
   4379    output_row(stdout, "TEN_USEC      ", h->ten_usec);
   4380    output_row(stdout, "HUNDRED_USEC  ", h->hundred_usec);
   4381 #else
   4382    h->hundred_usec[0] += sum_row(h->unit_usec);
   4383    h->hundred_usec[0] += sum_row(h->ten_usec);
   4384    output_row(stdout, "TENTH_MSEC    ", h->hundred_usec);
   4385 #endif
   4386    output_row(stdout, "UNIT_MSEC     ", h->unit_msec);
   4387    output_row(stdout, "TEN_MSEC      ", h->ten_msec);
   4388    output_row(stdout, "HUNDRED_MSEC  ", h->hundred_msec);
   4389    output_row(stdout, "UNIT_SEC      ", h->unit_sec);
   4390    output_row(stdout, "TEN_SEC       ", h->ten_sec);
   4391    fprintf(where,">100_SECS: %d\n", h->ridiculous);
   4392    fprintf(where,"HIST_TOTAL:      %d\n", h->total);
   4393    if (debug) {
   4394      fprintf(where,
   4395 	     "sum %"PRIi64", sumsquare %f, limit %d count %d\n",
   4396 	     h->sum,
   4397 	     h->sumsquare,
   4398 	     h->limit,
   4399 	     h->count);
   4400    }
   4401 }
   4402 
   4403 /* search buckets for each unit */
   4404 int
   4405 HIST_search_bucket(int *unit, int num, int *last, int *current, double scale){
   4406   int base = HIST_NUM_OF_BUCKET / 10;
   4407   int i;
   4408   for (i = 0; i < HIST_NUM_OF_BUCKET; i++){
   4409     *last = *current;
   4410     *current += unit[i];
   4411     if (*current >= num)
   4412       return (int)((i + (double)(num - *last)/(*current - *last)) * scale/base);
   4413   }
   4414   return 0;
   4415 }
   4416 
   4417 /* get percentile from histogram */
   4418 int
   4419 HIST_get_percentile(HIST h, const double percentile){
   4420   double win_kludge = percentile * (double) h->total;
   4421   int num = (int) win_kludge;
   4422   int last = 0;
   4423   int current = 0;
   4424   int result;
   4425 
   4426   if (!num)
   4427     return 0;
   4428 
   4429   /* search in unit usec range */
   4430   result = HIST_search_bucket(h->unit_usec, num, &last, &current, 1e0);
   4431   if (result)
   4432     return result;
   4433 
   4434   /* search in ten usec range */
   4435   result = HIST_search_bucket(h->ten_usec, num, &last, &current, 1e1);
   4436   if (result)
   4437     return result;
   4438 
   4439   /* search in ten hundred usec range */
   4440   result = HIST_search_bucket(h->hundred_usec, num, &last, &current, 1e2);
   4441   if (result)
   4442     return result;
   4443 
   4444   /* search in unic msec range */
   4445   result = HIST_search_bucket(h->unit_msec, num, &last, &current, 1e3);
   4446   if (result)
   4447     return result;
   4448 
   4449   /* search in ten msec range */
   4450   result = HIST_search_bucket(h->ten_msec, num, &last, &current, 1e4);
   4451   if (result)
   4452     return result;
   4453 
   4454   /* search in hundred msec range */
   4455   result = HIST_search_bucket(h->hundred_msec, num, &last, &current, 1e5);
   4456   if (result)
   4457     return result;
   4458 
   4459   /* search in unit sec range */
   4460   result = HIST_search_bucket(h->unit_sec, num, &last, &current, 1e6);
   4461   if (result)
   4462     return result;
   4463 
   4464   /* search in ten sec range */
   4465   result = HIST_search_bucket(h->ten_sec, num, &last, &current, 1e7);
   4466   if (result)
   4467     return result;
   4468 
   4469   return (int)(1e8);
   4470 }
   4471 
   4472 
   4473 /* get basic stats */
   4474 void
   4475 HIST_get_stats(HIST h, int *min, int *max, double *mean, double *stddev){
   4476   *min = h->hmin;
   4477   *max = h->hmax;
   4478   if (h->total){
   4479     *mean = (double)h->sum / (double)h->total;
   4480     *stddev = (h->sumsquare * h->total - pow((double)h->sum, 2)) /
   4481       pow(h->total, 2);
   4482     *stddev = sqrt(*stddev);
   4483   }
   4484   else{
   4485     *mean = 0;
   4486     *stddev = 0;
   4487   }
   4488 }
   4489 
   4490 
   4491 /* with the advent of sit-and-spin intervals support, we might as well
   4492    make these things available all the time, not just for demo or
   4493    histogram modes. raj 2006-02-06 */
   4494 #ifdef HAVE_GETHRTIME
   4495 
   4496 void
   4497 HIST_timestamp(hrtime_t *timestamp)
   4498 {
   4499   *timestamp = gethrtime();
   4500 }
   4501 
   4502 int
   4503 delta_micro(hrtime_t *begin, hrtime_t *end)
   4504 {
   4505   long nsecs;
   4506   nsecs = (*end) - (*begin);
   4507   return(nsecs/1000);
   4508 }
   4509 
   4510 #elif defined(HAVE_GET_HRT)
   4511 #include "hrt.h"
   4512 
   4513 void
   4514 HIST_timestamp(hrt_t *timestamp)
   4515 {
   4516   *timestamp = get_hrt();
   4517 }
   4518 
   4519 int
   4520 delta_micro(hrt_t *begin, hrt_t *end)
   4521 {
   4522 
   4523   return((int)get_hrt_delta(*end,*begin));
   4524 
   4525 }
   4526 #elif defined(WIN32)
   4527 void HIST_timestamp(LARGE_INTEGER *timestamp)
   4528 {
   4529 	QueryPerformanceCounter(timestamp);
   4530 }
   4531 
   4532 int delta_micro(LARGE_INTEGER *begin, LARGE_INTEGER *end)
   4533 {
   4534 	LARGE_INTEGER DeltaTimestamp;
   4535 	static LARGE_INTEGER TickHz = {{0,0}};
   4536 
   4537 	if (TickHz.QuadPart == 0)
   4538 	{
   4539 		QueryPerformanceFrequency(&TickHz);
   4540 	}
   4541 
   4542 	/*+*+ Rick; this will overflow after ~2000 seconds, is that
   4543 	  good enough? Spencer: Yes, that should be more than good
   4544 	  enough for histogram support */
   4545 
   4546 	DeltaTimestamp.QuadPart = (end->QuadPart - begin->QuadPart) *
   4547 	  1000000/TickHz.QuadPart;
   4548 	assert((DeltaTimestamp.HighPart == 0) &&
   4549 	       ((int)DeltaTimestamp.LowPart >= 0));
   4550 
   4551 	return (int)DeltaTimestamp.LowPart;
   4552 }
   4553 
   4554 #else
   4555 
   4556 void
   4557 HIST_timestamp(struct timeval *timestamp)
   4558 {
   4559   gettimeofday(timestamp,NULL);
   4560 }
   4561 
   4562  /* return the difference (in micro seconds) between two timeval */
   4563  /* timestamps */
   4564 int
   4565 delta_micro(struct timeval *begin,struct timeval *end)
   4566 
   4567 {
   4568 
   4569   int usecs, secs;
   4570 
   4571   if (end->tv_usec < begin->tv_usec) {
   4572     /* borrow a second from the tv_sec */
   4573     end->tv_usec += 1000000;
   4574     end->tv_sec--;
   4575   }
   4576   usecs = end->tv_usec - begin->tv_usec;
   4577   secs  = end->tv_sec - begin->tv_sec;
   4578 
   4579   usecs += (secs * 1000000);
   4580 
   4581   return(usecs);
   4582 
   4583 }
   4584 #endif /* HAVE_GETHRTIME */
   4585 
   4586 void
   4587 HIST_timestamp_start(HIST h) {
   4588 
   4589   if (NULL == h) {
   4590     fprintf(where,"HIST_timestamp_start called with NULL histogram\n");
   4591     fflush(where);
   4592     exit(-1);
   4593   }
   4594   if (h->count == h->limit) {
   4595     fprintf(where,"HIST_timestamp_start called with full time_ones\n");
   4596   }
   4597 
   4598   HIST_timestamp(&(h->time_ones[h->producer]));
   4599   h->producer += 1;
   4600   h->producer %= h->limit;
   4601   h->count += 1;
   4602 
   4603 
   4604 }
   4605 
   4606 /* snap an ending timestamp and add the delta to the histogram */
   4607 void
   4608 HIST_timestamp_stop_add(HIST h) {
   4609 
   4610   if (NULL == h) {
   4611     fprintf(where,"HIST_timestamp_stop called with NULL histogram\n");
   4612     fflush(where);
   4613     exit(-1);
   4614   }
   4615 
   4616   if (h->consumer == h->producer) {
   4617     fprintf(where,
   4618 	    "HIST_timestamp_stop called with empty time_ones consumer %d producer %d\n",
   4619 	    h->consumer,
   4620 	    h->producer);
   4621     fflush(where);
   4622     exit(-1);
   4623   }
   4624   /* take our stopping timestamp */
   4625   HIST_timestamp(&(h->time_two));
   4626 
   4627   /* now add it */
   4628   HIST_add(h,delta_micro(&(h->time_ones[h->consumer]),&(h->time_two)));
   4629   h->consumer += 1;
   4630   h->consumer %= h->limit;
   4631   h->count -= 1;
   4632 
   4633 }
   4634 
   4635 
   4636 
   4638 /* these routines for confidence intervals are courtesy of IBM. They
   4639    have been modified slightly for more general usage beyond TCP/UDP
   4640    tests. raj 11/94 I would suspect that this code carries an IBM
   4641    copyright that is much the same as that for the original HP netperf
   4642    code */
   4643 int     confidence_iterations; /* for iterations */
   4644 
   4645 double
   4646   result_confid=-10.0,
   4647   loc_cpu_confid=-10.0,
   4648   rem_cpu_confid=-10.0,
   4649 
   4650   measured_sum_result=0.0,
   4651   measured_square_sum_result=0.0,
   4652   measured_mean_result=0.0,
   4653   measured_var_result=0.0,
   4654 
   4655   measured_sum_local_cpu=0.0,
   4656   measured_square_sum_local_cpu=0.0,
   4657   measured_mean_local_cpu=0.0,
   4658   measured_var_local_cpu=0.0,
   4659 
   4660   measured_sum_remote_cpu=0.0,
   4661   measured_square_sum_remote_cpu=0.0,
   4662   measured_mean_remote_cpu=0.0,
   4663   measured_var_remote_cpu=0.0,
   4664 
   4665   measured_sum_local_service_demand=0.0,
   4666   measured_square_sum_local_service_demand=0.0,
   4667   measured_mean_local_service_demand=0.0,
   4668   measured_var_local_service_demand=0.0,
   4669 
   4670   measured_sum_remote_service_demand=0.0,
   4671   measured_square_sum_remote_service_demand=0.0,
   4672   measured_mean_remote_service_demand=0.0,
   4673   measured_var_remote_service_demand=0.0,
   4674 
   4675   measured_sum_local_time=0.0,
   4676   measured_square_sum_local_time=0.0,
   4677   measured_mean_local_time=0.0,
   4678   measured_var_local_time=0.0,
   4679 
   4680   measured_mean_remote_time=0.0,
   4681 
   4682   measured_fails,
   4683   measured_local_results,
   4684   confidence=-10.0;
   4685 /*  interval=0.1; */
   4686 
   4687 /************************************************************************/
   4688 /*                                                                      */
   4689 /*      Constants for Confidence Intervals                              */
   4690 /*                                                                      */
   4691 /************************************************************************/
   4692 void
   4693 init_stat()
   4694 {
   4695         measured_sum_result=0.0;
   4696         measured_square_sum_result=0.0;
   4697         measured_mean_result=0.0;
   4698         measured_var_result=0.0;
   4699 
   4700         measured_sum_local_cpu=0.0;
   4701         measured_square_sum_local_cpu=0.0;
   4702         measured_mean_local_cpu=0.0;
   4703         measured_var_local_cpu=0.0;
   4704 
   4705         measured_sum_remote_cpu=0.0;
   4706         measured_square_sum_remote_cpu=0.0;
   4707         measured_mean_remote_cpu=0.0;
   4708         measured_var_remote_cpu=0.0;
   4709 
   4710         measured_sum_local_service_demand=0.0;
   4711         measured_square_sum_local_service_demand=0.0;
   4712         measured_mean_local_service_demand=0.0;
   4713         measured_var_local_service_demand=0.0;
   4714 
   4715         measured_sum_remote_service_demand=0.0;
   4716         measured_square_sum_remote_service_demand=0.0;
   4717         measured_mean_remote_service_demand=0.0;
   4718         measured_var_remote_service_demand=0.0;
   4719 
   4720         measured_sum_local_time=0.0;
   4721         measured_square_sum_local_time=0.0;
   4722         measured_mean_local_time=0.0;
   4723         measured_var_local_time=0.0;
   4724 
   4725         measured_mean_remote_time=0.0;
   4726 
   4727         measured_fails = 0.0;
   4728         measured_local_results=0.0,
   4729         confidence=-10.0;
   4730 }
   4731 
   4732 /* this routine does a simple table lookup for some statistical
   4733    function that I would remember if I stayed awake in my probstats
   4734    class... raj 11/94 */
   4735 double
   4736 confid(int level, int freedom)
   4737 {
   4738 double  t99[35],t95[35];
   4739 
   4740    t95[1]=12.706;
   4741    t95[2]= 4.303;
   4742    t95[3]= 3.182;
   4743    t95[4]= 2.776;
   4744    t95[5]= 2.571;
   4745    t95[6]= 2.447;
   4746    t95[7]= 2.365;
   4747    t95[8]= 2.306;
   4748    t95[9]= 2.262;
   4749    t95[10]= 2.228;
   4750    t95[11]= 2.201;
   4751    t95[12]= 2.179;
   4752    t95[13]= 2.160;
   4753    t95[14]= 2.145;
   4754    t95[15]= 2.131;
   4755    t95[16]= 2.120;
   4756    t95[17]= 2.110;
   4757    t95[18]= 2.101;
   4758    t95[19]= 2.093;
   4759    t95[20]= 2.086;
   4760    t95[21]= 2.080;
   4761    t95[22]= 2.074;
   4762    t95[23]= 2.069;
   4763    t95[24]= 2.064;
   4764    t95[25]= 2.060;
   4765    t95[26]= 2.056;
   4766    t95[27]= 2.052;
   4767    t95[28]= 2.048;
   4768    t95[29]= 2.045;
   4769    t95[30]= 2.042;
   4770 
   4771    t99[1]=63.657;
   4772    t99[2]= 9.925;
   4773    t99[3]= 5.841;
   4774    t99[4]= 4.604;
   4775    t99[5]= 4.032;
   4776    t99[6]= 3.707;
   4777    t99[7]= 3.499;
   4778    t99[8]= 3.355;
   4779    t99[9]= 3.250;
   4780    t99[10]= 3.169;
   4781    t99[11]= 3.106;
   4782    t99[12]= 3.055;
   4783    t99[13]= 3.012;
   4784    t99[14]= 2.977;
   4785    t99[15]= 2.947;
   4786    t99[16]= 2.921;
   4787    t99[17]= 2.898;
   4788    t99[18]= 2.878;
   4789    t99[19]= 2.861;
   4790    t99[20]= 2.845;
   4791    t99[21]= 2.831;
   4792    t99[22]= 2.819;
   4793    t99[23]= 2.807;
   4794    t99[24]= 2.797;
   4795    t99[25]= 2.787;
   4796    t99[26]= 2.779;
   4797    t99[27]= 2.771;
   4798    t99[28]= 2.763;
   4799    t99[29]= 2.756;
   4800    t99[30]= 2.750;
   4801 
   4802    if(level==95){
   4803         return(t95[freedom]);
   4804    } else if(level==99){
   4805         return(t99[freedom]);
   4806    } else{
   4807         return(0);
   4808    }
   4809 }
   4810 
   4811 void
   4812 calculate_confidence(int confidence_iterations,
   4813                      float time,
   4814                      double result,
   4815                      float loc_cpu,
   4816                      float rem_cpu,
   4817                      float loc_sd,
   4818                      float rem_sd)
   4819 {
   4820 
   4821   if (debug) {
   4822     fprintf(where,
   4823             "calculate_confidence: itr  %d; time %f; res  %f\n"
   4824             "                               lcpu %f; rcpu %f\n"
   4825             "                               lsdm %f; rsdm %f\n",
   4826             confidence_iterations,
   4827             time,
   4828             result,
   4829             loc_cpu,
   4830             rem_cpu,
   4831             loc_sd,
   4832             rem_sd);
   4833     fflush(where);
   4834   }
   4835 
   4836   /* the test time */
   4837   measured_sum_local_time               +=
   4838     (double) time;
   4839   measured_square_sum_local_time        +=
   4840     (double) time*time;
   4841   measured_mean_local_time              =
   4842     (double) measured_sum_local_time/confidence_iterations;
   4843   measured_var_local_time               =
   4844     (double) measured_square_sum_local_time/confidence_iterations
   4845       -measured_mean_local_time*measured_mean_local_time;
   4846 
   4847   /* the test result */
   4848   measured_sum_result           +=
   4849     (double) result;
   4850   measured_square_sum_result    +=
   4851     (double) result*result;
   4852   measured_mean_result          =
   4853     (double) measured_sum_result/confidence_iterations;
   4854   measured_var_result           =
   4855     (double) measured_square_sum_result/confidence_iterations
   4856       -measured_mean_result*measured_mean_result;
   4857 
   4858   /* local cpu utilization */
   4859   measured_sum_local_cpu        +=
   4860     (double) loc_cpu;
   4861   measured_square_sum_local_cpu +=
   4862     (double) loc_cpu*loc_cpu;
   4863   measured_mean_local_cpu       =
   4864     (double) measured_sum_local_cpu/confidence_iterations;
   4865   measured_var_local_cpu        =
   4866     (double) measured_square_sum_local_cpu/confidence_iterations
   4867       -measured_mean_local_cpu*measured_mean_local_cpu;
   4868 
   4869   /* remote cpu util */
   4870   measured_sum_remote_cpu       +=
   4871     (double) rem_cpu;
   4872   measured_square_sum_remote_cpu+=
   4873     (double) rem_cpu*rem_cpu;
   4874   measured_mean_remote_cpu      =
   4875     (double) measured_sum_remote_cpu/confidence_iterations;
   4876   measured_var_remote_cpu       =
   4877     (double) measured_square_sum_remote_cpu/confidence_iterations
   4878       -measured_mean_remote_cpu*measured_mean_remote_cpu;
   4879 
   4880   /* local service demand */
   4881   measured_sum_local_service_demand     +=
   4882     (double) loc_sd;
   4883   measured_square_sum_local_service_demand+=
   4884     (double) loc_sd*loc_sd;
   4885   measured_mean_local_service_demand    =
   4886     (double) measured_sum_local_service_demand/confidence_iterations;
   4887   measured_var_local_service_demand     =
   4888     (double) measured_square_sum_local_service_demand/confidence_iterations
   4889       -measured_mean_local_service_demand*measured_mean_local_service_demand;
   4890 
   4891   /* remote service demand */
   4892   measured_sum_remote_service_demand    +=
   4893     (double) rem_sd;
   4894   measured_square_sum_remote_service_demand+=
   4895     (double) rem_sd*rem_sd;
   4896   measured_mean_remote_service_demand   =
   4897     (double) measured_sum_remote_service_demand/confidence_iterations;
   4898   measured_var_remote_service_demand    =
   4899     (double) measured_square_sum_remote_service_demand/confidence_iterations
   4900       -measured_mean_remote_service_demand*measured_mean_remote_service_demand;
   4901 
   4902   if(confidence_iterations>1){
   4903      result_confid= (double) interval -
   4904        2.0 * confid(confidence_level,confidence_iterations-1)*
   4905          sqrt(measured_var_result/(confidence_iterations-1.0)) /
   4906            measured_mean_result;
   4907 
   4908      loc_cpu_confid= (double) interval -
   4909        2.0 * confid(confidence_level,confidence_iterations-1)*
   4910          sqrt(measured_var_local_cpu/(confidence_iterations-1.0)) /
   4911            measured_mean_local_cpu;
   4912 
   4913      rem_cpu_confid= (double) interval -
   4914        2.0 * confid(confidence_level,confidence_iterations-1)*
   4915          sqrt(measured_var_remote_cpu/(confidence_iterations-1.0)) /
   4916            measured_mean_remote_cpu;
   4917 
   4918      if(debug){
   4919        printf("Conf_itvl %2d: results:%4.1f%% loc_cpu:%4.1f%% rem_cpu:%4.1f%%\n",
   4920               confidence_iterations,
   4921               (interval-result_confid)*100.0,
   4922               (interval-loc_cpu_confid)*100.0,
   4923               (interval-rem_cpu_confid)*100.0);
   4924      }
   4925 
   4926      /* if the user has requested that we only wait for the result to
   4927 	be confident rather than the result and CPU util(s) then do
   4928 	so. raj 2007-08-08 */
   4929      if (!result_confidence_only) {
   4930        confidence = min(min(result_confid,loc_cpu_confid),rem_cpu_confid);
   4931      }
   4932      else {
   4933        confidence = result_confid;
   4934      }
   4935   }
   4936 }
   4937 
   4938  /* here ends the IBM code */
   4939 
   4940 void
   4941 retrieve_confident_values(float *elapsed_time,
   4942                           double *thruput,
   4943                           float *local_cpu_utilization,
   4944                           float *remote_cpu_utilization,
   4945                           float *local_service_demand,
   4946                           float *remote_service_demand)
   4947 
   4948 {
   4949   *elapsed_time            = (float)measured_mean_local_time;
   4950   *thruput                 = measured_mean_result;
   4951   *local_cpu_utilization   = (float)measured_mean_local_cpu;
   4952   *remote_cpu_utilization  = (float)measured_mean_remote_cpu;
   4953   *local_service_demand    = (float)measured_mean_local_service_demand;
   4954   *remote_service_demand   = (float)measured_mean_remote_service_demand;
   4955 }
   4956 
   4957 double
   4958 get_result_confid()
   4959 {
   4960   return (double) (100.0 * (interval - result_confid));
   4961 }
   4962 
   4963 double
   4964 get_loc_cpu_confid()
   4965 {
   4966   return (double) (100.0 * (interval - loc_cpu_confid));
   4967 }
   4968 
   4969 double
   4970 get_rem_cpu_confid()
   4971 {
   4972   return (double) (100.0 * (interval - rem_cpu_confid));
   4973 }
   4974 
   4975 /* display_confidence() is called when we could not achieve the
   4976    desired confidence in the results. it will print the achieved
   4977    confidence to "where" raj 11/94 */
   4978 void
   4979 display_confidence()
   4980 
   4981 {
   4982   fprintf(where,
   4983           "!!! WARNING\n"
   4984           "!!! Desired confidence was not achieved within "
   4985           "the specified iterations.\n"
   4986           "!!! This implies that there was variability in "
   4987           "the test environment that\n"
   4988           "!!! must be investigated before going further.\n"
   4989           "!!! Confidence intervals: Throughput      : %4.3f%%\n"
   4990           "!!!                       Local CPU util  : %4.3f%%\n"
   4991           "!!!                       Remote CPU util : %4.3f%%\n\n",
   4992           100.0 * (interval - result_confid),
   4993           100.0 * (interval - loc_cpu_confid),
   4994           100.0 * (interval - rem_cpu_confid));
   4995 }
   4996