home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 8 Other / 08-Other.zip / mdisk.lzh / DiskThd.C next >
C/C++ Source or Header  |  1993-12-02  |  11KB  |  337 lines

  1. /*
  2. *
  3. *   "I/O Stone" Benchmark Program
  4. *
  5. *   Written by: Arvin Park (park@midas.ucdavis.edu) and
  6. *            Jeff Becker (becker@iris.ucdavis.edu)
  7. *            Division of Computer Science
  8. *            University of California, Davis
  9. *            Davis CA 95616
  10. *            (916) 752-5183
  11. *
  12. *   Version C/II
  13. *   Date: 06/27/90
  14. *
  15. *   Defines: If your version of "C" does not include an ftime()
  16. *            function or the C library time.h, define NOTIME.
  17. *            Use a stopwatch to measure elapsed wall time.
  18. *            Divide 2,000,000 by the elapsed time to get
  19. *            the correct number of iostones/second.
  20. *
  21. *   To compile:   cc -O io.c -o io
  22. *
  23. *   Note:    [1] This program should be run without other processes
  24. *            competing for system resources. Run it in the dead of
  25. *            night if you have to.
  26. *
  27. *            [2] This program uses 5 megabytes of disk space. Make
  28. *            sure that at least this much space is available on
  29. *            your file system before you run the program.
  30. *
  31. *   Results: If you get results from a new (machine/operating
  32. *            system/disk controller and drive) combination, please
  33. *            send them to becker@iris.ucdavis.edu. Please include
  34. *            complete information on the machine type, operating
  35. *            system, version, disk controller, and disk drives.
  36. *            Also make a note of any system modifications that
  37. *            have been performed.
  38. *
  39. *-------------------------------------------------------------------------
  40. * 8/26/91 Tin Le
  41. *    Added simple Makefile.
  42. *
  43. *    As far as I can determine from examining the code, iostone is
  44. *    meant for benchmarking file I/O and buffer cache efficiencies.
  45. *
  46. *    It does this by creating NSETS (4) of SET_SIZE (99) files.  Then
  47. *    iostone performs I/O on each file in each set.  The type of I/O is
  48. *    randomly picked (r/w).
  49. *
  50. *--------------------------------------------------------------------------
  51. * 7/21/93 Oddgeir Kvien, kvien@elkraft.unit.no
  52. *
  53. * Slightly modified to compile with Borland C++ for OS/2
  54. *
  55. *--------------------------------------------------------------------------
  56. * 11/93 Jeffrey Patten        1:2410/242@fidonet.org
  57. *
  58. * IOStone gets chopped to pieces to adapt it as a portion of a
  59. * multithreaded disk/cpu usage benchmark.  The numbers generated
  60. * are -NOT- comparable to those generated by the original program.
  61. * No attempt was made to maintain portability - my programming skills
  62. * are not yet advanced enough for that.
  63. *
  64. *--------------------------------------------------------------------------
  65. */
  66.  
  67. #define  INCL_NOPMAPI
  68. #define  INCL_DOS
  69. #include <os2.h>
  70.  
  71. #include "MDisk.h"
  72.  
  73. #include <dir.h>
  74. #include <stdio.h>
  75. #include <io.h>
  76. #include <string.h>
  77. #include <time.h>
  78. #include <stdlib.h>
  79.  
  80. /* PREDEFINISJON */
  81. int  my_rand( int max );
  82. void initfile( char *fname, long fsize, PDTV pDisk );
  83. void readswrites( PDTV pDisk );
  84.  
  85. void EndItAll( int rc, PDTV pDisk );
  86.  
  87.  
  88. VOID APIENTRY ThdDskPerf( ULONG ulTask )
  89. {
  90.   int k;
  91.   PDTV pDisk;
  92.  
  93.   pDisk = (PDTV)ulTask;
  94.  
  95.   pDisk->szDir[ 6 ] = (char)( pDisk->ulTask + 0x30 );
  96.   pDisk->szDir[ 7 ] = 0;
  97.  
  98.   setdisk( (int)( pDisk->szDrive[ 0 ] - 'A' ) );
  99.   mkdir( pDisk->szDir );
  100.   chdir( pDisk->szDir );
  101.  
  102.   /* create test files */
  103.   DosPostEventSem( pDisk->hevReady );
  104.  
  105.   /* start timing */
  106.   DosWaitEventSem( hevGo, SEM_INDEFINITE_WAIT );
  107.  
  108.   /* perform string of file operations */
  109.   for( k = 0; k < ITER; k++ )
  110.     readswrites( pDisk );
  111.  
  112.   /*stop timimg*/
  113.   EndItAll( 0, pDisk );
  114. }
  115.  
  116. void init( PDTV pDisk )
  117. {
  118.   int this_set;                         /*mark the file set (0..NSETS-1)*/
  119.   int bcount;                           /*counter to track #spacer files*/
  120.   int fcount;                           /*a counter to tell where to create*/
  121.   int i, j, k;                                      /*files to flush buffer cache and*/
  122.                                         /*spread other files across disk*/
  123.   pDisk->bsize[ 0 ] = 256;   pDisk->bfreq[ 0 ] = 128;
  124.   pDisk->bsize[ 1 ] = 512;   pDisk->bfreq[ 1 ] = 64;
  125.   pDisk->bsize[ 2 ] = 1024;  pDisk->bfreq[ 2 ] = 64;
  126.   pDisk->bsize[ 3 ] = 2048;  pDisk->bfreq[ 3 ] = 64;
  127.   pDisk->bsize[ 4 ] = 4096;  pDisk->bfreq[ 4 ] = 32;  /*set file block sizes and*/
  128.   pDisk->bsize[ 5 ] = 8192;  pDisk->bfreq[ 5 ] = 32;  /*access frequencies*/
  129.   pDisk->bsize[ 6 ] = 16384; pDisk->bfreq[ 6 ] = 8;
  130.   pDisk->bsize[ 7 ] = 32768; pDisk->bfreq[ 7 ] = 2;
  131.   pDisk->bsize[ 8 ] = 65536; pDisk->bfreq[ 8 ] = 2;
  132.  
  133.   k = 0;                                  /*set up files*/
  134.   bcount = 0;
  135.   fcount = 0;
  136.   for( i = 0; i < NBLOCKSIZES; i++ )
  137.     {
  138.       for( j = 0; j < pDisk->bfreq[ i ]; j++ )
  139.         {
  140.           if( i < NBLOCKSIZES - 1 )
  141.             this_set = j % NSETS;
  142.           else
  143.             this_set = ( j + 2 ) % NSETS;
  144.           sprintf( pDisk->tmp, "%0d_%0d", i, j );       /*create filename*/
  145.           pDisk->files[ this_set ][ k ] = malloc( 1 + strlen( pDisk->tmp ));
  146.           if( ! pDisk->files[ this_set ][ k ] )
  147.             {
  148.               printf( "Could not allocate string for filename\n" );
  149.               EndItAll( 1, pDisk );
  150.             }
  151.           strcpy( pDisk->files[ this_set ][ k ], pDisk->tmp );
  152.           initfile( pDisk->tmp, pDisk->bsize[ i ], pDisk );
  153.           if( i < NBLOCKSIZES - 1 && this_set == NSETS - 1 )
  154.             k++;
  155.           if( bcount < NBFLUSH_FILES && fcount % 44 == 0 )
  156.             {
  157.               sprintf( pDisk->tmp, "%bf_%0d", bcount );       /*create spacer file*/
  158.               pDisk->buf_flush_files[ bcount ] = malloc( 1 + strlen( pDisk->tmp ));
  159.               if( ! pDisk->buf_flush_files[ bcount ] )
  160.                 {
  161.                   printf( "Could not allocate string for filename\n" );
  162.                   EndItAll( 1, pDisk );
  163.                 }
  164.               strcpy( pDisk->buf_flush_files[ bcount ], pDisk->tmp );
  165.               initfile( pDisk->tmp, BFLUSH_FILE_SIZE, pDisk );
  166.               bcount++;
  167.             }
  168.           fcount++;
  169.         }
  170.     }
  171.  
  172.   for( i = 0; i < NBFLUSH_FILES; i++ )
  173.     {        /*read spacer files to flush buffers*/
  174.       if( ( pDisk->fd = open( pDisk->buf_flush_files[ i ], 2)) < 0 )
  175.         {
  176.           printf( "error opening buffer flush file\n" );
  177.           EndItAll( 1, pDisk );
  178.         }
  179.       lseek( pDisk->fd, 0L, 0 );
  180.       k = BFLUSH_FILE_SIZE / BUFFERSIZE;
  181.       for( j = 0; j < k; j++ )
  182.         {
  183.           if( ( pDisk->nbytes = read( pDisk->fd, pDisk->buffer, BUFFERSIZE )) < 0 )
  184.             {
  185.               printf( "Error reading buffer flush file\n" );
  186.               EndItAll( 1, pDisk );
  187.             }
  188.         }
  189.       close( pDisk->fd );
  190.     }
  191.  
  192.   srand( SEED );            /*initialize random number generator*/
  193.   for( i = 0; i < NSETS; i++ )
  194.     {        /*permutation for reading/writing*/
  195.       for( j = SET_SIZE; j > 0; j-- )
  196.         {
  197.           k = my_rand( j );
  198.           strcpy( pDisk->tmp, pDisk->files[ i ][ j - 1 ] );
  199.           strcpy( pDisk->files[ i ][ j - 1 ], pDisk->files[ i ][ k ] );
  200.           strcpy( pDisk->files[ i ][ k ], pDisk->tmp );
  201.         }
  202.     }
  203. }
  204.  
  205. int my_rand( int max )
  206. {
  207.   return rand() % max;
  208. }
  209.  
  210.  
  211. void initfile( char *fname, long fsize, PDTV pDisk )
  212. {                                       /*create a temporary file*/
  213.   FILE *fs;
  214.   int  block, num_blocks;
  215.  
  216.   if(( fs = fopen( fname, "w" )) == NULL )
  217.     {
  218.       printf( "init: Cannot create temporary file\n" );
  219.       EndItAll( 1, pDisk );
  220.     }
  221.   rewind( fs );                /*write initial portion of file*/
  222.   if( fsize > BUFFERSIZE )
  223.     {
  224.       num_blocks = fsize / BUFFERSIZE;
  225.       for( block = 0; block < num_blocks; block++ )
  226.         {
  227.           if( ( pDisk->nbytes = fwrite( pDisk->buffer, 1, BUFFERSIZE, fs)) < 0 )
  228.             {
  229.               printf( "init: error writing block\n" );
  230.               EndItAll( 1, pDisk );
  231.             }
  232.         }
  233.     }
  234.   else
  235.     {
  236.       if( ( pDisk->nbytes = fwrite( pDisk->buffer, 1, fsize, fs )) < 0 )
  237.         {
  238.           printf( "init: error writing block\n ");
  239.           EndItAll( 1, pDisk );
  240.         }
  241.     }
  242.   fclose( fs );
  243. }
  244.  
  245. void readswrites( PDTV pDisk )
  246. {
  247.   int  i, j;
  248.   int  xfer, num_xfer;      /*to access buffer correct # times*/
  249.   long xfer_amt;            /*amount to transfer to/from buffer*/
  250.   int  fsize_index;            /*file size index (0..8)*/
  251.   int  rnum;                /*rand. num to choose read or write*/
  252.   int  rep1, rep2;            /*indices to loop through each file*/
  253.                               /*set twice, and all sets three times*/
  254.  
  255.   for( rep1 = 0; rep1 < 3; rep1++ )
  256.     {        /*in order to achieve locality which*/
  257.       for( i = 0; i < NSETS; i++ )
  258.         {        /*is consistent with buffer cache data*/
  259.           for( rep2 = 0; rep2 < 2; rep2++ )
  260.             {    /*of Ousterhout et al (1985)*/
  261.               for( j = 0; j < SET_SIZE; j++ )
  262.                 {
  263.                   if( ( pDisk->fd = open( pDisk->files[ i ][ j ], 2)) < 0 )
  264.                     {
  265.                       printf( "readswrites: cannot open file\n" );
  266.                       EndItAll( 1, pDisk );
  267.                     }
  268.                   fsize_index = *( pDisk->files[ i ][ j ] ) - '0';     /*max xfer_amt = BUFFERSIZE*/
  269.                   if( pDisk->bsize[ fsize_index ] >= BUFFERSIZE )
  270.                     {
  271.                       num_xfer = pDisk->bsize[ fsize_index ] / BUFFERSIZE;
  272.                       xfer_amt = BUFFERSIZE;
  273.                     }
  274.                   else
  275.                     {
  276.                       num_xfer = 1;
  277.                       xfer_amt = pDisk->bsize[ fsize_index ];
  278.                     }
  279.                   rnum = my_rand( 3 );
  280.                   if( rnum < 2 )
  281.                     {        /*read:write = 2:1*/
  282.                       lseek( pDisk->fd, 0L, 0 );
  283.                       for( xfer = 0; xfer < num_xfer; xfer++ )
  284.                         {
  285.                           if( ( pDisk->nbytes = read( pDisk->fd, pDisk->buffer, xfer_amt)) < 0 )
  286.                             {
  287.                               printf( "readswrites %d: read error\n", pDisk->ulTask );
  288.                               EndItAll( 1, pDisk );
  289.                              }
  290.                         }
  291.                     }
  292.                   else
  293.                     {
  294.                       lseek( pDisk->fd, 0L, 0 );
  295.                       for( xfer = 0; xfer < num_xfer; xfer++ )
  296.                         {
  297.                           if( ( pDisk->nbytes = write( pDisk->fd, pDisk->buffer, xfer_amt)) < 0 )
  298.                             {
  299.                               printf( "readswrites %d: write error\n", pDisk->ulTask );
  300.                               EndItAll( 1, pDisk );
  301.                             }
  302.                         }
  303.                     }
  304.                   close( pDisk->fd );
  305.                 }
  306.             }
  307.         }
  308.     }
  309. }
  310.  
  311. void EndItAll( int rc, PDTV pDisk )
  312. {
  313.   pDisk->ulCount   = ( CONST * ITER );
  314.   pDisk->iExitCode = rc;
  315.   DosPostEventSem( pDisk->hevDone );
  316.  
  317.   DosExit( 0, rc );
  318. }
  319.  
  320.  
  321. void removefiles( PDTV pDisk )
  322. {
  323.   int i, j, k;
  324.  
  325.   /*remove files*/
  326.   for( i = 0; i < NSETS; i++ )
  327.     for( j = 0; j < SET_SIZE; j++ )
  328.       unlink( pDisk->files[ i ][ j ] );
  329.  
  330.   for( k = 0; k < NBFLUSH_FILES; k++ )
  331.     unlink( pDisk->buf_flush_files[ k ] );
  332.  
  333.   chdir( "\\" );
  334.   rmdir( pDisk->szDir );
  335. }
  336.  
  337.