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

📄 disksim_diskctlr.c

📁 目前最精确的磁盘模拟器的第3版
💻 C
📖 第 1 页 / 共 5 页
字号:
      }    seg->state = BUFFER_WRITING;    if(nextdiskreq->inblkno < (nextioreq->blkno + nextioreq->bcount))     {      *initiate_seek = TRUE;    }     else {      *immediate_release = TRUE;    }  }  if(ok_to_check_bus      && (currdisk->extradisc_diskreq != nextdiskreq))   {    disk_check_bus(currdisk,nextdiskreq);  }}		      /* 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 void disk_check_hda(disk *currdisk, 			   diskreq *currdiskreq, 			   int ok_to_check_bus){  segment     *seg;  diskreq     *nextdiskreq = 0;  ioreq_event *nextioreq = 0;  int          initiate_seek = FALSE;  int          immediate_release = FALSE;  double       delay = 0.0;  double       mintime = 0.0;  if(disk_printhack && (simtime >= disk_printhacktime)) {    fprintf (outputfile, "%12.6f  %8p  Entering disk_check_hda"	     " for disk %d\n", simtime, currdiskreq,currdisk->devno);    fflush(outputfile);  }  if(currdisk->const_acctime) {    return;  }     // 1.  If effectivehda already set, do nothing.  if(currdisk->effectivehda) {    return;  }  else {    // try to get an effectivehda    disk_get_effectivehda(currdisk, currdiskreq);    if(!currdisk->effectivehda) {      return;     }  }  nextdiskreq = currdisk->effectivehda;  // oops.  the above code doesn't guarantee that seg is valid!  assert(nextdiskreq->seg != 0);  seg = nextdiskreq->seg;  if(nextdiskreq->ioreqlist) {    disk_check_hda_pending(currdisk, 			   nextioreq, 			   nextdiskreq, 			   seg, 			   ok_to_check_bus,			   &mintime,			   &immediate_release,			   &initiate_seek);  }   else {    // there aren't any requests so we're only prefetching    seg->state = BUFFER_READING;    if(seg->endblkno < seg->maxreadaheadblkno) {      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 pure read	 * segment in disk_check_hda\n"); exit(1); } 	 */      }       else {	seg->access->blkno = seg->endblkno;      }      seg->access->flags = READ | BUFFER_BACKGROUND;      currdisk->immed = currdisk->immedread;      if(seg->access->type == NULL_EVENT) {	initiate_seek = TRUE;      }    }     else {      immediate_release = TRUE;    }  } // pure prefetch case  if(disk_printhack && (simtime >= disk_printhacktime)) {    fprintf (outputfile, "                        "	     "initiate_seek = %d, immediate_release = %d\n", 	     initiate_seek, immediate_release);    fflush(outputfile);  }  if(initiate_seek) {    if(nextdiskreq->overhead_done > simtime) {      delay += nextdiskreq->overhead_done - simtime;    }         if(disk_seek_stoptime > simtime) {      delay += disk_seek_stoptime - simtime;    }         if(!disk_initiate_seek(currdisk,			   seg, 			   seg->access, 			   TRUE, 			   delay, 			   mintime))       {	disk_release_hda(currdisk, nextdiskreq);      }  }  else if(immediate_release) {    disk_release_hda(currdisk, nextdiskreq);  }  if(!immediate_release &&       (seg->state == BUFFER_READING) &&       (seg->access->flags & BUFFER_BACKGROUND))     {      disk_check_prefetch_swap(currdisk);    }} // static void disk_check_hda()/* prematurely stop a prefetch */static void disk_buffer_stop_access (disk *currdisk){  diskreq* effective = currdisk->effectivehda;  segment* seg;  if(disk_printhack && (simtime >= disk_printhacktime)) {    fprintf (outputfile, "%12.6f  %8p  Entering disk_buffer_stop_access\n", simtime, effective);    fflush(outputfile);  }  ddbg_assert2(effective != 0, "disk has NULL effectivehda");  ddbg_assert(effective == currdisk->currenthda);  seg = effective->seg;  ddbg_assert((seg->access->flags & BUFFER_BACKGROUND) &&	 (seg->access->flags & READ));  if(seg->access->type != NULL_EVENT) {    int rv = removefromintq((event *)seg->access);    ddbg_assert3(rv != FALSE,	       ("Non-null seg->access does not appear on the intq %d\n", 		seg->access->type));    seg->access->type = NULL_EVENT;  }  seg->state = ((!(effective->flags & COMPLETION_RECEIVED) 		 || currdisk->enablecache 		 || seg->diskreqlist->seg_next) ? BUFFER_CLEAN : BUFFER_EMPTY);  if(effective->flags & COMPLETION_RECEIVED) {    ddbg_assert2(effective->ioreqlist == 0,	       "Pure prefetch with non-NULL ioreqlist detected");    disk_buffer_remove_from_seg(effective);    addtoextraq((event *) effective);    if(seg->diskreqlist) {      disk_find_new_seg_owner(currdisk,seg);    }  }  currdisk->effectivehda = currdisk->currenthda = NULL;}/* attempt to take over control of the hda from an ongoing prefetch */static int disk_buffer_attempt_access_swap(disk *currdisk, 				diskreq *currdiskreq){  diskreq     *effective = currdisk->effectivehda;  ioreq_event *currioreq;  segment     *seg;  if(disk_printhack && (simtime >= disk_printhacktime)) {    fprintf (outputfile, "%12.6f  %8p  Entering disk_buffer_attempt_access_swap\n", simtime, currdiskreq);    fprintf (outputfile, "                        trying to swap %8p\n", effective);    fflush(outputfile);  }  ddbg_assert2(effective != 0, "disk has NULL effectivehda");  seg = effective->seg;  ddbg_assert(seg->access->flags & READ);  ddbg_assert(currdiskreq->ioreqlist != NULL);  /* Since "free" reads are not allowed to prefetch currently, we don't     really need the first clause.  But, better safe than sorry...  */  if((effective == currdisk->currenthda)      && (seg->access->flags & BUFFER_BACKGROUND)      && (!swap_forward_only 	 || !effective->ioreqlist 	 || (effective->ioreqlist->blkno < currdiskreq->ioreqlist->blkno))) {    if(effective->flags & COMPLETION_RECEIVED) {      ddbg_assert(effective->ioreqlist == NULL);      disk_buffer_remove_from_seg(effective);      addtoextraq((event *) effective);    }     else {      ddbg_assert(effective->ioreqlist != NULL);      currioreq = currdiskreq->ioreqlist;      ddbg_assert(currioreq != NULL);      while (currioreq->next) {	currioreq = currioreq->next;      }      seg->access->flags = currioreq->flags;      seg->minreadaheadblkno = max(seg->minreadaheadblkno, min((currioreq->blkno + currioreq->bcount + currdisk->minreadahead), currdisk->model->dm_sectors));      seg->maxreadaheadblkno = max(seg->maxreadaheadblkno, min(disk_buffer_get_max_readahead(currdisk,seg,currioreq), currdisk->model->dm_sectors));      if((seg->endblkno >= (currioreq->blkno + currioreq->bcount)) 	 && (seg->endblkno < seg->maxreadaheadblkno)) 	{	  seg->access->flags |= BUFFER_BACKGROUND;	}    }    currdisk->effectivehda = currdisk->currenthda = NULL;    if(disk_printhack && (simtime >= disk_printhacktime)) {      fprintf (outputfile, "                        Swap successful\n");      fflush(outputfile);    }    return(TRUE);  }  if(disk_printhack && (simtime >= disk_printhacktime)) {    fprintf (outputfile, "                        Swap unsuccessful\n");    fflush(outputfile);  }  return(FALSE);}/* setseg indicates that currdiskreq->seg has not been permanently * "set", and should be nullified if the hda cannot be obtained or * set if it is obtained  */static void disk_activate_read(disk *currdisk, 		   diskreq *currdiskreq, 		   int setseg, 		   int ok_to_check_bus){  ioreq_event *currioreq;  if(disk_printhack && (simtime >= disk_printhacktime)) {    fprintf (outputfile, "%12.6f  %8p  Entering disk_activate_read\n", simtime, currdiskreq);    fprintf (outputfile, "                        setseg = %d\n", setseg);    fflush(outputfile);  }  /* use specified access time instead of simulating mechanical     activity */  if(currdisk->const_acctime) {    if(!currdisk->currenthda) {      currdisk->currenthda = 	currdisk->effectivehda = 	currdisk->currentbus = currdiskreq;      currdiskreq->overhead_done = simtime + currdisk->acctime;      currioreq = ioreq_copy(currdiskreq->ioreqlist);      currioreq->ioreq_hold_diskreq = currdiskreq;      currioreq->type = DEVICE_PREPARE_FOR_DATA_TRANSFER;      currioreq->time = currdiskreq->overhead_done;      addtointq((event *) currioreq);      ioqueue_set_starttime(currdisk->queue,currdiskreq->ioreqlist);    }    return;  }  /* Is there a request being serviced right now? If so, can     it be interrupted? */  if(!(currdiskreq->flags & HDA_OWNED)      && currdisk->effectivehda      && (currdisk->effectivehda != currdiskreq)      && (currdiskreq->hittype != BUFFER_COLLISION)      && (!currdiskreq->seg 	 || (currdiskreq->seg->recyclereq == currdiskreq) 	 || (currdiskreq->seg->state != BUFFER_DIRTY))      && disk_buffer_stopable_access(currdisk,currdiskreq))     {      if((currdiskreq->seg != currdisk->effectivehda->seg) 	 || (currdiskreq->hittype == BUFFER_NOMATCH)) {	disk_buffer_stop_access(currdisk);      }       else {	disk_buffer_attempt_access_swap(currdisk,currdiskreq);      }    }    /* If we have a segment then try to own it */  if(currdiskreq->seg && setseg) {    if(currdisk->effectivehda) {      if(currdiskreq->seg->recyclereq == currdiskreq) {	/* I don't think the following code ever gets used... */	fprintf(stderr,"GOT HERE!  SURPRISE, SURPRISE!\n");	currdiskreq->seg->recyclereq = NULL;      }      currdiskreq->seg = NULL;      currdiskreq->hittype = BUFFER_NOMATCH;    }     else {      disk_buffer_set_segment(currdisk,currdiskreq);    }  }  /* if we have a segment but don't own it, try to own it */  if(currdiskreq->seg && !(currdiskreq->flags & SEG_OWNED)) {    disk_buffer_attempt_seg_ownership(currdisk,currdiskreq);  }  if(!(currdiskreq->flags & HDA_OWNED)      && (currdiskreq->hittype != BUFFER_COLLISION)) {    disk_check_hda(currdisk,currdiskreq,ok_to_check_bus);  }  if(!(currdiskreq->flags & HDA_OWNED)      && (currdisk->currentbus == currdiskreq)) {    currioreq = currdiskreq->ioreqlist;    while (currioreq) {      ioqueue_set_starttime(currdisk->queue,currioreq);      currioreq = currioreq->next;    }  }}/* setseg indicates that currdiskreq->seg has not been permanently * "set", and should be nullified if the hda cannot be obtained or set * if it is obtained  */static void disk_activate_write(disk *currdisk, 		    diskreq *currdiskreq, 		    int setseg, 		    int ok_to_check_bus){  ioreq_event *currioreq;  if(disk_printhack && (simtime >= disk_printhacktime)) {    fprintf (outputfile, "%12.6f  %8p  Entering disk_activate_write\n", simtime, currdiskreq);    fprintf (outputfile, "                        setseg = %d\n", setseg);    fflush(outputfile);  }  if(!currdisk->currenthda && (currdisk->const_acctime)) {    currdisk->currenthda =       currdisk->effectivehda =       currdisk->currentbus = currdiskreq;    currdiskreq->overhead_done = simtime + currdisk->acctime;    currioreq = ioreq_copy(currdiskreq->ioreqlist);    currioreq->ioreq_hold_diskreq = currdiskreq;    currioreq->type = DEVICE_PREPARE_FOR_DATA_TRANSFER;    currioreq->time = currdiskreq->overhead_done;    addtointq((event *) currioreq);    ioqueue_set_starttime(currdisk->queue,currdiskreq->ioreqlist);    return;  }  if(!(currdiskreq->flags & HDA_OWNED)      && currdisk->effectivehda      && (currdisk->effectivehda != currdiskreq)      && disk_buffer_stopable_access(currdisk,currdiskreq))     {      if((currdiskreq->seg != currdisk->effectivehda->seg) 	 || (currdiskreq->hittype != BUFFER_APPEND)) {	disk_buffer_stop_access(currdisk);      }    }    if(currdiskreq->seg && setseg) {    if(currdisk->effectivehda) {      if(currdiskreq->seg->recyclereq == currdiskreq) {	/* I don't think the following code ever gets used... */	fprintf(stderr,"GOT HERE!  SURPRISE, SURPRISE, SURPRISE!\n");	currdiskreq->seg->recyclereq = NULL;      }      currdiskreq->seg = NULL;      currdiskreq->hittype = BUFFER_NOMATCH;    }     else {      disk_buffer_set_segment(currdisk,currdiskreq);    }  }  if(currdiskreq->seg && !(currdiskreq->flags & SEG_OWNED)) {    disk_buffer_attempt_seg_ownership(currdisk,currdiskreq);  }  if(!(currdiskreq->flags & HDA_OWNED)      && (currdiskreq->hittype != BUFFER_COLLISION)) {    disk_check_hda(currdisk,currdiskreq,ok_to_check_bus);  }  if(!(currdiskreq->flags & HDA_OWNED)      && (currdisk->currentbus == currdiskreq)) {    currioreq = currdiskreq->ioreqlist;    while (currioreq) {      ioqueue_set_starttime(currdisk->queue,currioreq);      currioreq = currioreq->next;    }  }}static void disk_read_

⌨️ 快捷键说明

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