home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / lan / lanper11 / lanperf.c next >
C/C++ Source or Header  |  1989-01-31  |  12KB  |  431 lines

  1. /*
  2.  *  LANPERF - PC Tech Journal LAN Performance Test
  3.  *  Copyright (c) 1988, Ziff Communications Company 
  4.  *  Rewritten 11/22/1988 entirely in C
  5.  *  Extended  01/31/1989 with maximum block size of 65534, changing version
  6.  *  number.
  7.  *
  8.  *      by Ben Myers
  9.  *      Spirit of Performance, Inc.
  10.  *      73 Westcott Road
  11.  *      Harvard, MA  01451
  12.  *      (508) 456-3889
  13.  *      MCI Mail 357-1400
  14.  *
  15.  *  The original used MASM routines for some of the functions.
  16.  *  The maximum block size permitted is now 16384 bytes, limited by the
  17.  *  small memory model of Microsoft C5.0.
  18.  *  Except for timer functions which are specific to IBM PC BIOS,
  19.  *  LANPERF is now portable to other operating environments.
  20.  *  Let me know of successes in porting it, and I would appreciate having
  21.  *  a copy of the modified source.  Thank you... Ben.
  22.  *
  23.  *  To build LANPERF.EXE:
  24.  *    cl /AH LANPERF.C   (Compiled with Microsoft C 5.0)
  25.  */
  26.  
  27. #include <fcntl.h>
  28. #include <stdio.h>
  29. #include <stdlib.h>
  30. #include <conio.h>
  31. #include <sys\types.h>
  32. #include <sys\stat.h>
  33. #include <share.h>
  34. #include <io.h>
  35. #include <time.h>
  36. /* MS/PC-DOS specific definitions and function */
  37. #include <dos.h>
  38. #define STARTTIME  begint = g_ticks()
  39. #define STOPTIME   endt = g_ticks()
  40. /*   duration in seconds * 18.2 ticks / second   */
  41. #define ENDTIMEDELTA  (duration / 5) + (duration * 18)
  42. long g_ticks()
  43. /* Returns the current number of clock ticks @ 18.2 ticks/second */
  44.   {
  45.     long Current_Ticks;
  46.     long far *BIOS_Clock;
  47.     /* Set up pointer to double word containing clock ticks in BIOS */
  48.     FP_SEG(BIOS_Clock) = 0;
  49.     FP_OFF(BIOS_Clock) = 0x046C;
  50.     _disable();                    /* No interrupts */
  51.     Current_Ticks = *BIOS_Clock;   /* Get the current number of ticks */
  52.     _enable();                     /* Allow interrupts again */
  53.     return (Current_Ticks);
  54.   }
  55.  
  56. /* end of MS/PC-DOS specific definitions and function */
  57.  
  58. #define MAXBLK      65534    /* maximum blksize value */
  59. /* for OS that does not distinguish between stream and sequential I/O */
  60. #define O_STREAM    0
  61.  
  62. /* information used by rtest() and wtest() routines */
  63.  
  64. int  master;                /* did we start the test? */
  65. unsigned int blksize;       /* block I/O size in bytes */
  66. unsigned int filesize;      /* size of file in blksize blocks */
  67. char ioshare;               /* sharing mode for tests */
  68. char iobuf[2*MAXBLK];       /* I/O buffer */
  69. unsigned int duration;      /* length of test (seconds) */
  70. long ops;                   /* total operations performed */
  71. char fname[20];             /* name of test file created */
  72.  
  73. int fhandle;                /* file handle */
  74. FILE *streamid;             /* stream I/O file */
  75. int fileexists;             /* return indicator from open, != 0 exists */
  76. unsigned int i;             /* loop counter */
  77. long begint;  /* Start time in PC BIOS clock ticks */
  78. long endt;    /* Stop time in PC BIOS clock ticks */
  79. long CalcEndTime;
  80.  
  81. char *modename[] =
  82.     {
  83.     "Compatibility", "Deny read/write", "Deny write",
  84.     "Deny read", "Deny none", "??"
  85.     };
  86.  
  87. main(int argc, char **argv)
  88. {
  89.     unsigned int atou(const char *str);
  90.     int i, err;
  91.     int do_read, do_write;
  92.  
  93.     printf("LANPERF Version 1.1\n");
  94.     printf("PC Tech Journal LAN Performance Test\n");
  95.     printf("Copyright (c) 1988, Ziff Communications Company\n\n");
  96.  
  97.     if ( argc < 2 )
  98.         {
  99.         printf("Options:\n");
  100.         printf(" t# - test length (seconds) (10-65535)\n");
  101.     printf(" b# - block size (in bytes) (1-%u)\n", MAXBLK);
  102.         printf(" f# - file size (in blocks) (1-65535)\n");
  103.         printf(" w  - do sequential write test\n");
  104.         printf(" r  - do sequential read test\n");
  105.         printf(" dM - file sharing mode\n");
  106.         printf("  ^ modes to deny (r w rw n c)\n");
  107.         printf(" x  - use defaults:  t60 b512 f64 r w dc\n");
  108.         exit(1);
  109.         }
  110.  
  111.     /* set default values */
  112.     blksize = 512;
  113.     filesize = 64;
  114.     duration = 60;
  115.     ioshare = 0;    /* compatibility mode */
  116.     do_read = 0;
  117.     do_write = 0;
  118.  
  119.     /* decode arguments */
  120.     for ( argv++, argc--; argc > 0; argv++, argc-- )
  121.         {
  122.         switch ( tolower(**argv) )
  123.             {
  124.             case 't' :
  125.                 duration = atou(*argv + 1);
  126.                 if ( duration < 10 )
  127.                     {
  128.                     printf("Illegal test time: %s\n", *argv);
  129.                     exit(1);
  130.                     }
  131.                 break;
  132.             case 'b':
  133.                 blksize = atou(*argv + 1);
  134.                 if ( blksize == 0 || blksize > MAXBLK )
  135.                     {
  136.                     printf("Illegal block size: %s\n", *argv);
  137.                     exit(1);
  138.                     }
  139.                 break;
  140.             case 'f':
  141.                 filesize = atou(*argv + 1);
  142.                 if ( filesize == 0 )
  143.                     {
  144.                     printf("Illegal file size: %s\n", *argv);
  145.                     exit(1);
  146.                     }
  147.                 break;
  148.             case 'd':
  149.                 switch ( tolower(*(*argv + 1)) )
  150.                     {
  151.                     case 'r':
  152.                         if ( tolower(*(*argv + 2)) == 'w' )
  153.                 ioshare = SH_DENYRW; /* deny r/w */
  154.                         else
  155.                 ioshare = SH_DENYRD; /* deny read */
  156.                         break;
  157.                     case 'w':
  158.             ioshare = SH_DENYWR;     /* deny write */
  159.                         break;
  160.                     case 'n':
  161.             ioshare = SH_DENYNO;     /* deny none */
  162.                         break;
  163.                     case 'c':
  164.             ioshare = SH_COMPAT;     /* compatibility */
  165.                         break;
  166.                     default:
  167.                         printf("Illegal sharing mode: %s\n", *argv);
  168.                         exit(1);
  169.                     }
  170.                 break;
  171.             case 'w':
  172.                 do_write = 1;
  173.                 break;
  174.             case 'r':
  175.                 do_read = 1;
  176.                 break;
  177.             case 'x':
  178.                 break;
  179.             default:
  180.                 printf("unknown option: %s\n", *argv);
  181.                 exit(1);
  182.             }
  183.         }
  184.  
  185.     /* If read or write not specified, do both */
  186.     if ( !do_read && !do_write )
  187.         {
  188.         do_read = 1;
  189.         do_write = 1;
  190.         }
  191.  
  192.     printf("Test time  : %u seconds\n", duration);
  193.     printf("Block size : %u bytes\n", blksize);
  194.     printf("File size  : %u blocks (%lu bytes)\n",
  195.      filesize, (long)filesize * (long)blksize);
  196.     printf("Sharing    : %s\n\n", modename[ioshare >> 4]);
  197.     printf("===> PRESS A KEY ON ANY STATION TO START <===\n\n");
  198.     printf("           Total     Mean Response  Throughput\n");
  199.     printf("Test     Operations    Time (ms)      (KB/s)\n");
  200.     printf("----     ----------  -------------  ----------\n");
  201.  
  202.     /* Fill buffer with random data pattern */
  203.     srand(19);
  204.     for ( i = 0; i < sizeof(iobuf); i++ )
  205.     iobuf[i] = rand ();
  206.  
  207.     strcpy(fname, "LANPERF.GO");
  208.     unlink(fname);               /* in case it's already there */
  209.     if ( (err = lpstart()) )
  210.         fatal(err);
  211.  
  212.     if ( do_write )
  213.         {
  214.         printf("WRITE  :");
  215.         if ( (err = wtest()) )
  216.             fatal(err);
  217.     printf("%8ld      %8.3f      %8.2f\n",
  218.             ops,
  219.             1000.0 * (float)duration / (float)ops,
  220.             ((float)ops * (float)blksize) / (duration * 1024.0));
  221.         }
  222.  
  223.     if ( do_read )
  224.         {
  225.         printf("READ   :");
  226.         if ( (err = rtest()) )
  227.             fatal(err);
  228.         printf("%8ld      %8.3f      %8.2f\n",
  229.             ops,
  230.             1000.0 * (float)duration / (float)ops,
  231.             ((float)ops * (float)blksize) / (duration * 1024.0));
  232.         }
  233.  
  234.     if ( master )
  235.         unlink("LANPERF.GO");
  236.  
  237.     exit(0);
  238. }
  239.  
  240.  
  241. fatal(int err)
  242. {
  243. static char *doscode[] =
  244.     {
  245.     "No error",
  246.     "Invalid function",
  247.     "File not found",
  248.     "Path not found",
  249.     "Too many open files",
  250.     "Access denied",
  251.     "Invalid handle",
  252.     "Memory is trashed",
  253.     "Insufficient memory",
  254.     "Invalid memory block",
  255.     "Bad environment",
  256.     "Invalid format",
  257.     "Invalid access code",
  258.     "Invalid data",
  259.     "??",
  260.     "Invalid drive",
  261.     "Can't remove current directory",
  262.     "Not same device",
  263.     "No more matching files",
  264.     };
  265.     
  266.     if ( err < 0 )
  267.         printf("\nERROR: possible disk full?");
  268.     else
  269.         {
  270.         printf("\nDOS error %u, ", err);
  271.         if ( err >= sizeof(doscode)/sizeof(doscode[0]) )
  272.             printf("??\n");
  273.         else
  274.             printf("%s\n",doscode[err]);
  275.         }
  276.     unlink("LANPERF.GO");
  277.     exit(1);
  278. }
  279.  
  280. #include <ctype.h>
  281. #include <limits.h>
  282.  
  283. unsigned int atou(const char *str)
  284. {
  285.     unsigned long tmp = 0;
  286.  
  287.     /* convert a string to an unsigned integer */
  288.     while ( *str )
  289.         {
  290.         if ( isdigit(*str) )
  291.             tmp = tmp * 10 + (*str++ - '0');
  292.         else
  293.             return(0);      /* garbage */
  294.         }
  295.     if ( tmp > UINT_MAX )
  296.         return(0);          /* number too big */
  297.     return((unsigned int)tmp);
  298. }
  299.  
  300. int lpstart ()
  301.  
  302. {
  303. int gotch, achar;
  304. struct stat file_info;
  305.  
  306. gotch = 0;
  307. fileexists = 0;
  308. while ((gotch == 0) | (fileexists == 0))
  309.   {
  310.   gotch = kbhit();
  311.   if ( gotch == 0 )
  312.     {
  313.     gotch = kbhit();
  314.     if ( gotch == 0 )
  315.       {
  316.       gotch = kbhit();
  317.       if ( gotch == 0 )
  318.     fileexists = stat ( fname, &file_info );
  319.       }
  320.     }
  321.   }
  322.   if (gotch != 0)      /* a character in the buffer */
  323.     {
  324.     achar = getch();   /* get it */
  325.     if (achar == 0)
  326.       achar= getch();  /* extended character */
  327.     }
  328.   if (fileexists != 0)     /* file doesn't already exist */
  329.     {
  330.     fhandle =              /* create and close it */
  331.       sopen ( fname, O_CREAT | O_STREAM | O_TRUNC | O_RDWR, ioshare,
  332.         S_IREAD | S_IWRITE );
  333.     if (fhandle != -1)
  334.       fileexists = 0;
  335.     else
  336.       fileexists = -1;
  337.     if ((close (fhandle)) != -1)
  338.       fileexists =0;
  339.     else
  340.       fileexists = -1;
  341.     }
  342.   return(fileexists);
  343. }
  344.  
  345. int rtest ()
  346. {
  347. register unsigned int i;
  348. int nbytes, n_blks;
  349.  
  350.     fhandle =              /* create and initialize it */
  351.       sopen ( fname, O_CREAT | O_STREAM | O_TRUNC | O_RDWR, ioshare,
  352.         S_IREAD | S_IWRITE );
  353.     fileexists = (fhandle != -1);
  354.     setmode ( fhandle, O_BINARY );
  355.     for (i = 0; i < filesize; i++)
  356.       {
  357.       /* vary position within buffer to defeat cacheing schemes */
  358.       if ((nbytes = write ( fhandle, &iobuf[i % MAXBLK], blksize )) < blksize)
  359.     {
  360.     printf ( "rtest: error in initializing file." );
  361.     close (fhandle);
  362.     unlink (fname);
  363.     exit (1);
  364.     }
  365.       }
  366.     lseek (fhandle, 0L, 0);  /* back to beginning of file */
  367.  
  368.     fileexists = ((close (fhandle)) != -1);
  369.     fhandle =              /* open to read now */
  370.       sopen ( fname, O_STREAM | O_RDONLY, ioshare );
  371.       setmode ( fhandle, O_BINARY );
  372.       ops = 0;
  373.       n_blks = filesize;
  374.       /* Calculate end time in ticks, adding duration * 18.2 ticks / sec */
  375.       CalcEndTime = (STARTTIME) + ENDTIMEDELTA;
  376.       do
  377.     {
  378.     for (i = 0; i < filesize; i++)
  379.       {
  380.       read ( fhandle, iobuf, blksize );
  381.  
  382.       ops++;
  383.       if (CalcEndTime <= (STOPTIME)) goto rtestexit;
  384.       }
  385.       /* after every pass through the file, seek back to beginning */
  386.       lseek (fhandle, 0L, 0);
  387.     }
  388.       while (CalcEndTime > endt);
  389.       rtestexit:
  390.       close (fhandle);
  391.       unlink (fname);
  392.       return (0);
  393. }
  394.  
  395. int wtest ()
  396. {
  397. register unsigned int i;
  398. int nbytes, n_blks;
  399.  
  400.     /* create and initialize file */
  401.  
  402.     fhandle =
  403.       sopen ( fname, O_CREAT | O_STREAM | O_TRUNC | O_RDWR, ioshare,
  404.         S_IREAD | S_IWRITE );
  405.     setmode ( fhandle, O_BINARY );
  406.       ops = 0;
  407.       n_blks = filesize;
  408.       /* Calculate end time in ticks, adding duration * 18.2 ticks / sec */
  409.       CalcEndTime = (STARTTIME) + ENDTIMEDELTA;
  410.       do
  411.     {
  412.     for (i = 0; i < filesize; i++)
  413.       {
  414.       /* vary position within buffer to defeat cacheing schemes */
  415.  
  416.       write ( fhandle, &iobuf[i % MAXBLK], blksize );
  417.  
  418.       ops++;
  419.       if (CalcEndTime <= (STOPTIME)) goto wtestexit;
  420.       }
  421.       /* after every pass through the file, seek back to beginning */
  422.       lseek (fhandle, 0L, 0);
  423.     }
  424.       while (CalcEndTime > endt);
  425.       wtestexit:
  426.       close (fhandle);
  427.       unlink (fname);
  428.       return (0);
  429.  
  430. }
  431.