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 >
Text File  |  1990-03-20  |  5KB  |  140 lines

  1. *****Listing 1*****
  2.  
  3. /* I/O subsystem simulation */
  4.  
  5. #include <stdio.h>
  6. #include <csimdefs.h>
  7. #include <stdlib.h>
  8. #include <assert.h>
  9.  
  10. /* Simulation clock scaling times */
  11. #define SEC(x)  ((TIME) ((x) * 1000) * 10)
  12. #define MS(x)   ((TIME) ((x) * 10))
  13.  
  14. /* model configuration constants */
  15. #define NO_CU           2L      /* the number of control units */
  16. #define NO_DRIVES       8       /* the number of disk drives */
  17. #define NO_SKEWED       2       /* skew the load toward 2 drives */
  18. #define SKEW_PERCENT    80      /* skew the load by 80% */
  19. #define HIT_PERCENT     90      /* 90% cache hit rate */
  20.  
  21. /* Max seek time is 12 MS case 3 - 24 MS. */
  22. #define MAXSEEK_TM      (MS(((Case == DOUBSEEK) ? 2 : 1) * 12))
  23.  
  24. /* case study types */
  25. enum    {
  26.         UNINIT,                 /* uninitialized */
  27.         BTREE,                  /* binary B-tree */
  28.         TRACKBUF,               /* track buffer */
  29.         DOUBSEEK                /* doubled seek time */
  30. }       Case = UNINIT;
  31.  
  32. /* check for a free data path in the control unit */
  33. int     path_avail(MS_PTR cu) {
  34. long    cu_avail;
  35.  
  36.         MAvail(cu,&cu_avail);
  37.         return(cu_avail != 0);
  38. }
  39.  
  40. /* perform a control unit level I/O */
  41. void cu_io(long arm, MS_PTR cu, SAS_PTR drives) {
  42. TIME    t;
  43.  
  44.         MSeize(cu,1L); /* Seize one of the data paths */
  45.         /* determine if this is a cache hit */
  46.         if (Percent() < HIT_PERCENT) { /* cache hit */
  47.                 /* calculate the hit lookup time based on scenario */
  48.                 t = (TIME) (Case == BTREE)? 2: 1;
  49.                 /* simulate time passing for cache lookup */
  50.                 XacAdvance(MS(t));
  51.                 /* simulate the data transfer time       *
  52.                  * transfer at buffer speeds not device  */
  53.                 XacAdvance(MS(1.2));
  54.         } else {  /* cache miss (with device access) */
  55.                 /* simulate the cache miss overhead processing */
  56.                 XacAdvance(MS(2));
  57.                 /* release the data path during the device access */
  58.                 MRelease(cu,1L);
  59.                 /* get exclusive access to the physical device */
  60.                 SASeize(drives,arm);
  61.                 /* simulate the drive seek time */
  62.                 XacAdvUniform((TIME)0,MAXSEEK_TM);
  63.                 /* simulate the wait for the data (latency) */
  64.                 XacAdvUniform((TIME)0,MS(16.7));
  65.                 /* if the device has a track buffer, */
  66.                 if (Case == TRACKBUF) {
  67.                         /* get one of the data pathes */
  68.                         MSeize(cu,1L);
  69.                 } else { /* without a track buffer */
  70.             /* synchronize the availability of the     *
  71.                      * data path with the rotation of the disk */
  72.                         while (!path_avail(cu)) {
  73.                                 /* wait one full rotation for the data */
  74.                                 XacAdvance(MS(16.7));
  75.                         }
  76.                         /* get one of the data pathes with no waiting */
  77.                         MSeize(cu,1L);
  78.                 }
  79.                 /* simulate the data transfer at device speeds */
  80.                 XacAdvance(MS(2.4));
  81.                 /* release the physical device */
  82.                 SARelease(drives,arm);
  83.         }
  84.         /* release the data path */
  85.         MRelease(cu,1L);
  86. }       
  87.  
  88. /* I/O subsystem model entry point */
  89. sim_main(int argc, char *argv[]) {
  90. Q_PTR   io_resp_time;   /* response time for the IO */
  91. MS_PTR  cu;             /* control unit resources */
  92. SAS_PTR drives;         /* physical drive servers */
  93. SAS_PTR vdrives;        /* virtual drive servers */
  94. TIME    warm_time;      /* model warm up time */
  95. TIME    run_time;       /* model run time */
  96. TIME    siorate;        /* start I/O rate */
  97. long    arm;            /* drive number */
  98.  
  99.         /* read in the command line parameters */
  100.         assert(argc == 5);
  101.         warm_time = (TIME) atol(argv[1]);
  102.         run_time = (TIME) atol(argv[2]);
  103.         siorate = SEC(1) / (TIME) atol(argv[3]);
  104.         Case = atoi(argv[4]);
  105.  
  106.         /* setup warm up and run time for model. */
  107.         SimWarmUp((TIME) SEC(warm_time),1);
  108.         SimRun((TIME) SEC(run_time),1);
  109.  
  110.         /* create the model resources */
  111.         Queue(&io_resp_time,"I/O Responce Time");
  112.         MServer(&cu,NO_CU,"Control Unit Data Pathes");
  113.         SArray(&drives,NO_DRIVES,"Physical Subsystem Disk Drive");
  114.         SArray(&vdrives,NO_DRIVES,"Virtual Subsystem Disk Drive");
  115.  
  116.         /* generate I/O requests at the specified start I/O rate */
  117.         XacGenExponen(siorate, GENFOREVER);
  118.         /* skew the I/O load toward fewer drives */
  119.         if (Percent() < SKEW_PERCENT) {
  120.                 /* select one of the heavily loaded drives */
  121.                 arm = rand() % NO_SKEWED;
  122.         } else {
  123.                 /* select one of the lightly loaded drives */
  124.                 arm = (rand() % (NO_DRIVES - NO_SKEWED)) + NO_SKEWED;
  125.         }
  126.         
  127.         /* capture response times */
  128.         QEnter(io_resp_time);
  129.         /* allow only one I/O in subsystem per drive */
  130.         SASeize(vdrives,arm);
  131.         /* perform the I/O */
  132.         cu_io(arm,cu,drives);
  133.         /* finish taking statistics */
  134.         QLeave(io_resp_time);
  135.         /* release the virtual drive for the next I/O */
  136.         SARelease(vdrives,arm);
  137.         /* kill off this I/O */
  138.         XacTerminate();
  139. }
  140.