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

📄 disksim_diskctlr.c

📁 目前最精确的磁盘模拟器的第3版
💻 C
📖 第 1 页 / 共 5 页
字号:
      if(!(currdiskreq->flags & HDA_OWNED)) {	ddbg_assert2(ioqueue_get_specific_request(currdisk->queue,tmpioreq),		   "ioreq_event not found");		disk_interferestats(currdisk, tmpioreq);      }      evtfound = (int)ioqueue_physical_access_done(currdisk->queue,tmpioreq);      ddbg_assert2(evtfound != 0, "ioreq_event not found");      tmpioreq = tmpioreq->next;    }    if((currdisk->keeprequestdata == -1) &&	!currdiskreq->seg->diskreqlist->seg_next)      {	ddbg_assert2((currdiskreq->outblkno <= currdiskreq->seg->endblkno),		   "Unable to erase request data from segment");	currdiskreq->seg->startblkno = currdiskreq->outblkno;      }        if((currdiskreq == currdisk->effectivehda) ||	(currdiskreq == currdisk->currenthda))       {	if(currdiskreq->seg->access->type == NULL_EVENT) {	  disk_release_hda(currdisk,currdiskreq);	} 	else {	  if(currdisk->preseeking != NO_PRESEEK) {	    disk_check_prefetch_swap(currdisk);	  }	}      }  }   else {  			/* WRITE */    if((currdiskreq == currdisk->effectivehda)        || (currdiskreq == currdisk->currenthda))       {	if(currdiskreq->seg->access->type == NULL_EVENT) {	  disk_release_hda(currdisk,currdiskreq);	}      }  }  curr->time = simtime;  curr->type = IO_INTERRUPT_ARRIVE;  curr->cause = COMPLETION;  if(currdisk->const_acctime) {    delay = 0.0;  }  else {    if(curr->flags & READ) {      delay = currdisk->overhead_complete_read;    }    else {      delay = currdisk->overhead_complete_write;    }  }  disk_send_event_up_path(curr, (delay * currdisk->timescale));  currdisk->outstate = DISK_WAIT_FOR_CONTROLLER;}static void disk_reconnection_or_transfer_complete (ioreq_event *curr){  disk        *currdisk = getdisk(curr->devno);  diskreq     *currdiskreq;  ioreq_event *tmpioreq;  double delay;  currdiskreq = currdisk->effectivebus;  if(!currdiskreq) {    currdiskreq = currdisk->effectivebus = currdisk->currentbus;  }  ddbg_assert2(currdiskreq != 0, "effectivebus and currentbus are NULL");  if(disk_printhack && (simtime >= disk_printhacktime)) {    fprintf (outputfile, "%12.6f  %8p  "	     "Entering disk_reconnection_or_transfer_complete for disk %d\n", 	     simtime, currdiskreq, curr->devno);    fflush(outputfile);  }  tmpioreq = currdiskreq->ioreqlist;  while (tmpioreq) {    if(tmpioreq->blkno == curr->blkno) {      break;    }    tmpioreq = tmpioreq->next;  }  ddbg_assert2(tmpioreq != 0, "ioreq_event not found in effectivebus");  switch (currdisk->outstate) {  case DISK_WAIT_FOR_CONTROLLER:  case DISK_TRANSFERING:    break;  default:    ddbg_assert3(0, ("Disk not waiting to transfer - devno %d, state %d\n", 	       curr->devno, currdisk->outstate));  }  currdisk->effectivebus = currdiskreq;  currdisk->outstate = DISK_TRANSFERING;  curr->type = DEVICE_DATA_TRANSFER_COMPLETE;  curr = disk_buffer_transfer_size(currdisk, currdiskreq, curr);  if(disk_printhack && (simtime >= disk_printhacktime)) {    fprintf (outputfile, "                        disk_buffer_transfer_size set bcount to %d\n", curr->bcount);    fflush(outputfile);  }  if(curr->bcount == -2) {    ddbg_assert2(currdisk->outwait == 0, "non-NULL outwait found");    currdisk->outwait = curr;  }   else if(curr->bcount == -1) {    curr->type = IO_INTERRUPT_ARRIVE;    curr->cause = DISCONNECT;    if(tmpioreq->flags & READ) {      delay = ((currdisk->lastflags & READ) ? currdisk->overhead_disconnect_read_afterread : currdisk->overhead_disconnect_read_afterwrite);    }     else {      delay = ((currdiskreq->flags & EXTRA_WRITE_DISCONNECT) ? currdisk->extradisc_disconnect2 : currdisk->overhead_disconnect_write);    }    disk_send_event_up_path(curr, (delay * currdisk->timescale));    currdisk->outstate = DISK_WAIT_FOR_CONTROLLER;  }   else if(curr->bcount == 0) {    disk_request_complete(currdisk, currdiskreq, curr);  }   else if(curr->bcount > 0) {    currdisk->starttrans = simtime;    currdisk->blksdone = 0;    disk_send_event_up_path(curr, (double) 0.0);  }}/* If no SEG_OWNER exists, give seg to first read diskreq with HDA_OWNED but    not effectivehda, or first diskreq with BUFFER_APPEND, or effectivehda    if no such diskreqs exist (and the seg is appropriate)*/static void disk_find_new_seg_owner(disk *currdisk, segment *seg){  diskreq *currdiskreq = seg->diskreqlist;  diskreq *bestdiskreq = NULL;  if(disk_printhack && (simtime >= disk_printhacktime)) {    fprintf (outputfile, "%12.6f            Entering disk_find_new_seg_owner for disk %d\n", simtime, currdisk->devno);    fflush(outputfile);  }  ddbg_assert(seg != NULL);  ddbg_assert(seg->recyclereq == NULL);  while (currdiskreq) {    if(currdiskreq->flags & SEG_OWNED) {      return;    }    if(!bestdiskreq && (currdiskreq != currdisk->effectivehda) && 	(currdiskreq->flags & HDA_OWNED) && (currdiskreq->ioreqlist) &&	(currdiskreq->ioreqlist->flags & READ)) {      bestdiskreq = currdiskreq;    }    currdiskreq = currdiskreq->seg_next;  }  if(!bestdiskreq) {    currdiskreq = seg->diskreqlist;    while (currdiskreq) {      if(currdiskreq->hittype == BUFFER_APPEND) {	bestdiskreq = currdiskreq;	break;      }      currdiskreq = currdiskreq->seg_next;    }  }  if(bestdiskreq) {    disk_buffer_attempt_seg_ownership(currdisk,bestdiskreq);  }   else if(currdisk->effectivehda 	  && (currdisk->effectivehda->seg == seg))     {      disk_buffer_attempt_seg_ownership(currdisk,currdisk->effectivehda);    }}/* * If pure prefetch, release the hda and free the diskreq. * If active read, release the hda if preseeking level is appropriate. * If fast write, release the hda, remove the event(s) from the ioqueue, *   and, if COMPLETION_RECEIVED, free all structures.  If *   LIMITED_FASTWRITE and an appended request exists, make it the *   next effectivehda. * If slow write, call the completion routine and release the hda if *   preseeking level is appropriate. */static void disk_release_hda(disk *currdisk, diskreq *currdiskreq){  ioreq_event *tmpioreq;  ioreq_event *holdioreq;  segment *seg = currdiskreq->seg;  diskreq *tmpdiskreq;  diskreq *nextdiskreq = NULL;  int release_hda = FALSE;  int free_structs = FALSE;  if(disk_printhack && (simtime >= disk_printhacktime)) {    fprintf (outputfile, "%12.6f  %8p  Entering disk_release_hda for disk %d\n", simtime, currdiskreq,currdisk->devno);    fflush(outputfile);  }  ddbg_assert(currdiskreq != NULL);  ddbg_assert3((currdiskreq == currdisk->effectivehda), 	     ("currdiskreq 0x%x, effectivehda 0x%x", 	      currdiskreq, currdisk->effectivehda));  ddbg_assert(seg != NULL);  if(!currdiskreq->ioreqlist) {    ddbg_assert2((currdiskreq->flags & COMPLETION_RECEIVED),	       "COMPLETION_RECEIVED not flagged for pure prefetch");    release_hda = TRUE;    free_structs = TRUE;    seg->state =       ((currdisk->enablecache || seg->diskreqlist->seg_next)        ? BUFFER_CLEAN        : BUFFER_EMPTY);  }  else if(currdiskreq->ioreqlist->flags & READ) {    if((currdisk->preseeking == PRESEEK_BEFORE_COMPLETION)        || ((currdisk->preseeking == PRESEEK_DURING_COMPLETION) 	   && (currdiskreq->flags & COMPLETION_SENT)))      {	int cleanOrEmpty;	release_hda = TRUE;		cleanOrEmpty = !(currdiskreq->flags & COMPLETION_SENT)	  ? BUFFER_CLEAN 	  : BUFFER_EMPTY;	seg->state = (currdisk->enablecache 		       || seg->diskreqlist->seg_next 		       || cleanOrEmpty);      }  }  else if((currdiskreq->flags & COMPLETION_RECEIVED) 	  || (currdisk->preseeking == PRESEEK_BEFORE_COMPLETION) 	  || ((currdisk->preseeking == PRESEEK_DURING_COMPLETION) 	      && (currdiskreq->flags & COMPLETION_SENT)))    {      release_hda = TRUE;      if(currdiskreq->flags & COMPLETION_RECEIVED) {	free_structs = TRUE;      }	      /* check to see if seg should be left DIRTY */	      tmpdiskreq = seg->diskreqlist;      while (tmpdiskreq) {	if(tmpdiskreq != currdiskreq) {	  tmpioreq = tmpdiskreq->ioreqlist;	  ddbg_assert(tmpioreq != NULL);	  if(!(tmpioreq->flags & READ)) {	    while (tmpioreq->next) {	      tmpioreq = tmpioreq->next;	    }	    if(tmpdiskreq->inblkno < (tmpioreq->blkno + tmpioreq->bcount)) {	      seg->state = BUFFER_DIRTY;	      if((tmpdiskreq->hittype == BUFFER_APPEND) &&		 (currdisk->fastwrites == LIMITED_FASTWRITE)) {		tmpioreq = currdiskreq->ioreqlist;		ddbg_assert(tmpioreq != NULL);		while (tmpioreq->next) {		  tmpioreq = tmpioreq->next;		}		if(tmpdiskreq->ioreqlist->blkno == 		   (tmpioreq->blkno + tmpioreq->bcount)) 		  {		    nextdiskreq = tmpdiskreq;		  }	      }	      break;	    }	  }	}	tmpdiskreq = tmpdiskreq->seg_next;      }	      if(!tmpdiskreq) {	if(seg->diskreqlist->seg_next) {	  seg->state = BUFFER_CLEAN;	} 	else {	  int clean = (currdisk->enablecache && currdisk->readhitsonwritedata);	  if(clean) {	    seg->state = BUFFER_CLEAN;	  }	  else {	    seg->state = BUFFER_EMPTY;	  }	}	currdisk->numdirty--;	if((disk_printhack > 1) 	   && (simtime >= disk_printhacktime)) 	  {	    fprintf (outputfile, "                        numdirty-- = %d\n",currdisk->numdirty);	    fflush(outputfile);	  }	ddbg_assert3(((currdisk->numdirty >= 0) 		    && (currdisk->numdirty <= currdisk->numwritesegs)),		   ("numdirty: %d", currdisk->numdirty));      }    }   if(disk_printhack && (simtime >= disk_printhacktime)) {    fprintf (outputfile, "                        free_structs = %d, release_hda = %d\n", free_structs, release_hda);    fflush(outputfile);  }    if(free_structs) {    disk_buffer_remove_from_seg(currdiskreq);    tmpioreq = currdiskreq->ioreqlist;    while (tmpioreq) {      holdioreq = tmpioreq->next;      addtoextraq((event *) tmpioreq);      tmpioreq = holdioreq;    }    addtoextraq((event *) currdiskreq);    if(seg->recyclereq) {      /* I don't think the following code ever gets used... */      fprintf(stderr,"GOT HERE!  SURPRISE!\n");            ddbg_assert2(seg->diskreqlist == 0,		 "non-NULL diskreqlist found for recycled seg");            nextdiskreq = seg->recyclereq;      disk_buffer_set_segment(currdisk,seg->recyclereq);      disk_buffer_attempt_seg_ownership(currdisk,seg->recyclereq);      seg->recyclereq = NULL;    }     else if(seg->diskreqlist) {      disk_find_new_seg_owner(currdisk,seg);    }  }    if(release_hda) {    if(currdisk->currenthda == currdisk->effectivehda) {      currdisk->currenthda = NULL;    }    currdisk->effectivehda = NULL;    ddbg_assert2(seg->access->type == NULL_EVENT,	       "non-NULL seg->access->type found upon releasing hda");        disk_check_hda(currdisk, nextdiskreq, TRUE);  }  }  /* Set up an ioreq_event for a request if it needs bus service.  If *  data is ready for transfer, bcount is set to the amount.   */static ioreq_event * disk_request_needs_bus(disk *currdisk, 		       diskreq *currdiskreq,		       int check_watermark){  ioreq_event *busioreq = NULL;  ioreq_event *tmpioreq = currdiskreq->ioreqlist;  diskreq     *seg_owner;  segment     *seg = currdiskreq->seg;  if((currdisk->outstate != DISK_IDLE) && !currdisk->outwait) {    return 0;  }  if((currdiskreq->flags & FINAL_WRITE_RECONNECTION_1) &&      !(currdiskreq->flags & FINAL_WRITE_RECONNECTION_2)) {    return 0;  }  if(currdisk->const_acctime) {    if((currdiskreq == currdisk->currenthda) && 	(currdiskreq->overhead_done <= simtime)) {      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;      }      busioreq->bcount = 0;    }    return busioreq;  }  if(seg      && (currdiskreq != seg->recyclereq)      && tmpioreq      && !(currdiskreq->flags & COMPLETION_SENT))     {      while (tmpioreq && tmpioreq->next) {	if(currdiskreq->outblkno < (tmpioreq->blkno + tmpioreq->bcount)) {	  break;	}	tmpioreq = tmpioreq->next;      }      if(currdiskreq->ioreqlist->flags & READ) {	ddbg_assert2(currdiskreq->outblkno < 		   (tmpioreq->blkno + tmpioreq->bcount),		   "read completion detected in disk_request_needs_bus");	if((seg->endblkno > currdiskreq->outblkno) 	   && (seg->startblkno <= currdiskreq->outblkno) 	   && (!check_watermark 	       || (seg->endblkno >= (tmpioreq->blkno + tmpioreq->bcount)) 	       || ((seg->endblkno - currdiskreq->outblkno) >= 		   currdiskreq->watermark))) 	  {	    if(currdisk->outwait) {	      busioreq = currdisk->outwait;	      currdisk->outwait = NULL;	      busioreq->time = simtime;	    } 	    else {	      busioreq = ioreq_copy(tmpioreq);	      busioreq->time = simtime;

⌨️ 快捷键说明

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