home *** CD-ROM | disk | FTP | other *** search
- _THE FIVE LEVELS OF RAID_
- by Mike Wiebel and Steve Johnson
-
- [LISTING ONE]
-
-
- /* sled.c */
-
- #include <stdio.h>
- #include <assert.h>
- #include <csimdefs.h>
-
- #define HMSEC(x) ((TIME)((x))) /* 1.0e-05 second */
- #define MSEC(x) ((TIME)(100.0 * (x))) /* milli second */
- #define SEC(x) MSEC((1000.0 * (x))) /* second */
- #define MINUTE(x) SEC((60.0 * (x))) /* minute */
- #define HOUR(x) MINUTE((60.0 * (x)))
-
- #define NUM_DISKS 1 /* num. disks in simulation */
- #define NUM_FE 1L /* num. front end channels */
- #define NUM_BE 1L /* num. back end channels */
- #define SEEK_TIME 3.83 /* avg. num. of milliseconds spent seeking */
- #define LATENCY 14.22 /* milliseconds required for one rotation */
- #define NUM_CYLINDERS 1113 /* num. cylinders on disk */
- #define TRACKS_PER_CYL 15 /* num. tracks per cylinder */
-
- SS_PTR cu; /* CSIM control unit pointer */
- SS_PTR disk_drive; /* CSIM disk drive pointer */
- MS_PTR fe_bus; /* CSIM front end channel pointer */
- MS_PTR be_bus; /* CSIM back end channel pointer */
-
- static long track=0L; /* current track backing */
- static int cylinder=0; /* current cylinder backing */
- static long tot_tracks=0L; /* total tracks backed */
-
- void backup_status(done)
- int *done;
- {
-
- /* determine if this disk drive is backed up. */
-
- track++;
- tot_tracks++;
- if (tot_tracks == NUM_DISKS * NUM_CYLINDERS * TRACKS_PER_CYL)
- *done = 1;
- }
-
- ECODE seek()
- {
- long num_fe; /* num. front end channels available */
-
- if(track == 1){ /* first track requires seek */
- XacAdvExponen(MSEC(SEEK_TIME));
- }
- if(track == TRACKS_PER_CYL){
- XacAdvance(MSEC(LATENCY));/* switch cylinder and rotate */
- track = 0;
- cylinder++;
- }
-
- /* if channel is available transmit data; else rotational delay */
-
- MAvail(fe_bus,&num_fe);
- while(!num_fe){
- XacAdvance(MSEC(LATENCY));
- MAvail(fe_bus,&num_fe);
-
-
- /* sled.c - 2 */
- }
- return(SUCCESS);
- }
-
- ECODE send_data()
- {
- double xfr_time;
-
- /* transfer data back to host */
-
- xfr_time = LATENCY;
- MSeize(fe_bus,1L);
- XacAdvance(MSEC(xfr_time));
- MRelease(fe_bus,1L);
- return(SUCCESS);
- }
-
- int sim_main(argc, argv)
- int argc;
- char *argv[];
- {
- int done=0;
- int i;
-
- /* configure system and set up CSIM statistics */
-
- SServer(&cu,"control unit statistics");
- SServer(&disk_drive,"disk drive statistics");
- MServer(&fe_bus,NUM_FE,"front end channels");
- MServer(&be_bus,NUM_BE,"back end channels");
-
- /* set simulation time */
-
- SimWarmUp(0,0);
- SimRun(MINUTE(30),1);
-
- /* simulate backup */
-
- SSeize(disk_drive);
- SSeize(cu);
- MSeize(be_bus,1L);
- for(i=0; i<NUM_DISKS; i++){
- do{
- backup_status(&done);
- assert(seek() == SUCCESS);
- assert(send_data() == SUCCESS);
- }while(!done);
- done = 0;
- track = 0;
- }
- printf("Backup complete\n");
- SimPrint();
- SRelease(cu);
- MRelease(be_bus,1L);
- SRelease(disk_drive);
- XacTerminate();
- }
-
-
- [LISTING TWO]
-
- /* RAID level 1 */
- #include <stdio.h>
- #include <assert.h>
- #include <csimdefs.h>
-
- #define HMSEC(x) ((TIME)((x))) /* hund.milli second */
- #define MSEC(x) ((TIME)(100.0 * (x))) /* milli second */
- #define SEC(x) MSEC((1000.0 * (x))) /* seconds */
- #define MINUTE(x) SEC((60.0 * (x))) /* minutes */
- #define HOUR(x) MINUTE((60.0 * (x)))
-
- #define NUM_DISKS 1 /* one disk; other disk is mirror */
- #define NUM_FE 2L /* num. front end channels */
- #define NUM_BE 2L /* num. back end channels */
- #define NUM_CU 2L /* num. of control units */
- #define SEEK_TIME 3.83 /* avg. num. of milliseconds spent seeking */
- #define LATENCY 14.22 /* avg. num. milliseconds spent seeking */
- #define NUM_CYLINDERS 2226
- #define TRACKS_PER_CYL 15
-
- MS_PTR cu; /* CSIM control unit pointer */
- MS_PTR disk_drive; /* CSIM disk drive pointer */
- MS_PTR fe_bus; /* CSIM front end channel pointer */
- MS_PTR be_bus; /* CSIM back end channel pointer */
- Q_PTR tsend;
-
- static long track=0L;
- static int curr_cylinder=0;
-
- void backup_status(done)
- int *done;
- {
- /* determine if this disk drive is backed up. */
-
- track++;
- if (track == TRACKS_PER_CYL){
- track = 0;
- curr_cylinder++;
- }
- if (curr_cylinder == NUM_CYLINDERS * NUM_DISKS)
- *done = 1;
- }
-
- ECODE seek(cylinder_backing)
- int *cylinder_backing;
- {
- long num_fe;
-
- if(curr_cylinder == 0 && track == 1){ /* first track requires seek */
- XacAdvExponen(MSEC(SEEK_TIME));
- }
- if(*cylinder_backing != curr_cylinder){
- XacAdvance(MSEC(LATENCY));
- *cylinder_backing = curr_cylinder;
- }
- return(SUCCESS);
- }
-
-
-
-
- /* lvl1.c - 2 */
-
- ECODE send_data()
- {
- double xfr_time;
-
-
- /* transfer data back to host */
- xfr_time = LATENCY;
-
- MSeize(fe_bus,1L);
- XacAdvance(MSEC(xfr_time));
- MRelease(fe_bus,1L);
- return(SUCCESS);
- }
-
- int sim_main(argc, argv)
- int argc;
- char *argv[];
- {
- XAC_PTR xp;
- BOOLEAN orig;
- static int done=0;
- int cylinder_backing=0;
- int i;
-
- /* configure system and set up CSIM utilities */
- MServer(&disk_drive,2L,"Disk drive server statistics");
- MServer(&cu,NUM_CU,"Control unit server statistics");
- MServer(&fe_bus,NUM_FE,"front end channel statistics");
- MServer(&be_bus,NUM_BE,"back end channel statistics");
- Queue(&tsend,"Time to send data");
- /* set simulation time */
- SimWarmUp(0,0);
- SimRun(MINUTE(17),1);
- /* simulate backup */
- XacSplit(&xp,&orig); /* allow each disk subsys to transfer */
- MSeize(cu,1L);
- MSeize(be_bus,1L);
- MSeize(disk_drive,1L);
- for(i=0; i<NUM_DISKS; i++){
- do{
- assert(seek(&cylinder_backing)==SUCCESS);
- QEnter(tsend);
- assert(send_data()==SUCCESS);
- QLeave(tsend);
- backup_status(&done);
- }while(!done);
- done = 0;
- track = 0;
- }
- SimPrint();
- MRelease(cu,1L);
- MRelease(be_bus,1L);
- MRelease(disk_drive,1L);
- XacTerminate();
- }
-
-
- [LISTING THREE]
-
- /* RAID level 3 */
-
- #include <stdio.h>
- #include <csimdefs.h>
-
- #define HMSEC(x) ((TIME)((x))) /* 1.0e-05 second */
- #define MSEC(x) ((TIME)(100.0 * (x))) /* milli second */
- #define SEC(x) MSEC((1000.0 * (x))) /* second */
- #define MINUTE(x) SEC((60.0 * (x))) /* minute */
- #define HOUR(x) MINUTE((60.0 * (x)))
-
- #define GRP_SIZE 4 /* no. data disks in parity group */
- #define NUM_CHECK 1 /* no. check disks in group */
- #define NUM_CHAN 2L /* no. of channels */
- #define NUM_BUSS 5L /* no. busses */
- #define SEEK_TIME 11.5 /* avg. num. of milliseconds spent seeking */
- #define LATENCY 16.66 /* milliseconds required for one rotation */
- #define TRACK_CAPACITY 40.0 /* capacity in KB */
- #define XFR_RATE 10000.0 /* KB transferred per sec */
- #define NUM_CYLINDERS 1900 /* no. useable cylinders on device */
- #define TRACKS_PER_CYL 19 /* no. tracks per cylinder */
- #define SWITCH_TIME 4 /* milliseconds */
-
- SS_PTR raid_cu; /* CSIM RAID control unit pointer */
- MS_PTR data_disk; /* CSIM array of data disks pointer */
- SS_PTR check_disk; /* CSIM check disk pointer */
- MS_PTR buss; /* CSIM array of busses pointer */
- MS_PTR channel; /* CSIM array of channels pointer */
-
-
- ECODE seek(track_tally,original,track_count)
- long track_tally;
- BOOLEAN original;
- int *track_count;
- {
-
- if (original){
- SSeize(check_disk);
- }
- else{
- MSeize(data_disk,1L);
- }
- if (!track_tally){
- XacAdvExponen(MSEC(SEEK_TIME));
- }
- if (!(*track_count) && track_tally){/* switch cylinders */
- XacAdvance(MSEC(SWITCH_TIME));
- }
- (*track_count)++;
- if (*track_count == TRACKS_PER_CYL)
- *track_count = 0;
-
- if (original){
- SRelease(check_disk);
- }
- else{
- MRelease(data_disk,1L);
- }
- return(SUCCESS);
- }
-
- /* lvl3.c - 2 */
-
- ECODE transfer()
- {
- double xfr_time;
- XAC_PTR xp;
- BOOLEAN orig;
-
- /* send data to control unit */
-
- MSeize(buss,1L);
- XacAdvance(MSEC(LATENCY));
- MRelease(buss,1L);
-
- /* send data to host */
-
- XacSplit(&xp,&orig);
- if (!orig){
- xfr_time = TRACK_CAPACITY/XFR_RATE;
- MSeize(channel,1L);
- XacAdvance(SEC(xfr_time));
- MRelease(channel,1L);
- XacTerminate();
- }
- return(SUCCESS);
- }
-
- int sim_main(argc, argv)
- int argc;
- char *argv[];
- {
- static int done=0; /* flag indicating completion */
- int track_count=0;
- long track_tally=0; /* count of tracks backed up */
- long backup_goal; /* total number of tracks to back up */
- int i; /* counter */
- XAC_PTR xp; /* CSIM transaction pointer */
- BOOLEAN original; /* flag indicating presence of original xac */
-
- /* configure system and set up CSIM */
-
- SServer(&raid_cu,"Control unit server statistics");
- SServer(&check_disk,"check disk statistics");
- MServer(&data_disk,GRP_SIZE,"data disk statistics");
- MServer(&buss,NUM_BUSS,"buss statistics");
- MServer(&channel,NUM_CHAN,"channel statistics");
-
- /* set simulation period */
-
- SimWarmUp(0,0);
- SimRun(MINUTE(30),1);
-
- for(i=0; i<GRP_SIZE; i++){ /* generate xac for each disk */
- XacSplit(&xp,&original);
- if (!original)
- break;
- }
-
- /* backup subsystem */
-
-
- /* lvl3.c - 3 */
-
- backup_goal = TRACKS_PER_CYL * NUM_CYLINDERS;
- while(!done){
- seek(track_tally,original,&track_count);
- transfer();
- track_tally++;
- if (track_tally == backup_goal){
- done = 1;
- SimPrint();
- }
- }
- XacTerminate();
- }
-
-
-
- [LISTING FOUR]
-
- /* RAID level 5 */
-
- #include <stdio.h>
- #include <assert.h>
- #include <csimdefs.h>
-
- #define HMSEC(x) ((TIME)((x))) /* 1.0e-05 second */
- #define MSEC(x) ((TIME)(100.0 * (x))) /* milli second */
- #define SEC(x) MSEC((1000.0 * (x))) /* second */
- #define MINUTE(x) SEC((60.0 * (x))) /* minute */
- #define HOUR(x) MINUTE((60.0 * (x)))
-
- #define GRP_SIZE 50 /* no. data disks in parity group */
- #define NUM_CHAN 2L /* no. of channels */
- #define NUM_BUSS 50L /* no. busses */
- #define SEEK_TIME 11.5 /* avg. num. of milliseconds spent seeking */
- #define LATENCY 16.66 /* milliseconds required for one rotation */
- #define TRACK_CAPACITY 40.0 /* capacity in KB */
- #define XFR_RATE 10000.0 /* KB transferred per sec */
- #define NUM_CYLINDERS 1900 /* no. useable cylinders on device */
- #define TRACKS_PER_CYL 19 /* no. tracks per cylinder */
- #define SWITCH_TIME 4 /* milliseconds */
- #define BUF_SZ 50 /* number of tracks buffer will hold */
-
- SS_PTR raid_cu; /* CSIM RAID control unit pointer */
- SAS_PTR data_disk; /* CSIM array of data disks pointer */
- MS_PTR buss; /* CSIM array of busses pointer */
- MS_PTR channel; /* CSIM array of channels pointer */
- long buffer[BUF_SZ]; /* RAID control unit buffer */
- long update[BUF_SZ]; /* RAID buffer lock */
- static long last_buf=0L; /* last track written to buffer */
-
- void buffer_search(track,bingo,slot)
- long track;
- int *bingo;
- int *slot;
- {
- int i;
-
- *bingo = 0;
- for(i=0; i<BUF_SZ; i++)
- if(buffer[i] == track){
- *bingo = 1;
- *slot = i;
- }
- }
-
- ECODE buf_get(slot)
- int slot;
- {
- double xfer_time;
- XAC_PTR xp;
- BOOLEAN orig;
-
- xfer_time = TRACK_CAPACITY / (double)XFR_RATE;
- XacSplit(&xp,&orig);
- MSeize(channel,1L);
- XacAdvance(SEC(xfer_time/2.0));
- MRelease(channel,1L);
-
-
- /* lvl5.c - 2 */
- if(!orig){
- XacTerminate();
- }
- buffer[slot] = -1; /* mark slot as writeable */
- return(SUCCESS);
- }
-
- int find_track(track)
- long track;
- {
- int number;
-
- number = track;
- while(number >= GRP_SIZE)
- number -= GRP_SIZE;
- return(number);
- }
-
- ECODE track_get()
- {
-
- MSeize(buss,1L);
- MSeize(channel,1L);
- XacAdvance(MSEC(LATENCY));
- XacAdvance(MSEC(1));
- MRelease(channel,1L);
- MRelease(buss,1L);
- return(SUCCESS);
- }
-
- ECODE update_buf(track)
- long track;
- {
- XAC_PTR xp;
- BOOLEAN orig;
- static int i;
- static int j;
- int slot;
- long next;
- int d_num;
-
- j = 0;
- for(i=0; i<BUF_SZ; i++){
- XacSplit(&xp,&orig);
- if(!orig) break;
- }
- if(!orig){
- slot = j++;
- if(buffer[slot] < track && update[slot] != 1){
- update[slot] = 1;
- next = last_buf++;
- d_num = find_track(next);
- SASeize(data_disk,d_num);
- XacAdvance(MSEC(LATENCY));
- SARelease(data_disk,d_num);
- buffer[slot] = next;
- update[slot] = 0;
- }
-
- /* lvl5.c - 3 */
-
- XacTerminate();
- }
- return(SUCCESS);
- }
-
- int sim_main(argc, argv)
- int argc;
- char *argv[];
- {
- XAC_PTR xp; /* CSIM transaction pointer */
- BOOLEAN original; /* flag indicating presence of original xac */
- static int done=0;
- static long track=0L;
- int disk_num;
- int i;
- int slot;
- int bingo;
- BOOLEAN avail;
-
- /* configure system and set up CSIM */
-
- SServer(&raid_cu,"Control unit buffer statistics");
- SArray(&data_disk,GRP_SIZE,"data disk statistics");
- MServer(&buss,NUM_BUSS,"buss statistics");
- MServer(&channel,NUM_CHAN,"channel statistics");
-
- for(i=0; i<BUF_SZ; i++){ /* mark buffer as empty */
- buffer[i] = -1;
- update[i] = 0;
- }
-
- /* set simulation period */
-
- SimWarmUp(0,0);
- SimRun(MINUTE(30),1);
-
- while(!done){
- XacSplit(&xp,&original);
- if(original){
- buffer_search(track,&bingo,&slot);
- if(bingo){
- assert(buf_get(slot) == SUCCESS);
- }
- else{
- disk_num = find_track(track);
- SAAvail(data_disk,disk_num,&avail);
- SASeize(data_disk,disk_num);
- buffer_search(track,&bingo,&slot);
- if(bingo){
- assert(buf_get(slot) == SUCCESS);
- }
- else{
- assert(track_get() == SUCCESS);
- }
- SARelease(data_disk,disk_num);
- }
-
-
- /* lvl5.c - 3 */
-
- if (track == GRP_SIZE * TRACKS_PER_CYL * NUM_CYLINDERS)
- done = 1;
- track++;
- }
- else{ /* maintain buffer */
- assert(update_buf(track) == SUCCESS);
- XacTerminate();
- }
- }
- printf("Backup complete\n");
- SimPrint();
- }
-
-
-