⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 disksim_diskctlr.c

📁 目前最精确的磁盘模拟器的第3版
💻 C
📖 第 1 页 / 共 5 页
字号:
          // acctime = diskacctime(currdisk,     //		  curr->tempptr1,     //		  DISKACCTIME,    //		  (curr->flags & READ),     //		  simtime,     //		  global_currcylno,    //		  global_currsurface,     //		  curr->cause,     //		  1,     //		  0);          nsecs = currdisk->model->mech->dm_acctime(currdisk->model,					      &currdisk->mech_state,					      &pbn,					      1,   // len					      (curr->flags & READ),					      0,   // immed					      &currdisk->mech_state,					      0); // breakdown    acctime = dm_time_itod(nsecs);  }				        curr->time = simtime + acctime;  if(currdisk->stat.latency == (double) -1.0) {    currdisk->stat.latency = (double) 0.0;    currdisk->stat.xfertime = acctime - currdisk->stat.seektime;  }   else {    currdisk->stat.xfertime += acctime;  }  if(((currdiskreq != seg->recyclereq)       && disk_buffer_block_available(currdisk, seg, curr->blkno))      || ((curr->flags & READ) && (!currdisk->read_direct_to_buffer)))     {      curr->type = DEVICE_GOT_REMAPPED_SECTOR;    }   else {    // get s/t for curr->blkno    int st = currdisk->model->layout->dm_get_sectors_lbn(currdisk->model,							 curr->blkno);    double rottime = currdisk->model->mech->dm_period(currdisk->model);    // what is this? (appears again in disk_goto_remapped_sector)    curr->time -= ((double) 1 / ((double)st * rottime));    curr->type = DEVICE_GOTO_REMAPPED_SECTOR;  }} // disk_get_remapped_sector()static void disk_goto_remapped_sector (disk *currdisk, ioreq_event *curr){  double rotatetime =     dm_time_itod(currdisk->model->mech->dm_period(currdisk->model));  diskreq *currdiskreq = currdisk->effectivehda;  segment *seg;  ddbg_assert2(currdiskreq != 0, "No effectivehda");  seg = currdiskreq->seg;  if(seg->outstate == BUFFER_PREEMPT) {    disk_release_hda(currdisk, currdiskreq);    return;  }  if((currdiskreq != seg->recyclereq)      && disk_buffer_block_available(currdisk, seg, curr->blkno))     {      // XXX is curr->blkno the track we want??      int st = currdisk->model->layout->dm_get_sectors_lbn(currdisk->model,							   curr->blkno);      double rottime = currdisk->model->mech->dm_period(currdisk->model);      // what is this?      curr->time += ((double) 1 / ((double)st * rottime));      curr->type = DEVICE_GOT_REMAPPED_SECTOR;    }   else {    seg->time += rotatetime;    currdisk->stat.xfertime += rotatetime;    curr->time += rotatetime;    curr->type = DEVICE_GOTO_REMAPPED_SECTOR;  }  addtointq((event *) curr);} // disk_goto_remapped_sector()static int disk_initiate_seek (disk *currdisk, 			       segment *seg, 			       ioreq_event *curr, 			       int firstseek, 			       double delay, 			       double mintime){  struct dm_pbn destpbn;  double seektime;  int seekdist;  int remapsector = 0;  if(disk_printhack && (simtime >= disk_printhacktime)) {    fprintf (outputfile, "%12.6f            Entering disk_initiate_seek to %d for disk %d\n", simtime, curr->blkno, curr->devno);    fflush(outputfile);  }  curr->type = NULL_EVENT;  seg->time = simtime + delay;  //  remapsector = FALSE;  // new ltop  {    uint64_t nsecs;    struct dm_mech_state end;    struct dm_mech_state begin = currdisk->mech_state;        currdisk->model->layout->dm_translate_ltop(currdisk->model, 					       curr->blkno, 					       MAP_FULL,					       &destpbn,					       &remapsector);    seekdist = abs(currdisk->mech_state.cyl - destpbn.cyl);    end.cyl = destpbn.cyl;    end.head = destpbn.head;    end.theta = 0;    curr->cause = destpbn.sector;        // new acctime     //  seektime = diskacctime(currdisk, curr->tempptr1, DISKSEEKTIME,    //		 (curr->flags & READ), seg->time, global_currcylno,    //		 global_currsurface, curr->cause, curr->bcount, 0);    nsecs = currdisk->model->mech->dm_seek_time(currdisk->model,					       &begin,					       &end,					       (curr->flags & READ));    seektime = dm_time_itod(nsecs);  }  if(seektime < mintime) {    seg->time += mintime - seektime;  }  curr->time = seg->time + seektime;  if((curr->flags & BUFFER_BACKGROUND)      && (curr->flags & READ))     {      if((currdisk->contread == BUFFER_READ_UNTIL_CYL_END) 	 && (seekdist != 0))       {	return FALSE;      }            if((currdisk->contread == BUFFER_READ_UNTIL_TRACK_END) 	 && ((seekdist != 0) | 	     (currdisk->mech_state.head != destpbn.head)))       {	return FALSE;      }    }  if(firstseek) {    currdisk->stat.seekdistance = seekdist;    currdisk->stat.seektime = seektime;    currdisk->stat.latency = (double) -1.0;    currdisk->stat.xfertime = (double) -1.0;  }   else if(remapsector == 0) {    currdisk->stat.xfertime += seektime;  }  curr->type = DEVICE_BUFFER_SEEKDONE;  if(remapsector != 0) {    disk_get_remapped_sector(currdisk, curr);  }  addtointq((event *) curr);  /*    fprintf (outputfile, "\nSeek from cyl %d head %d to cyl %d head %d, time %f\n", currdisk->currcylno, currdisk->currsurface, currcylno, currsurface, seektime);  */  return TRUE;} // disk_initiate_seek()/* Attempt to start hda activity.   * 1.  If effectivehda already set, do nothing. * 2.  If currdiskreq is NULL, attempt to find the appropriate next * request from the queue.   */static voiddisk_get_effectivehda(disk *currdisk,		      diskreq *currdiskreq){  diskreq     *nextdiskreq = currdiskreq;  ioreq_event *nextioreq;  // if we have a currenthda, make that the effectivehda  if(currdisk->currenthda) {    if(currdiskreq && (currdiskreq != currdisk->currenthda)) {      fprintf(stderr, "currdiskreq != currenthda in disk_check_hda\n");      assert(0);    }    currdisk->effectivehda = currdisk->currenthda;  }   // ok.  So no currenthda.  Let's find a "next" io request (we'll  // call it nextdiskreq) and make that the current/effective hda.  else {     if(nextdiskreq && nextdiskreq->ioreqlist) {      nextioreq = ioreq_copy(nextdiskreq->ioreqlist);      nextioreq->ioreq_hold_diskreq = nextdiskreq;      nextioreq->ioreq_hold_disk = currdisk;      if(!disk_enablement_function(nextioreq)) {	nextdiskreq = NULL;      }      addtoextraq((event *)nextioreq);    }    // we don't have a nextdiskreq yet.  check the disk's ioqueue for    // one.    if(!nextdiskreq) {      nextioreq = ioqueue_show_next_request(currdisk->queue);      if(nextioreq) {	nextdiskreq = (diskreq*) nextioreq->ioreq_hold_diskreq;      }    }    // if we don't have a nextdiskreq by now, we're going to fall out    // of this without having figured out an effectivehda and bail    // below    if(nextdiskreq) {      if(nextdiskreq->flags & HDA_OWNED) {	fprintf(stderr, "disk_check_hda:"		"  diskreq was already HDA_OWNED\n");	assert(0);      }      // does this request have a disk cache segment associated with      // it?      if(nextdiskreq->seg && 	  !(nextdiskreq->flags & SEG_OWNED) &&	  (nextdiskreq->seg->recyclereq != nextdiskreq)) 	{	  disk_buffer_attempt_seg_ownership(currdisk, nextdiskreq);	}	       if(!nextdiskreq->seg) {	// hmmm ... no cache segment ... let's try to find one	disk_buffer_select_segment(currdisk,nextdiskreq,FALSE);	if(nextdiskreq->seg) {	  disk_buffer_set_segment(currdisk, nextdiskreq);	  disk_buffer_attempt_seg_ownership(currdisk, nextdiskreq);	} 	else { 	  // still no cache segment.  try to "recycle" one.	  nextdiskreq->seg = 	    disk_buffer_recyclable_segment(currdisk,					   (nextdiskreq->ioreqlist->flags & READ));	  if(nextdiskreq->seg) {	    nextdiskreq->seg->recyclereq = nextdiskreq;	  }	} // else { // nextdiskreq->seg == 0      } // if(!nextdiskreq->seg)	       // so if we succeeded in finding a cache segment above,       // do something with the ioreqs on the nextdiskreq->ioreqlist.      if(nextdiskreq->seg) {	nextioreq = nextdiskreq->ioreqlist;	while(nextioreq) { 	  if(!ioqueue_get_specific_request(currdisk->queue,					   nextioreq)) 	    {	      fprintf(stderr, "disk_get_effectivehda()"		      "  ioreq_event not found by"		      " ioqueue_get_specific_request call\n");	      assert(0);	    }	   	  nextioreq = nextioreq->next;	}      } // if(nextdiskreq->seg)      // what if we didn't find a segment?      currdisk->currenthda = currdisk->effectivehda = nextdiskreq;      nextdiskreq->flags |= HDA_OWNED;         } // if(nextdiskreq)  } // else { // currdisk->currenthda == 0  if(disk_printhack && (simtime >= disk_printhacktime)) {    fprintf (outputfile, "                        "	     "effectivehda = %8p\n", currdisk->effectivehda);    fflush(outputfile);  }} // disk_get_effectivehda()// handle the case for disk_check_hda when requests are pending// (i.e. not pure prefetch)static void disk_check_hda_pending(disk *currdisk, 		       ioreq_event *nextioreq, 		       diskreq *nextdiskreq, 		       segment *seg, 		       int ok_to_check_bus,		       double *mintime,		       int *immediate_release,		       int *initiate_seek) {  nextioreq = nextdiskreq->ioreqlist;  while (nextioreq->next) {    nextioreq = nextioreq->next;  }  seg->access->flags = nextioreq->flags;    // is the request a READ?  if(nextioreq->flags & READ) {    if(seg->access->type != NULL_EVENT) {      /*       *	if((seg->access->blkno != seg->endblkno) &&       *	(seg->access->blkno != (seg->endblkno + 1)) &&       *	(seg->access->blkno !=       *	currdisk->firstblkontrack)) { fprintf(stderr,       *	"non-NULL seg->access->type with incorrect       *	seg->access->blkno found for read segment in       *	disk_check_hda\n"); exit(1); }        */    }     else {      // here's our bug ... we have some bogus seg that ends on      // the 1-past-the-end-of-the-disk block and we try      // to access it here      seg->access->blkno = seg->endblkno;    }    if(!seg->recyclereq) {      seg->minreadaheadblkno = 	max(seg->minreadaheadblkno, 	    min((nextioreq->blkno + 		 nextioreq->bcount + 		 currdisk->minreadahead), 		currdisk->model->dm_sectors));      seg->maxreadaheadblkno = 	max(seg->maxreadaheadblkno, 	    min(disk_buffer_get_max_readahead(currdisk,seg,nextioreq),		currdisk->model->dm_sectors));    }    currdisk->immed = currdisk->immedread;    seg->state = BUFFER_READING;    if(seg->recyclereq) {      seg->access->blkno = nextdiskreq->outblkno;      *initiate_seek = TRUE;    }     else if((seg->endblkno < (nextioreq->blkno + 			      nextioreq->bcount)) ||	    (seg->startblkno > nextdiskreq->outblkno))     {      *initiate_seek = TRUE;    }     else if(seg->endblkno < 	    max(seg->maxreadaheadblkno, 		disk_buffer_get_max_readahead(currdisk, 					      seg, 					      nextioreq)))     {      seg->access->flags |= BUFFER_BACKGROUND;      if(currdisk->readaheadifidle) {	/* Check for type != NULL_EVENT below negates this */	*initiate_seek = TRUE;      }    } // else if(seg->endblkno < ...    else {      *immediate_release = TRUE;    }	       if(seg->access->type != NULL_EVENT) {      if(*immediate_release) {	fprintf(stderr,"CHECK:  immediate_release reset!\n");	fflush(stderr);      }      *initiate_seek = FALSE;      *immediate_release = FALSE;    } // if(seg->access->type != NULL_EVENT)  } // deal with a READ req  // ... or is the request a WRITE?  else {     if(seg->access->type != NULL_EVENT) {      fprintf(stderr, "non-NULL seg->access->type found"	      " for write segment in disk_check_hda\n");      assert(0);    }    /* prepare minimum seek time for seek if not sequential writes */    if((nextdiskreq->hittype != BUFFER_APPEND) ||       (seg->access->flags & READ) ||       (seg->access->blkno != nextdiskreq->ioreqlist->blkno) ||       (seg->access->bcount != 1) ||       (seg->access->time != simtime)) {      *mintime = currdisk->minimum_seek_delay;    }     /*     * else { fprintf(stderr,"Sequential write stream detected     * at %f\n", simtime); }      */	       seg->access->blkno = nextdiskreq->inblkno;    if(nextdiskreq->flags & COMPLETION_RECEIVED) {      seg->access->flags |= BUFFER_BACKGROUND;    }    currdisk->immed = currdisk->immedwrite;    if((seg->state != BUFFER_WRITING)       && (seg->state != BUFFER_DIRTY))      {	currdisk->numdirty++;		if((disk_printhack > 1) 	   && (simtime >= disk_printhacktime)) 	  {	    fprintf (outputfile, "                        "		     "numdirty++ = %d\n",currdisk->numdirty);	    fflush(outputfile);	  }		assert(currdisk->numdirty >= 0);	assert(currdisk->numdirty <= currdisk->numwritesegs);	

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -