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

📄 disksim_diskctlr.c

📁 目前最精确的磁盘模拟器的第3版
💻 C
📖 第 1 页 / 共 5 页
字号:
	      busioreq->type = IO_INTERRUPT_ARRIVE;	      busioreq->cause = RECONNECT;	    }	    busioreq->bcount = min(seg->endblkno,(tmpioreq->blkno + tmpioreq->bcount)) - currdiskreq->outblkno;	  }      }       else {			/* WRITE */	seg_owner = disk_buffer_seg_owner(seg,FALSE);	if(!seg_owner) {	  seg_owner = currdiskreq;	}	if((currdiskreq->inblkno >= (tmpioreq->blkno + tmpioreq->bcount)) 	   || ((currdiskreq->outblkno == currdiskreq->ioreqlist->blkno) 	       && (currdiskreq->hittype != BUFFER_APPEND)) 	   || ((seg->endblkno == currdiskreq->outblkno) 	       && (seg->endblkno < (tmpioreq->blkno + tmpioreq->bcount)) 	       && ((seg->endblkno - seg_owner->inblkno) < seg->size) 	       && (!check_watermark 		   || ((seg->endblkno - currdiskreq->inblkno) <= 		       currdiskreq->watermark)))) 	  {	    if(currdisk->outwait) {	      busioreq = currdisk->outwait;	      currdisk->outwait = NULL;	      busioreq->time = simtime;	    } 	    else {	      busioreq = ioreq_copy(tmpioreq);	      busioreq->time = simtime;	      busioreq->type = IO_INTERRUPT_ARRIVE;	      busioreq->cause = RECONNECT;	    }	    if((currdiskreq->outblkno == currdiskreq->ioreqlist->blkno) 	       && (currdiskreq->hittype != BUFFER_APPEND)) 	      {		busioreq->bcount = min(tmpioreq->bcount,seg->size);	      } 	    else {	      int i1 = tmpioreq->blkno + tmpioreq->bcount - 		currdiskreq->outblkno;	      int i2 = seg->size - seg->endblkno + seg_owner->inblkno;	      busioreq->bcount = min(i1, i2);	    }	  }      }    }    return busioreq;}/* * Queue priority list: * 10  HDA_OWNED, !currenthda & !effectivehda (completions and full read hits) *  9		  effectivehda *  8		  currenthda *  7  Appending limited fastwrite (LIMITED_FASTWRITE and BUFFER_APPEND) *  6  Full sneakyintermediateread with seg *  5  Partial sneakyintermediateread with seg *  4  Full sneakyintermediateread currently without seg *  3  Partial sneakyintermediateread currently without seg *  2  Write prebuffer to effectivehda->seg *  1  Write prebuffer to currenthda->seg *  0  Write prebuffer with other seg *  -1 Write prebuffer currently without seg * * Not usable: *    requests which don't need bus service *    requests using recycled segs *    requests with no available segs * * If a sneakyintermediateread is detected which has a seg, was marked as  * a read hit, has not transferred any data yet, and is no longer a hit,  * remove the diskreq from the segment. * * Possible improvements: *   un-set segment if read hit is no longer a hit and no data has been *   transferred yet. * *   reverse queue order (oldest first) so that we don't have to peruse *   the entire queue if a 10 is found */static diskreq * disk_select_bus_request(disk *currdisk, ioreq_event **busioreq){  diskreq *currdiskreq = currdisk->pendxfer;  diskreq *bestdiskreq = NULL;  ioreq_event *currioreq = 0;  ioreq_event *tmpioreq;  int curr_value;  int best_value = -99;  int curr_set_segment;  int best_set_segment = FALSE;  if(disk_printhack && (simtime >= disk_printhacktime)) {    fprintf (outputfile, "%12.6f         Entering disk_select_bus_request for disk %d\n", simtime, currdisk->devno);    fflush(outputfile);  }  while (currdiskreq) {    curr_value = -100;    curr_set_segment = FALSE;    ddbg_assert2(currdiskreq->ioreqlist != 0, 	       "diskreq with NULL ioreqlist found in bus queue");    if(currdiskreq->seg        && (currdiskreq->seg->recyclereq == currdiskreq))       {	// dont do anything      }     else if(currdiskreq->flags & HDA_OWNED) {      currioreq = disk_request_needs_bus(currdisk,currdiskreq,TRUE);      if(currioreq) {	if(currdiskreq == currdisk->effectivehda) {	  curr_value = 9;	} 	else if(currdiskreq == currdisk->currenthda) {	  curr_value = 8;	} 	else {	  curr_value = 10;	}      }    }     else if((best_value <= 7) 	    && (currdisk->fastwrites == LIMITED_FASTWRITE) 	    && (currdiskreq->hittype == BUFFER_APPEND))       {	currioreq = disk_request_needs_bus(currdisk,currdiskreq,TRUE);	if(currioreq) {	  curr_value = 7;	}      }     else if((best_value <= 6) 	    && (currdisk->sneakyintermediatereadhits) 	    && (currdiskreq->ioreqlist->flags & READ))       {	if(currdiskreq->seg) {	  currioreq = disk_request_needs_bus(currdisk,currdiskreq,TRUE);	  if(currioreq) {	    tmpioreq = currdiskreq->ioreqlist;	    while (tmpioreq->next) {	      tmpioreq = tmpioreq->next;	    }	    curr_value = ((currdiskreq->seg->endblkno >= (tmpioreq->blkno + tmpioreq->bcount)) ? 6 : 5);	  } 	  else if(currdiskreq->outblkno == currdiskreq->ioreqlist->blkno) {	    /* Not entirely sure this works or is appropriate */	    currioreq = disk_request_needs_bus(currdisk,currdiskreq,FALSE);	    if(currioreq) {	      addtoextraq((event *)currioreq);	    } 	    else {	      if(disk_printhack && (simtime >= disk_printhacktime)) {		fprintf (outputfile, "%12.6f         "			 "sneakyintermediatereadhits removed diskreq "			 "from seg\n",			 simtime);		fprintf (outputfile, "                       "			 "seg = %d-%d\n", 			 currdiskreq->seg->startblkno, 			 currdiskreq->seg->endblkno);		fprintf (outputfile, "                       "			 "diskreq = %d, %d, %d (1==R)\n",			 currdiskreq->ioreqlist->blkno, 			 currdiskreq->ioreqlist->bcount, 			 (currdiskreq->ioreqlist->flags & READ));		fflush(outputfile);	      }	      disk_buffer_remove_from_seg(currdiskreq);	    }	  }	} 	if(!currdiskreq->seg && (best_value <= 4)) {	  disk_buffer_select_segment(currdisk, currdiskreq, FALSE);	  if(currdiskreq->seg) {	    if(currdiskreq->hittype == BUFFER_NOMATCH) {	      currdiskreq->seg = NULL;	    } 	    else {	      if(currdisk->reqwater) {		currdiskreq->watermark = max(1, (int) ((double) min(currdiskreq->seg->size, currdiskreq->ioreqlist->bcount) * currdisk->readwater));	      } 	      else {		currdiskreq->watermark = (int) (((double) currdiskreq->seg->size * currdisk->readwater) + (double) 0.9999999999);	      }	      currioreq = disk_request_needs_bus(currdisk,currdiskreq,TRUE);	      if(!currioreq) {		currdiskreq->seg = NULL;		currdiskreq->hittype = BUFFER_NOMATCH;	      } 	      else {		curr_value = ((currdiskreq->hittype == BUFFER_WHOLE) ? 4 : 3);		curr_set_segment = TRUE;	      }	    }	  }	}      }    else if((best_value <= 2) 	    && (currdisk->writeprebuffering) 	    && !(currdiskreq->ioreqlist->flags & READ))       {	if(currdiskreq->seg) {	  currioreq = disk_request_needs_bus(currdisk,currdiskreq,TRUE);	  if(currioreq) {	    tmpioreq = currdiskreq->ioreqlist;	    while (tmpioreq->next) {	      tmpioreq = tmpioreq->next;	    }	    if(currdisk->effectivehda && 	       (currdisk->effectivehda->seg == currdiskreq->seg)) {	      curr_value = 2;	    } 	    else if(currdisk->currenthda && 		    (currdisk->currenthda->seg == currdiskreq->seg)) {	      curr_value = 1;	    } 	    else {	      curr_value = 0;	    }	  }	} 	else if(best_value <= -1) {	  disk_buffer_select_segment(currdisk,currdiskreq,FALSE);	  if(currdiskreq->seg) {	    if(currdisk->reqwater) {	      currdiskreq->watermark = max(1, (int) ((double) min(currdiskreq->seg->size, currdiskreq->ioreqlist->bcount) * currdisk->writewater));	    } 	    else {	      currdiskreq->watermark = (int) (((double) currdiskreq->seg->size * currdisk->writewater) + (double) 0.9999999999);	    }	    currioreq = disk_request_needs_bus(currdisk,currdiskreq,TRUE);	    if(currioreq) {	      curr_value = -1;	      curr_set_segment = TRUE;	    } 	    else {	      currdiskreq->seg = NULL;	      currdiskreq->hittype = BUFFER_NOMATCH;	    }	  }	}      }    if(curr_value >= best_value) {      if(*busioreq) {	addtoextraq((event *) *busioreq);	if(best_set_segment) {	  bestdiskreq->seg = NULL;	  bestdiskreq->hittype = BUFFER_NOMATCH;	}      }      best_value = curr_value;      best_set_segment = curr_set_segment;      bestdiskreq = currdiskreq;      *busioreq = currioreq;    } else if(curr_set_segment) {      currdiskreq->seg = NULL;      currdiskreq->hittype = BUFFER_NOMATCH;    }    currdiskreq = currdiskreq->bus_next;  }  if(best_set_segment) {    disk_buffer_set_segment(currdisk,bestdiskreq);  }  return(bestdiskreq);} // disk_select_bus_request()/* * Attempt to start bus activity.  If currdiskreq doesn't match a * non-NULL effectivebus, do nothing.  Otherwise, if currdiskreq * doesn't match a non-NULL currentbus, do nothing.  Otherwise, if * there is already a request outstanding (buswait), do nothing. * Otherwise, check to see if currdiskreq needs some bus activity.  If * currdiskreq is NULL, attempt to find the appropriate next request * from the queue. * * Queue priority list: *    effectivebus (if non-NULL, this is the only choice possible) *    currentbus   (if non-NULL, this is the only choice possible) *    see disk_select_bus_request  */static void disk_check_bus (disk *currdisk, diskreq *currdiskreq){  diskreq     *nextdiskreq = currdiskreq;  diskreq     *tmpdiskreq;  ioreq_event *busioreq = NULL;  double	delay;  if(disk_printhack && (simtime >= disk_printhacktime)) {    fprintf (outputfile, "%12.6f  %8p  Entering disk_check_bus for disk %d\n", simtime, currdiskreq,currdisk->devno);    fflush(outputfile);  }  if(currdisk->buswait) {    return;  }  /* add checking here for acctime >= 0.0 */  if(currdiskreq) {    if(currdisk->effectivebus) {      if(currdisk->effectivebus != currdiskreq) {	nextdiskreq = NULL;      }    }     else if(currdisk->currentbus) {      if(currdisk->currentbus != currdiskreq) {	nextdiskreq = NULL;      }    }    if(nextdiskreq) {      /* Only truly affected call is the one from disk_check_hda.  It       * needs to be TRUE in order to match disk_completion's call.       * Otherwise, preseeking is disadvantaged...         */      busioreq = disk_request_needs_bus(currdisk,nextdiskreq,TRUE);      if(!busioreq) {	nextdiskreq = NULL;      }    }  }   else {    if(currdisk->effectivebus) {      busioreq = disk_request_needs_bus(currdisk,currdisk->effectivebus,TRUE);      if(busioreq) {	nextdiskreq = currdisk->effectivebus;      }    }     else if(currdisk->currentbus) {      busioreq = disk_request_needs_bus(currdisk,currdisk->currentbus,TRUE);      if(busioreq) {	nextdiskreq = currdisk->currentbus;      }    }     else {      nextdiskreq = disk_select_bus_request(currdisk,&busioreq);    }  }  if(nextdiskreq) {    if(disk_printhack && (simtime >= disk_printhacktime)) {      fprintf (outputfile, "                        nextdiskreq = %8p\n", nextdiskreq);      fflush(outputfile);    }    if((nextdiskreq != currdisk->currentbus)        && (nextdiskreq != currdisk->effectivebus))       {	/* remove nextdiskreq from bus queue */	if(currdisk->pendxfer == nextdiskreq) {	  currdisk->pendxfer = nextdiskreq->bus_next;	} 	else {	  tmpdiskreq = currdisk->pendxfer;	  while (tmpdiskreq && (tmpdiskreq->bus_next != nextdiskreq)) {	    tmpdiskreq = tmpdiskreq->bus_next;	  }	  ddbg_assert2(tmpdiskreq != 0, 		     "Next bus request not found in bus queue");	  tmpdiskreq->bus_next = nextdiskreq->bus_next;	}	nextdiskreq->bus_next = NULL;      }    currdisk->currentbus = currdisk->effectivebus = nextdiskreq;    if(busioreq->cause == RECONNECT) {      if(nextdiskreq->ioreqlist->flags & READ) {	disk_activate_read(currdisk, nextdiskreq, FALSE, FALSE);      }       else {	disk_activate_write(currdisk, nextdiskreq, FALSE, FALSE);      }      if(currdisk->extradisc_diskreq == nextdiskreq) {	currdisk->extradisc_diskreq = NULL;	delay = currdisk->overhead_reselect_first;      }       else {	delay = ((nextdiskreq->flags & EXTRA_WRITE_DISCONNECT) ? currdisk->overhead_reselect_other : currdisk->overhead_reselect_first);      }      if(busioreq->bcount > 0) {	delay += currdisk->overhead_data_prep;      }      if(currdisk->const_acctime) {	delay = 0.0;      }       else {	nextdiskreq->seg->outstate = BUFFER_CONTACTING;      }      currdisk->outstate = DISK_WAIT_FOR_CONTROLLER;      disk_send_event_up_path(busioreq, (delay * currdisk->timescale));    }     else if(busioreq->cause == DEVICE_DATA_TRANSFER_COMPLETE) {      disk_reconnection_or_transfer_complete(busioreq);    }     else {      ddbg_assert2(0, "unexpected busioreq->cause in disk_check_bus");    }  }} // disk_check_bus()static void disk_get_remapped_sector(disk *currdisk, ioreq_event *curr){  double acctime;  segment *seg;  diskreq *currdiskreq = currdisk->effectivehda;  ddbg_assert2(currdiskreq != 0, "No effectivehda");  seg = currdiskreq->seg;  // new ltop and acctime  {    uint64_t nsecs;    struct dm_pbn pbn;    currdisk->model->layout->dm_translate_ltop(currdisk->model, 					       curr->blkno, 					       MAP_FULL,					       &pbn,					       0);    curr->cause = pbn.sector;      

⌨️ 快捷键说明

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