home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The C Users' Group Library 1994 August
/
wc-cdrom-cusersgrouplibrary-1994-08.iso
/
listings
/
v_08_04
/
8n04044a
< prev
next >
Wrap
Text File
|
1990-03-20
|
5KB
|
140 lines
*****Listing 1*****
/* I/O subsystem simulation */
#include <stdio.h>
#include <csimdefs.h>
#include <stdlib.h>
#include <assert.h>
/* Simulation clock scaling times */
#define SEC(x) ((TIME) ((x) * 1000) * 10)
#define MS(x) ((TIME) ((x) * 10))
/* model configuration constants */
#define NO_CU 2L /* the number of control units */
#define NO_DRIVES 8 /* the number of disk drives */
#define NO_SKEWED 2 /* skew the load toward 2 drives */
#define SKEW_PERCENT 80 /* skew the load by 80% */
#define HIT_PERCENT 90 /* 90% cache hit rate */
/* Max seek time is 12 MS case 3 - 24 MS. */
#define MAXSEEK_TM (MS(((Case == DOUBSEEK) ? 2 : 1) * 12))
/* case study types */
enum {
UNINIT, /* uninitialized */
BTREE, /* binary B-tree */
TRACKBUF, /* track buffer */
DOUBSEEK /* doubled seek time */
} Case = UNINIT;
/* check for a free data path in the control unit */
int path_avail(MS_PTR cu) {
long cu_avail;
MAvail(cu,&cu_avail);
return(cu_avail != 0);
}
/* perform a control unit level I/O */
void cu_io(long arm, MS_PTR cu, SAS_PTR drives) {
TIME t;
MSeize(cu,1L); /* Seize one of the data paths */
/* determine if this is a cache hit */
if (Percent() < HIT_PERCENT) { /* cache hit */
/* calculate the hit lookup time based on scenario */
t = (TIME) (Case == BTREE)? 2: 1;
/* simulate time passing for cache lookup */
XacAdvance(MS(t));
/* simulate the data transfer time *
* transfer at buffer speeds not device */
XacAdvance(MS(1.2));
} else { /* cache miss (with device access) */
/* simulate the cache miss overhead processing */
XacAdvance(MS(2));
/* release the data path during the device access */
MRelease(cu,1L);
/* get exclusive access to the physical device */
SASeize(drives,arm);
/* simulate the drive seek time */
XacAdvUniform((TIME)0,MAXSEEK_TM);
/* simulate the wait for the data (latency) */
XacAdvUniform((TIME)0,MS(16.7));
/* if the device has a track buffer, */
if (Case == TRACKBUF) {
/* get one of the data pathes */
MSeize(cu,1L);
} else { /* without a track buffer */
/* synchronize the availability of the *
* data path with the rotation of the disk */
while (!path_avail(cu)) {
/* wait one full rotation for the data */
XacAdvance(MS(16.7));
}
/* get one of the data pathes with no waiting */
MSeize(cu,1L);
}
/* simulate the data transfer at device speeds */
XacAdvance(MS(2.4));
/* release the physical device */
SARelease(drives,arm);
}
/* release the data path */
MRelease(cu,1L);
}
/* I/O subsystem model entry point */
sim_main(int argc, char *argv[]) {
Q_PTR io_resp_time; /* response time for the IO */
MS_PTR cu; /* control unit resources */
SAS_PTR drives; /* physical drive servers */
SAS_PTR vdrives; /* virtual drive servers */
TIME warm_time; /* model warm up time */
TIME run_time; /* model run time */
TIME siorate; /* start I/O rate */
long arm; /* drive number */
/* read in the command line parameters */
assert(argc == 5);
warm_time = (TIME) atol(argv[1]);
run_time = (TIME) atol(argv[2]);
siorate = SEC(1) / (TIME) atol(argv[3]);
Case = atoi(argv[4]);
/* setup warm up and run time for model. */
SimWarmUp((TIME) SEC(warm_time),1);
SimRun((TIME) SEC(run_time),1);
/* create the model resources */
Queue(&io_resp_time,"I/O Responce Time");
MServer(&cu,NO_CU,"Control Unit Data Pathes");
SArray(&drives,NO_DRIVES,"Physical Subsystem Disk Drive");
SArray(&vdrives,NO_DRIVES,"Virtual Subsystem Disk Drive");
/* generate I/O requests at the specified start I/O rate */
XacGenExponen(siorate, GENFOREVER);
/* skew the I/O load toward fewer drives */
if (Percent() < SKEW_PERCENT) {
/* select one of the heavily loaded drives */
arm = rand() % NO_SKEWED;
} else {
/* select one of the lightly loaded drives */
arm = (rand() % (NO_DRIVES - NO_SKEWED)) + NO_SKEWED;
}
/* capture response times */
QEnter(io_resp_time);
/* allow only one I/O in subsystem per drive */
SASeize(vdrives,arm);
/* perform the I/O */
cu_io(arm,cu,drives);
/* finish taking statistics */
QLeave(io_resp_time);
/* release the virtual drive for the next I/O */
SARelease(vdrives,arm);
/* kill off this I/O */
XacTerminate();
}