예제 #1
0
static void initialize_bands(struct dm_disk_if *d) {
  int j;
  double tmptime, rotblks;
  struct dm_layout_g1 *l = (struct dm_layout_g1 *)d->layout;

  return;
  
  // Defunct.  Cook up skews if none provided in model.
  for (j = 0; j < l->bands_len; j++) {
    double period;
    // set tmptime to the greater of a headswitch for a read or a
    // write
    
    struct dm_mech_state s1 = {0,0,0}, s2 = {1,0,0};
    dm_time_t t1 = d->mech->dm_seek_time(d, &s1, &s2, 0);
    dm_time_t t2 = d->mech->dm_seek_time(d, &s1, &s2, 1);
    
    tmptime = t1 > t2 ? t1 : t2;

    period = dm_time_itod(d->mech->dm_period(d));
    rotblks = ((double)l->bands[j].blkspertrack) / period;
    //    l->bands[j].firstblkangle = l->bands[j].firstblkangle / rotblks;

    if (l->bands[j].trackskew == -1.0) {
      ddbg_assert2(0, "unimplemented");
      l->bands[j].trackskew = tmptime;
    } 
    else if (l->bands[j].trackskew == -2.0) {
      ddbg_assert2(0, "unimplemented");
      tmptime = (double) ((int) (tmptime * rotblks + 0.999999999));
      l->bands[j].trackskew = tmptime / rotblks;
    } 
    else {
      l->bands[j].trackskew = l->bands[j].trackskew;
    }

    // zero distance seek without a head switch
    // write vs. read
    // XXX ... based on disksim-pre3-28, every seek function returns
    // zero seek time for a zero distance seek!
    //    tmptime = max(diskseektime(d, 1, 0, 0), 
    //		  diskseektime(d, 1, 0, 1));
    tmptime = 0;

    if (l->bands[j].cylskew == -1.0) {
      ddbg_assert2(0, "unimplemented");
      l->bands[j].cylskew = tmptime;
    } 
    else if (l->bands[j].cylskew == -2.0) {
      ddbg_assert2(0, "unimplemented");
      tmptime = (double) ((int) (tmptime * rotblks + 0.99999999));
      l->bands[j].cylskew = tmptime / rotblks;
    } 
    else {
      l->bands[j].cylskew = l->bands[j].cylskew;
    }
  }
}
예제 #2
0
static void DISKSIM_GLOBAL_STAT_DEFINITION_FILE_loader(int result, char *s) { 
 char *path = lp_search_path(lp_cwd, s);
 if(!path) {
 ddbg_assert2(0, "Couldn't find statdefs file in path");
 }
 else {
 statdeffile = fopen(path, "r");
 ddbg_assert2(statdeffile != 0, "failed to open statdefs file!");
 }

}
예제 #3
0
static void 
cachedev_wakeup_complete (struct cache_if *c, 
			  void *d) // really struct cache_dev_event
{
  struct cache_dev_event *desc = (struct cache_dev_event *)d;
  struct cache_dev *cache = (struct cache_dev *)c;
  ASSERT (0);

#ifdef DEBUG_CACHEDEV
   fprintf (outputfile, "*** %f: Entered cachedev::cachedev_wakeup_complete (does nothing)\n", simtime );
#endif

  // ???

#if 0
   switch(desc->type) {
   case CACHE_EVENT_READ:
      cache_read_continue(cache, desc);
      break;
   case CACHE_EVENT_WRITE:
     cache_write_continue(cache, desc);
     break;
   case CACHE_EVENT_FLUSH:
      (*desc->donefunc)(desc->doneparam, desc->req);
      addtoextraq((event *) desc);
      break;

   default:
     ddbg_assert2(0, "Unknown cachedev event type");
     break;
   }
#endif
}
예제 #4
0
static void simpledisk_interrupt_complete (ioreq_event *curr)
{
#ifdef DEBUG_SIMPLEDISK
   fprintf (outputfile, "*** %f: simpledisk_interrupt_complete - devno %d, blkno %d, bcount %d, flags 0x%x, cause %d\n", simtime, curr->devno, curr->blkno, curr->bcount, curr->flags, curr->cause );
#endif

   switch (curr->cause) {

      case RECONNECT:
         simpledisk_reconnect_done(curr);
	 break;

      case DISCONNECT:
	 simpledisk_disconnect_done(curr);
	 break;

      case COMPLETION:
	 simpledisk_completion_done(curr);
	 break;

      default:
         ddbg_assert2(0, "bad event type");
         break;
   }
}
예제 #5
0
// assuming no activity, what will the state of the disk be
// at some time in the future
static void 
dm_progress_g1(struct dm_disk_if *d, 
	       struct dm_pbn *cur_state,
	       dm_time_t time,
	       struct dm_pbn *result_state)
{
  ddbg_assert2(0, "unimplemented");
}
예제 #6
0
// who calls this?
// in pre3-28, this seems unreachable (not sure) (bucy 2/02)
void 
dm_mech_g1_seek_init(struct dm_disk_if *d) {
  double tmpfull, tmpavg, tmptime;
  struct dm_mech_g1 *m = (struct dm_mech_g1 *)d->mech;
  // XXX get rid of this
  FILE *outputfile = stderr;

  ddbg_assert2(0, "This is deprecated and/or hasn't been ported.\n");



  if ((m->seektype == SEEK_3PT_CURVE) && 
      (m->seekavg > m->seekone)) 
    {
      fprintf (outputfile, "seekone %" PRIu64 ", seekavg %" PRIu64 ", seekfull %" PRIu64 "\n", 
	       m->seekone, m->seekavg, m->seekfull);

      tmpfull = m->seekfull;
      tmpavg = m->seekavg;
      tmptime = (double) -10.0 * m->seekone;
      tmptime += (double) 15.0 * m->seekavg;
      tmptime += (double) -5.0 * m->seekfull;
      //      tmptime = tmptime / 
      //	(3.0 * sqrt((double) (d->dm_cyls)));

      m->seekavg *= (double) -15.0;
      m->seekavg += (double) 7.0 * m->seekone;
      m->seekavg += (double) 8.0 * m->seekfull;
      m->seekavg = m->seekavg / 
	(double) (3 * d->dm_cyls);

      m->seekfull = tmptime;

      //      fprintf (outputfile, "seekone %f, seekavg %f, seekfull %f\n", 
      //	       m->seekone, m->seekavg, m->seekfull);

      //      fprintf (outputfile, "seekone %f, seekavg %f, seekfull %f\n", 
      //       diskseektime(m, 1, 0, 1), 
      //       diskseektime(m, (d->dm_cyls / 3), 0, 1), 
      //       diskseektime(m, (d->dm_cyls - 1), 0, 1));

      if ((m->seekavg < 0.0) || (m->seekfull < 0.0)) {
	m->seektype = SEEK_3PT_CURVE;
	m->seekfull = tmpfull;
	m->seekavg = tmpavg;
      }
    }
}
예제 #7
0
파일: ssd.c 프로젝트: ESOS-Lab/EnergySim
static void ssd_interrupt_complete (ioreq_event *curr)
{
   switch (curr->cause) {

      case RECONNECT:
         ssd_reconnect_done(curr);
		 break;

      case DISCONNECT:
		 ssd_disconnect_done(curr);
		 break;

      case COMPLETION:
		 ssd_completion_done(curr);
		 break;

      default:
         ddbg_assert2(0, "bad event type");
   }
}
예제 #8
0
static void simpledisk_interrupt_complete (ioreq_event *curr)
{
   // fprintf (outputfile, "Entered simpledisk_interrupt_complete - cause %d\n", curr->cause);

   switch (curr->cause) {

      case RECONNECT:
         simpledisk_reconnect_done(curr);
	 break;

      case DISCONNECT:
	 simpledisk_disconnect_done(curr);
	 break;

      case COMPLETION:
	 simpledisk_completion_done(curr);
	 break;

      default:
         ddbg_assert2(0, "bad event type");
   }
}
예제 #9
0
int disksim_loadparams(char *inputfile, int synthgen) {
  int rv;
  int c;
  struct lp_tlt **tlts;
  int tlts_len;

  // register modules with libparam
  for(c = 0; c <= DISKSIM_MAX_MODULE; c++) {
    lp_register_module(disksim_mods[c]);
  }

  // diskmodel modules
  for(c = 0; c <= DM_MAX_MODULE; c++) {
    lp_register_module(dm_mods[c]);
  }

  // memsmodel modules
  for(c = 0; c <= MEMSMODEL_MAX_MODULE; c++) {
    lp_register_module(memsmodel_mods[c]);
  }  

  lp_register_topoloader(disksim_topoloader);

  //  lp_init_typetbl();


  disksim->parfile = fopen(inputfile,"r");
  ddbg_assert2(disksim->parfile != NULL, 
	     ("Parameter file \"%s\" cannot be opened for read access\n", 
	      inputfile));

  lp_init_typetbl();

  rv = lp_loadfile(disksim->parfile, 
		   &tlts, 
		   &tlts_len, 
		   inputfile,
		   disksim->overrides,
		   disksim->overrides_len);

  lp_unparse_tlts(tlts, tlts_len, outputfile, inputfile);

  lp_instantiate("Global", "Global");
  lp_instantiate("Stats", "Stats");

  // instantiate any logorgs, syncsets we find
  for(c = 0; c < lp_typetbl_len; c++) {
    if(lp_typetbl[c] != 0 && (lp_typetbl[c]->spec != 0)) {
      if(!strcmp(lp_lookup_base_type(lp_typetbl[c]->sub, 0), "disksim_logorg")) {
	iodriver_load_logorg(lp_typetbl[c]->spec);
      }

      else if(!strcmp(lp_lookup_base_type(lp_typetbl[c]->sub, 0), "disksim_syncset")) {
	disk_load_syncsets(lp_typetbl[c]->spec);
      }
    }
  }

  // do this *after* logorgs get instantiated!
  if(synthgen) {
    lp_instantiate("Proc", "Proc");
    lp_instantiate("Synthio", "Synthio");
  }


  fclose(disksim->parfile);
  return rv;
}
예제 #10
0
static void disksim_topoloader(struct lp_topospec *ts, int len) {
  int rv = load_iodriver_topo(ts, len);
  ddbg_assert2(rv != 0, "Topospec load failed!");
}
예제 #11
0
static int layout_g2_loadmap(struct dm_layout_g2 *l)
{
    FILE *fd;
    char junk[1024];
    char countstr[16];
    char *mapfile;

    int extentguess;
    int extents_ct = 0;

    struct dm_pbn pbn;
    int64_t lbn;
    int c,h,s,count;
    int lastc, lasth;
    int cyls, heads;
    int i, j;
    // index [cyl][head], number of extents for that track
    int **track_ext_counts;

    struct dm_layout_g2_node *curr;
    struct dm_layout_g2_node *track_extents;

    struct dm_pbn *currdefect;

    mapfile = lp_search_path(lp_cwd, l->mapfile);

    fd = fopen(mapfile, "r");
    ddbg_assert3(fd != 0, ("failed to open layout mappings file %s", l->mapfile));

    // ignore first 2 lines
    fgets(junk, sizeof(junk), fd);
    fgets(junk, sizeof(junk), fd);

    if(fscanf(fd, "%d cylinders, %*d rot, %d heads\n", &cyls, &heads) != 2) {
        ddbg_assert2(0, "*** error: layout_g2_loadmap: need <cyls> ... <heads>\n");
    }

    //  printf("*** layout_g2: %s %s\n", vendor, model);
    //  printf("*** layout_g2: %d %d\n", cyls, heads);

    extentguess = cyls * heads * 2; // 0t tracks
    extentguess += extentguess/4;         // if there are a lot of defects
    l->ltop_map = calloc(extentguess, sizeof(struct dm_layout_g2_node));
    curr = &l->ltop_map[0];

    l->ptol_map = calloc(cyls, sizeof(struct dm_layout_g2_cyl));

    for(i = 0; i < cyls; i++) {
        l->ptol_map[i].surfaces = calloc(heads, sizeof(struct dm_layout_g2_surf));
    }

    track_ext_counts = calloc(cyls, sizeof(int *));
    for(i = 0; i < cyls; i++) {
        track_ext_counts[i] = calloc(heads, sizeof(int));
    }

    curr = &l->ltop_map[0];
    // ltop map
    while(fscanf(fd, "lbn %d --> cyl %d, head %d, sect %d, %s %d\n",
                 &curr->lbn,
                 &curr->loc.cyl,
                 &curr->loc.head,
                 &curr->loc.sector,
                 countstr,
                 &curr->len) == 6)
    {
        if(!strcmp(countstr, "seqcnt")) {
            curr->len++;
        }

        track_ext_counts[curr->loc.cyl][curr->loc.head]++;
        curr++;
        extents_ct++;
        l->ltop_map_len++;
    }

    // copy the ltop map and sort it by track
    track_extents = calloc(extents_ct, sizeof(struct dm_layout_g2_node));
    memcpy(track_extents, l->ltop_map, extents_ct * sizeof(struct dm_layout_g2_node));

    qsort(track_extents, extents_ct, sizeof(struct dm_layout_g2_node),
          trackcmp);

    // ptol map
    curr = &track_extents[0];
    for(i = 0; i < cyls; i++) {
        for(j = 0; j < heads; j++) {
            int k;
            int extents_len = track_ext_counts[i][j];

            l->ptol_map[i].surfaces[j].extents = calloc(extents_len, sizeof(struct dm_layout_g2_node));
            l->ptol_map[i].surfaces[j].extents_len = extents_len;

            for(k = 0; k < extents_len; k++) {
                l->ptol_map[i].surfaces[j].extents[k] = *curr;
                curr++;
            }
        }
    }


    // free the extra extent list
    free(track_extents);

    //  ddbg_assert2(extents_ct > (cyls * heads), "EOF on layout mappings file??");

    //  l->extents_len = extents_ct;

    // populate the defect list
    defects = calloc(extents_ct >> 3, sizeof(struct dm_pbn));
    currdefect = &defects[0];
    while(fscanf(fd, "Defect at cyl %d, head %d, sect %d\n",
                 &currdefect->cyl,
                 &currdefect->head,
                 &currdefect->sector) == 3)
    {
        currdefect++;
        defects_len++;
    }




    fclose(fd);
    return 0;
}
예제 #12
0
struct dm_layout_if *
dm_layout_g1_loadparams(struct lp_block *b, struct dm_disk_if *d)
{
  struct dm_layout_g1 *result = malloc(sizeof(*result));
  memset(result, 0, sizeof(*result));

  //#include "modules/dm_layout_g1_param.c"
  
  lp_loadparams(result, b, &dm_layout_g1_mod);

  result->disk = d;
  result->disk->layout = (struct dm_layout_if *)result;
  
  
  
  /*    result->hdr = g1_layout_nosparing; */
  /*    result->hdr = g1_layout_sectpertrackspare; */
  /*    result->hdr = g1_layout_sectperzonespare; */
  /*    result->hdr = g1_layout_sectpercylspare; */
  /*    result->hdr = g1_layout_sectperrangespare; */
  
  switch(result->mapping) {
  case LAYOUT_NORMAL:
  case LAYOUT_CYLSWITCHONSURF1:
  case LAYOUT_CYLSWITCHONSURF2:
    if(result->sparescheme == NO_SPARING) {
      result->hdr = g1_layout_nosparing; 
    } else {
      if (result->sparescheme == TRACK_SPARING) {
	result->hdr = g1_layout_tracksparing;
      }
      else if (result->sparescheme == SECTPERTRACK_SPARING) {
	  
	result->hdr = g1_layout_sectpertrackspare; 
      }
	
      else if ((issectpercyl(result)) ||
	       (result->sparescheme == SECTATEND_SPARING))
	{
	  result->hdr = g1_layout_sectpercylspare;
	}
      else if ((result->sparescheme == SECTSPERZONE_SPARING) ||
	       (result->sparescheme == SECTSPERZONE_SPARING_SLIPTOEND))
	{
	  result->hdr = g1_layout_sectperzonespare; 
	}
      else if (result->sparescheme == SECTPERRANGE_SPARING) {
	result->hdr = g1_layout_sectperrangespare;
      }
      else {
	ddbg_assert2(0, "Unknown sparing scheme");
      }
    }
    break;
  default:
    ddbg_assert2(0, "Unknown lbn<->pbn scheme");
  }


  // careful with the order here...
  initialize_bands(result->disk);
  dm_layout_g1_initialize(d);
  checknumblocks(result);
  setup_band_blknos(result);

  return (struct dm_layout_if *)result;
}
예제 #13
0
static void *
cachedev_disk_access_complete (struct cache_if *c,
			       ioreq_event *curr)
{
  struct cache_dev *cache = (struct cache_dev *)c;
   struct cache_dev_event *rwdesc = (struct cache_dev_event *)curr->buf;
   struct cache_dev_event *tmp = NULL;

#ifdef DEBUG_CACHEDEV
   fprintf (outputfile, "*** %f: Entered cachedev::cache_disk_access_complete: cacheDevEventType %d, buf %p, type %d, devno %d, blkno %d, bcount %d, flags 0x%x\n", simtime, rwdesc->type, curr->buf, curr->type, curr->devno, curr->blkno, curr->bcount, curr->flags);
#endif

   switch(rwdesc->type) {
   case CACHE_EVENT_READ:
      /* Consider writing same buffer to cache_devno, in order to populate it.*/
      /* Not clear whether it is more appropriate to do it from here or from  */
      /* "free_block_clean" -- do it here for now to get more overlap.        */
      if (curr->devno == cache->real_devno) {
         ioreq_event *flushreq = ioreq_copy(rwdesc->req);
         flushreq->type = IO_ACCESS_ARRIVE;
         flushreq->buf = rwdesc;
         flushreq->flags = WRITE;
         flushreq->devno = cache->cache_devno;
         rwdesc->type = CACHE_EVENT_POPULATE_ALSO;

#ifdef DEBUG_CACHEDEV
   fprintf (outputfile, "*** %f: Entered cachedev::cache_disk_access_complete - flushing memory cache to disk: type %d, devno %d, blkno %d, bcount %d, flags 0x%x, buf %p\n", simtime, flushreq->type, flushreq->devno, flushreq->blkno, flushreq->bcount, flushreq->flags, flushreq->buf);
#endif
         (*cache->issuefunc)(cache->issueparam, flushreq);
         cache->stat.popwrites++;
         cache->stat.popwriteblocks += rwdesc->req->bcount;
      }

      /* Ongoing read request can now proceed, so call donefunc from get_block*/
      (*rwdesc->donefunc)(rwdesc->doneparam,rwdesc->req);

      break;
   case CACHE_EVENT_WRITE:

      /* finished writing to cache-device */
      if (curr->devno == cache->cache_devno) {
         cachedev_setbits (cache->validmap, curr);
         cachedev_setbits (cache->dirtymap, curr);
         if (cache->writescheme == CACHE_WRITE_THRU) {
            ioreq_event *flushreq = ioreq_copy(rwdesc->req);
            flushreq->type = IO_ACCESS_ARRIVE;
            flushreq->buf = rwdesc;
            flushreq->flags = WRITE;
            flushreq->devno = cache->real_devno;
            rwdesc->type = CACHE_EVENT_FLUSH;
            (*cache->issuefunc)(cache->issueparam, flushreq);
            cache->stat.destagewrites++;
            cache->stat.destagewriteblocks += rwdesc->req->bcount;
         }
      }
      (*rwdesc->donefunc)(rwdesc->doneparam,rwdesc->req);

      if (rwdesc->type != CACHE_EVENT_FLUSH) {
         cachedev_remove_ongoing_request (cache, rwdesc);
         addtoextraq ((event *) rwdesc);
         cache->bufferspace -= curr->bcount;
      }

      break;

   case CACHE_EVENT_POPULATE_ONLY:
     cachedev_setbits (cache->validmap, curr);
     cachedev_remove_ongoing_request (cache, rwdesc);
      addtoextraq ((event *) rwdesc);
      cache->bufferspace -= curr->bcount;
      break;
      
   case CACHE_EVENT_POPULATE_ALSO:
     cachedev_setbits (cache->validmap, curr);
     rwdesc->type = CACHE_EVENT_READ;
     break;

   case CACHE_EVENT_FLUSH:
      cachedev_clearbits (cache->dirtymap, curr);
      cachedev_remove_ongoing_request (cache, rwdesc);
      addtoextraq ((event *) rwdesc);
      cache->bufferspace -= curr->bcount;
      break;

   case CACHE_EVENT_IDLEFLUSH_READ:
     {
       ioreq_event *flushreq = ioreq_copy (curr);
       flushreq->type = IO_ACCESS_ARRIVE;
       flushreq->flags = WRITE;
       flushreq->devno = cache->real_devno;
       rwdesc->type = CACHE_EVENT_IDLEFLUSH_FLUSH;
       (*cache->issuefunc)(cache->issueparam, flushreq);
       cache->stat.destagewrites++;
       cache->stat.destagewriteblocks += curr->bcount;
     } break;

   case CACHE_EVENT_IDLEFLUSH_FLUSH:
     cachedev_clearbits (cache->dirtymap, curr);
     cachedev_remove_ongoing_request (cache, rwdesc);
     addtoextraq ((event *) rwdesc);
     cachedev_idlework_callback (cache, curr->devno);
     cache->bufferspace -= curr->bcount;
     break;

   default:
     ddbg_assert2(0, "Unknown cachedev event type");
     break;
   }

   addtoextraq((event *) curr);

   /* returned cacheevent will get forwarded to cachedev_wakeup_continue... */
   return(tmp);
}
예제 #14
0
/* dummy */
void disksim_device_loadparams(void) {
  ddbg_assert2(0, "this is a dummy that isn't supposed to be called");
}
예제 #15
0
int disksim_iomap_loadparams(struct lp_block *b) { 
  ddbg_assert2(0, "this is a dummy and isn't supposed to be called");
  return 0;
}
예제 #16
0
void 
dm_mech_g1_read_extracted_seek_curve (char *filename, 
				      int *cntptr,
				      int **distsptr, 
				      dm_time_t **timesptr)
{
   int rv, mat;
   int lineflag = 1;
   int count = 0, buflen = 128;
   int *dists;
   dm_time_t *times;
   FILE *seekfile = NULL;
   char linebuf[1024];

   char *pathname = lp_search_path(lp_cwd, filename);

   if(pathname) {
     seekfile = fopen(pathname, "r");
   }
   else {
     ddbg_assert2(0, "Seek file not found in path!");
   }

   ddbg_assert3(seekfile != 0, ("fopen seekfile (%s) failed: %s", 
				filename,
				strerror(errno)));


   rv = (fgets(linebuf, sizeof(linebuf), seekfile) != 0);

   mat = sscanf(linebuf, "Seek distances measured: %d\n", &count);
   if(mat == 1) {
     buflen = count;
     lineflag = 0;
   }

   dists = calloc(buflen, sizeof(*dists));
   times = calloc(buflen, sizeof(*times));


   do {
     double time, stdev;
     int dist;
   
     if(!lineflag) {
       rv = (fgets(linebuf, sizeof(linebuf), seekfile) != 0);
     }
     else {
       lineflag = 0;       
     }
     if(rv) {
       mat = sscanf(linebuf, "%d, %lf, %lf\n", &dist, &time, &stdev);
       
       if(mat == 2 || mat == 3) {
	 if(count >= buflen-1) {
	   buflen *= 2;
	   dists = realloc(dists, buflen * sizeof(*dists));
	   times = realloc(times, buflen * sizeof(*times));
	 }
       
	 dists[count] = dist;
	 times[count] = dm_time_dtoi(time);
	 count++;
       }
       else {
	 fprintf(stderr, "*** bogus line in seek curve (%s:%d): %s\n", 
		 __FILE__, __LINE__, linebuf);
       }
     }
   } while(rv);

   fclose(seekfile);
   *cntptr = count;
   *distsptr = dists;
   *timesptr = times;
}