home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 8 Other
/
08-Other.zip
/
mdisk.lzh
/
DiskThd.C
next >
Wrap
C/C++ Source or Header
|
1993-12-02
|
11KB
|
337 lines
/*
*
* "I/O Stone" Benchmark Program
*
* Written by: Arvin Park (park@midas.ucdavis.edu) and
* Jeff Becker (becker@iris.ucdavis.edu)
* Division of Computer Science
* University of California, Davis
* Davis CA 95616
* (916) 752-5183
*
* Version C/II
* Date: 06/27/90
*
* Defines: If your version of "C" does not include an ftime()
* function or the C library time.h, define NOTIME.
* Use a stopwatch to measure elapsed wall time.
* Divide 2,000,000 by the elapsed time to get
* the correct number of iostones/second.
*
* To compile: cc -O io.c -o io
*
* Note: [1] This program should be run without other processes
* competing for system resources. Run it in the dead of
* night if you have to.
*
* [2] This program uses 5 megabytes of disk space. Make
* sure that at least this much space is available on
* your file system before you run the program.
*
* Results: If you get results from a new (machine/operating
* system/disk controller and drive) combination, please
* send them to becker@iris.ucdavis.edu. Please include
* complete information on the machine type, operating
* system, version, disk controller, and disk drives.
* Also make a note of any system modifications that
* have been performed.
*
*-------------------------------------------------------------------------
* 8/26/91 Tin Le
* Added simple Makefile.
*
* As far as I can determine from examining the code, iostone is
* meant for benchmarking file I/O and buffer cache efficiencies.
*
* It does this by creating NSETS (4) of SET_SIZE (99) files. Then
* iostone performs I/O on each file in each set. The type of I/O is
* randomly picked (r/w).
*
*--------------------------------------------------------------------------
* 7/21/93 Oddgeir Kvien, kvien@elkraft.unit.no
*
* Slightly modified to compile with Borland C++ for OS/2
*
*--------------------------------------------------------------------------
* 11/93 Jeffrey Patten 1:2410/242@fidonet.org
*
* IOStone gets chopped to pieces to adapt it as a portion of a
* multithreaded disk/cpu usage benchmark. The numbers generated
* are -NOT- comparable to those generated by the original program.
* No attempt was made to maintain portability - my programming skills
* are not yet advanced enough for that.
*
*--------------------------------------------------------------------------
*/
#define INCL_NOPMAPI
#define INCL_DOS
#include <os2.h>
#include "MDisk.h"
#include <dir.h>
#include <stdio.h>
#include <io.h>
#include <string.h>
#include <time.h>
#include <stdlib.h>
/* PREDEFINISJON */
int my_rand( int max );
void initfile( char *fname, long fsize, PDTV pDisk );
void readswrites( PDTV pDisk );
void EndItAll( int rc, PDTV pDisk );
VOID APIENTRY ThdDskPerf( ULONG ulTask )
{
int k;
PDTV pDisk;
pDisk = (PDTV)ulTask;
pDisk->szDir[ 6 ] = (char)( pDisk->ulTask + 0x30 );
pDisk->szDir[ 7 ] = 0;
setdisk( (int)( pDisk->szDrive[ 0 ] - 'A' ) );
mkdir( pDisk->szDir );
chdir( pDisk->szDir );
/* create test files */
DosPostEventSem( pDisk->hevReady );
/* start timing */
DosWaitEventSem( hevGo, SEM_INDEFINITE_WAIT );
/* perform string of file operations */
for( k = 0; k < ITER; k++ )
readswrites( pDisk );
/*stop timimg*/
EndItAll( 0, pDisk );
}
void init( PDTV pDisk )
{
int this_set; /*mark the file set (0..NSETS-1)*/
int bcount; /*counter to track #spacer files*/
int fcount; /*a counter to tell where to create*/
int i, j, k; /*files to flush buffer cache and*/
/*spread other files across disk*/
pDisk->bsize[ 0 ] = 256; pDisk->bfreq[ 0 ] = 128;
pDisk->bsize[ 1 ] = 512; pDisk->bfreq[ 1 ] = 64;
pDisk->bsize[ 2 ] = 1024; pDisk->bfreq[ 2 ] = 64;
pDisk->bsize[ 3 ] = 2048; pDisk->bfreq[ 3 ] = 64;
pDisk->bsize[ 4 ] = 4096; pDisk->bfreq[ 4 ] = 32; /*set file block sizes and*/
pDisk->bsize[ 5 ] = 8192; pDisk->bfreq[ 5 ] = 32; /*access frequencies*/
pDisk->bsize[ 6 ] = 16384; pDisk->bfreq[ 6 ] = 8;
pDisk->bsize[ 7 ] = 32768; pDisk->bfreq[ 7 ] = 2;
pDisk->bsize[ 8 ] = 65536; pDisk->bfreq[ 8 ] = 2;
k = 0; /*set up files*/
bcount = 0;
fcount = 0;
for( i = 0; i < NBLOCKSIZES; i++ )
{
for( j = 0; j < pDisk->bfreq[ i ]; j++ )
{
if( i < NBLOCKSIZES - 1 )
this_set = j % NSETS;
else
this_set = ( j + 2 ) % NSETS;
sprintf( pDisk->tmp, "%0d_%0d", i, j ); /*create filename*/
pDisk->files[ this_set ][ k ] = malloc( 1 + strlen( pDisk->tmp ));
if( ! pDisk->files[ this_set ][ k ] )
{
printf( "Could not allocate string for filename\n" );
EndItAll( 1, pDisk );
}
strcpy( pDisk->files[ this_set ][ k ], pDisk->tmp );
initfile( pDisk->tmp, pDisk->bsize[ i ], pDisk );
if( i < NBLOCKSIZES - 1 && this_set == NSETS - 1 )
k++;
if( bcount < NBFLUSH_FILES && fcount % 44 == 0 )
{
sprintf( pDisk->tmp, "%bf_%0d", bcount ); /*create spacer file*/
pDisk->buf_flush_files[ bcount ] = malloc( 1 + strlen( pDisk->tmp ));
if( ! pDisk->buf_flush_files[ bcount ] )
{
printf( "Could not allocate string for filename\n" );
EndItAll( 1, pDisk );
}
strcpy( pDisk->buf_flush_files[ bcount ], pDisk->tmp );
initfile( pDisk->tmp, BFLUSH_FILE_SIZE, pDisk );
bcount++;
}
fcount++;
}
}
for( i = 0; i < NBFLUSH_FILES; i++ )
{ /*read spacer files to flush buffers*/
if( ( pDisk->fd = open( pDisk->buf_flush_files[ i ], 2)) < 0 )
{
printf( "error opening buffer flush file\n" );
EndItAll( 1, pDisk );
}
lseek( pDisk->fd, 0L, 0 );
k = BFLUSH_FILE_SIZE / BUFFERSIZE;
for( j = 0; j < k; j++ )
{
if( ( pDisk->nbytes = read( pDisk->fd, pDisk->buffer, BUFFERSIZE )) < 0 )
{
printf( "Error reading buffer flush file\n" );
EndItAll( 1, pDisk );
}
}
close( pDisk->fd );
}
srand( SEED ); /*initialize random number generator*/
for( i = 0; i < NSETS; i++ )
{ /*permutation for reading/writing*/
for( j = SET_SIZE; j > 0; j-- )
{
k = my_rand( j );
strcpy( pDisk->tmp, pDisk->files[ i ][ j - 1 ] );
strcpy( pDisk->files[ i ][ j - 1 ], pDisk->files[ i ][ k ] );
strcpy( pDisk->files[ i ][ k ], pDisk->tmp );
}
}
}
int my_rand( int max )
{
return rand() % max;
}
void initfile( char *fname, long fsize, PDTV pDisk )
{ /*create a temporary file*/
FILE *fs;
int block, num_blocks;
if(( fs = fopen( fname, "w" )) == NULL )
{
printf( "init: Cannot create temporary file\n" );
EndItAll( 1, pDisk );
}
rewind( fs ); /*write initial portion of file*/
if( fsize > BUFFERSIZE )
{
num_blocks = fsize / BUFFERSIZE;
for( block = 0; block < num_blocks; block++ )
{
if( ( pDisk->nbytes = fwrite( pDisk->buffer, 1, BUFFERSIZE, fs)) < 0 )
{
printf( "init: error writing block\n" );
EndItAll( 1, pDisk );
}
}
}
else
{
if( ( pDisk->nbytes = fwrite( pDisk->buffer, 1, fsize, fs )) < 0 )
{
printf( "init: error writing block\n ");
EndItAll( 1, pDisk );
}
}
fclose( fs );
}
void readswrites( PDTV pDisk )
{
int i, j;
int xfer, num_xfer; /*to access buffer correct # times*/
long xfer_amt; /*amount to transfer to/from buffer*/
int fsize_index; /*file size index (0..8)*/
int rnum; /*rand. num to choose read or write*/
int rep1, rep2; /*indices to loop through each file*/
/*set twice, and all sets three times*/
for( rep1 = 0; rep1 < 3; rep1++ )
{ /*in order to achieve locality which*/
for( i = 0; i < NSETS; i++ )
{ /*is consistent with buffer cache data*/
for( rep2 = 0; rep2 < 2; rep2++ )
{ /*of Ousterhout et al (1985)*/
for( j = 0; j < SET_SIZE; j++ )
{
if( ( pDisk->fd = open( pDisk->files[ i ][ j ], 2)) < 0 )
{
printf( "readswrites: cannot open file\n" );
EndItAll( 1, pDisk );
}
fsize_index = *( pDisk->files[ i ][ j ] ) - '0'; /*max xfer_amt = BUFFERSIZE*/
if( pDisk->bsize[ fsize_index ] >= BUFFERSIZE )
{
num_xfer = pDisk->bsize[ fsize_index ] / BUFFERSIZE;
xfer_amt = BUFFERSIZE;
}
else
{
num_xfer = 1;
xfer_amt = pDisk->bsize[ fsize_index ];
}
rnum = my_rand( 3 );
if( rnum < 2 )
{ /*read:write = 2:1*/
lseek( pDisk->fd, 0L, 0 );
for( xfer = 0; xfer < num_xfer; xfer++ )
{
if( ( pDisk->nbytes = read( pDisk->fd, pDisk->buffer, xfer_amt)) < 0 )
{
printf( "readswrites %d: read error\n", pDisk->ulTask );
EndItAll( 1, pDisk );
}
}
}
else
{
lseek( pDisk->fd, 0L, 0 );
for( xfer = 0; xfer < num_xfer; xfer++ )
{
if( ( pDisk->nbytes = write( pDisk->fd, pDisk->buffer, xfer_amt)) < 0 )
{
printf( "readswrites %d: write error\n", pDisk->ulTask );
EndItAll( 1, pDisk );
}
}
}
close( pDisk->fd );
}
}
}
}
}
void EndItAll( int rc, PDTV pDisk )
{
pDisk->ulCount = ( CONST * ITER );
pDisk->iExitCode = rc;
DosPostEventSem( pDisk->hevDone );
DosExit( 0, rc );
}
void removefiles( PDTV pDisk )
{
int i, j, k;
/*remove files*/
for( i = 0; i < NSETS; i++ )
for( j = 0; j < SET_SIZE; j++ )
unlink( pDisk->files[ i ][ j ] );
for( k = 0; k < NBFLUSH_FILES; k++ )
unlink( pDisk->buf_flush_files[ k ] );
chdir( "\\" );
rmdir( pDisk->szDir );
}