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

📄 disksim_diskcache.c

📁 目前最精确的磁盘模拟器的第3版
💻 C
📖 第 1 页 / 共 4 页
字号:
	       tmpioreq = tmpioreq->next;	    }	 }      } else if (seg->state == BUFFER_CLEAN) {	 if (!seg->diskreqlist) {	    if (currdisk->numdirty < currdisk->numwritesegs) {/*		|| reusable_dirty_segment) {*/	       curr_value = 2;	       first_ioreq = currdiskreq->ioreqlist;	       while (first_ioreq) {	          if (disk_buffer_overlap(seg,first_ioreq)) {	             curr_value = 4;	             break;                  }	          first_ioreq = first_ioreq->next;	       }	    }         } else {            /* check for collision with uncleanable data */	    tmpioreq = currdiskreq->ioreqlist;	    while (tmpioreq) {	       if (disk_buffer_overlap(seg,tmpioreq)) {		  if (!disk_buffer_reusable_segment_check(currdisk, seg)) {		     currdiskreq->hittype = BUFFER_COLLISION;		     currdiskreq->seg = NULL;		  }                  break;	       }	       tmpioreq = tmpioreq->next;	    }	 }      } else if ((!currdisk->writecomb) || 		 (seg->outstate == BUFFER_TRANSFERING)) {	 /* no PREPEND's or APPEND's allowed */         /* check for collision with uncleanable data */	 tmpioreq = currdiskreq->ioreqlist;	 while (tmpioreq) {	    if (disk_buffer_overlap(seg,tmpioreq)) {	       if (!disk_buffer_reusable_segment_check(currdisk, seg)) {	          currdiskreq->hittype = BUFFER_COLLISION;	          currdiskreq->seg = NULL;	       }               break;	    }	    tmpioreq = tmpioreq->next;	 }/*	 if ((currdisk->numdirty >= currdisk->numwritesegs) &&	     !reusable_dirty_segment &&	     disk_buffer_reusable_segment_check(currdisk, seg)) {            reusable_dirty_segment = TRUE;            currdiskreq->seg = NULL;            currdiskreq->hittype = BUFFER_NOMATCH;            seg = currdisk->seglist;	    best_value = 0;	    continue;	 }*/      } else {         first_ioreq = currdiskreq->ioreqlist;	 tmp_diskreq = holddiskreq = seg->diskreqlist;	 while (tmp_diskreq->seg_next) {	    tmp_diskreq = tmp_diskreq->seg_next;	    if (!(tmp_diskreq->ioreqlist->flags & READ)) {	       holddiskreq = tmp_diskreq;	    }         }	 last_ioreq = holddiskreq->ioreqlist;         while (last_ioreq && last_ioreq->next) {	    last_ioreq = last_ioreq->next;	 }	 if ((first_ioreq->blkno == (last_ioreq->blkno + last_ioreq->bcount)) &&	     (first_ioreq->blkno == seg->endblkno) &&	     (seg->size > (first_ioreq->blkno - (disk_buffer_seg_owner(seg,FALSE))->inblkno))) {            curr_hittype = BUFFER_APPEND;	    curr_value = ((seg->state == BUFFER_WRITING) ? 7 : 6);	 } else if (seg->state == BUFFER_DIRTY) {	    int total_bcount = currdiskreq->ioreqlist->bcount;	    last_ioreq = currdiskreq->ioreqlist;	    while (last_ioreq->next) {	       last_ioreq = last_ioreq->next;	       total_bcount += last_ioreq->bcount;            }	    holddiskreq = seg->diskreqlist;	    while (holddiskreq->ioreqlist->flags & READ) {	       holddiskreq = holddiskreq->seg_next;            }	    first_ioreq = holddiskreq->ioreqlist;	    if ((first_ioreq->blkno == (last_ioreq->blkno + last_ioreq->bcount)) &&	        (first_ioreq->blkno == seg->startblkno) &&		((seg->startblkno == seg->endblkno) || (seg->hold_bcount == 0)) &&		(seg->size >= ((seg->endblkno - seg->startblkno) + total_bcount)) &&		(!currdisk->extradisc_diskreq || 		 (currdisk->extradisc_diskreq->seg != seg))) {               curr_hittype = BUFFER_PREPEND;	       curr_value = 5;	    }         }	 if (curr_hittype == BUFFER_NOMATCH) {            /* check for collision with uncleanable data */	    tmpioreq = currdiskreq->ioreqlist;	    while (tmpioreq) {	       if (disk_buffer_overlap(seg,tmpioreq)) {	          if (!disk_buffer_reusable_segment_check(currdisk, seg)) {	             currdiskreq->hittype = BUFFER_COLLISION;	             currdiskreq->seg = NULL;		  }                  break;	       }	       tmpioreq = tmpioreq->next;	    }/*	    if ((currdisk->numdirty >= currdisk->numwritesegs) &&	        !reusable_dirty_segment &&	        disk_buffer_reusable_segment_check(currdisk, seg)) {               reusable_dirty_segment = TRUE;               currdiskreq->seg = NULL;               currdiskreq->hittype = BUFFER_NOMATCH;               seg = currdisk->seglist;	       best_value = 0;	       continue;	    }*/	 }      }      if (curr_value > best_value) {	 currdiskreq->seg = seg;	 currdiskreq->hittype = curr_hittype;	 best_value = curr_value;      }      seg = seg->next;   }   /* If BUFFER_NOMATCH && BUFFER_READING, perform preemption check.      Note that currdiskreq->seg should be set before the call.   */   if ((best_value == 1) &&       !disk_buffer_stopable_access(currdisk,currdiskreq)) {      /* check for collision with uncleanable data */      tmpioreq = currdiskreq->ioreqlist;      while (tmpioreq) {         if (disk_buffer_overlap(currdiskreq->seg,tmpioreq)) {	    if (!disk_buffer_reusable_segment_check(currdisk, seg)) {  	       currdiskreq->hittype = BUFFER_COLLISION;	    }            break;	 }	 tmpioreq = tmpioreq->next;      }      currdiskreq->seg = NULL;   }if (disk_printhack && (simtime >= disk_printhacktime)) {fprintf (outputfile, "                        segment = %8p, hittype = %d\n",currdiskreq->seg,currdiskreq->hittype);fflush(outputfile);}   return(currdiskreq->seg);}segment * disk_buffer_select_segment (disk *currdisk, diskreq *currdiskreq,				      int set_extradisc){   segment *seg;   if (currdisk->const_acctime) {      currdiskreq->seg = NULL;      currdiskreq->hittype = BUFFER_NOMATCH;      return(NULL);   }   if(currdiskreq->ioreqlist->flags & READ) {      seg = disk_buffer_select_read_segment(currdisk, currdiskreq);      if (currdisk->dedicatedwriteseg && (seg == currdisk->dedicatedwriteseg)) {	 fprintf(stderr, "Read request about to use the write segment\n");	 exit(1);      }   }    else {			/* WRITE */      seg = disk_buffer_select_write_segment(currdisk, currdiskreq);   }   /* if suffering extra write disconnects and no extradisc_diskreq exists */   /* and this is a write following a non-sequential write, set the        */   /* EXTRA_WRITE_DISCONNECT diskreq flag.  */   if (set_extradisc        && currdisk->extra_write_disconnect        && !currdisk->neverdisconnect        && !currdisk->extradisc_diskreq        && !(currdiskreq->ioreqlist->flags & READ)        && seg        && ((LRU_at_seg_list_head && !seg->prev) 	   || (!LRU_at_seg_list_head && !seg->next))        && seg->access        && !(seg->access->flags & READ)        && (currdiskreq->ioreqlist->blkno != seg->endblkno))    {      currdiskreq->flags |= EXTRA_WRITE_DISCONNECT;   }   return(seg);}/* check for BUFFER hit (and no COLLISIONS's) */static int disk_buffer_check_read_segments (disk *currdisk, ioreq_event *currioreq, int* buffer_reading){   segment *seg;   int return_hittype = BUFFER_NOMATCH;   int read_hit_on_dirty_data = FALSE;if ((disk_printhack > 1) && (simtime >= disk_printhacktime)) {fprintf (outputfile, "%12.6f  %8p  Entering disk_buffer_check_read_segments\n",simtime,currioreq);fflush(outputfile);}   if (!currdisk->enablecache) {      return(BUFFER_NOMATCH);   }   seg = currdisk->seglist;   while (seg) {      if (seg->recyclereq) {      } else if (seg->state == BUFFER_EMPTY) {      } else if ((currdisk->dedicatedwriteseg) && 	  (seg == currdisk->dedicatedwriteseg)) {         /* check for collision with dirty data */         if ((seg->state == BUFFER_DIRTY) || (seg->state == BUFFER_WRITING)) {	    if (disk_buffer_overlap(seg,currioreq) &&	        !disk_buffer_reusable_segment_check(currdisk, seg)) {	       return(BUFFER_COLLISION);	    }	 }      } else if ((currioreq->blkno < seg->startblkno) || 		 (currioreq->blkno >= seg->endblkno)) {	 if (seg->state == BUFFER_CLEAN) {         } else if (seg->state == BUFFER_READING) {	    if ((seg->endblkno == currioreq->blkno) && 		currdisk->almostreadhits) {	       /* special case:  block currently being prefetched is		  the first block of this request.  We count this as		  a partial read hit.               */	       if (return_hittype == BUFFER_NOMATCH) {		  *buffer_reading = TRUE;	          return_hittype = BUFFER_PARTIAL;	       }	    }         } else if (currioreq->blkno < seg->startblkno) {            /* check for collision with dirty data */	    if (disk_buffer_overlap(seg,currioreq) &&		!disk_buffer_reusable_segment_check(currdisk, seg)) {	       return(BUFFER_COLLISION);	    }	 }      } else {	 switch (seg->state) {	 case BUFFER_DIRTY:	 case BUFFER_WRITING:	   if (read_hit_on_dirty_data ||	       (!currdisk->readhitsonwritedata &&		!disk_buffer_reusable_segment_check(currdisk, seg))) {	     return(BUFFER_COLLISION);	   }	   read_hit_on_dirty_data = TRUE;	   break;	 case BUFFER_READING:	   break;	 case BUFFER_CLEAN:	       if (!currdisk->readhitsonwritedata &&		   seg->access && !(seg->access->flags & READ)) {		 continue;	       }	       break;	 default:	   ddbg_assert(0);	 }	 if (seg->endblkno >= (currioreq->blkno + currioreq->bcount)) {            return_hittype = BUFFER_WHOLE;	    *buffer_reading = (seg->state == BUFFER_READING);         } else if (return_hittype != BUFFER_WHOLE) {	    return_hittype = BUFFER_PARTIAL;	    *buffer_reading = (seg->state == BUFFER_READING);	 }      }      seg = seg->next;   }if ((disk_printhack > 1) && (simtime >= disk_printhacktime) &&     (return_hittype != BUFFER_NOMATCH)) {fprintf (outputfile, "                        HITable segment found\n");fflush(outputfile);}   return(return_hittype);}/* check for directly APPENDable WRITING segment (and no COLLISION's) */static int disk_buffer_check_write_segments (disk *currdisk, ioreq_event *currioreq){   segment *seg;   int return_hittype = BUFFER_NOMATCH;   diskreq *tmp_diskreq;   diskreq *holddiskreq;   ioreq_event *last_ioreq;if ((disk_printhack > 1) && (simtime >= disk_printhacktime)) {fprintf (outputfile, "%12.6f  %8p  Entering disk_buffer_check_write_segments\n",simtime,currioreq);fflush(outputfile);}   if (!currdisk->writecomb) {      return(BUFFER_NOMATCH);   }   seg = currdisk->seglist;   while (seg) {      if (seg->recyclereq) {      }       else if (seg->state == BUFFER_EMPTY) {      }       else if (seg->state == BUFFER_READING) {	 return(BUFFER_NOMATCH);      }       else if ((currdisk->dedicatedwriteseg) && 	  (seg != currdisk->dedicatedwriteseg)) {         /* check for collision with uncleanable data */         if ((seg->state == BUFFER_CLEAN) && seg->diskreqlist) {	    if (disk_buffer_overlap(seg,currioreq) &&	        !disk_buffer_reusable_segment_check(currdisk, seg)) {	       return(BUFFER_COLLISION);	    }	 }      }       else if ((seg->state == BUFFER_CLEAN) || 	       (seg->state == BUFFER_DIRTY)) 	{	  /* check for collision with uncleanable data */	  if (seg->diskreqlist) {	    if (disk_buffer_overlap(seg,currioreq) &&		!disk_buffer_reusable_segment_check(currdisk, seg)) {	      return(BUFFER_COLLISION);	    }	  }      }       else if (seg->outstate == BUFFER_TRANSFERING) {         /* check for collision with uncleanable data */	 if (disk_buffer_overlap(seg,currioreq) &&	     !disk_buffer_reusable_segment_check(currdisk, seg)) {	    return(BUFFER_COLLISION);	 }      }       else {	 tmp_diskreq = holddiskreq = seg->diskreqlist;	 while (tmp_diskreq->seg_next) {	    tmp_diskreq = tmp_diskreq->seg_next;	    if (!(tmp_diskreq->ioreqlist->flags & READ)) {	       holddiskreq = tmp_diskreq;	    }         }	 last_ioreq = holddiskreq->ioreqlist;         while (last_ioreq && last_ioreq->next) {	    last_ioreq = last_ioreq->next;	 }	 if ((currioreq->blkno == (last_ioreq->blkno + last_ioreq->bcount)) &&	     (currioreq->blkno == seg->endblkno) &&	     (seg->size > (currioreq->blkno - (disk_buffer_seg_owner(seg,FALSE))->inblkno))) {            return_hittype = BUFFER_APPEND;	 } 	 else {            /* check for collision with uncleanable data */	    if (disk_buffer_overlap(seg,currioreq) &&	        !disk_buffer_reusable_segment_check(currdisk, seg)) {	       return(BUFFER_COLLISION);	    }	 }      }      seg = seg->next;   }if ((disk_printhack > 1) && (simtime >= disk_printhacktime) &&     (return_hittype == BUFFER_APPEND)) {fprintf (outputfile, "                        APPENDable segment found\n");fflush(outputfile);}   return(return_hittype);}/* Checks for cache/buffer hits */int disk_buffer_check_segments (disk *currdisk, ioreq_event *currioreq,			        int* buffer_reading){   if (currioreq->flags & READ) {      return(disk_buffer_check_read_segments(currdisk, currioreq, buffer_reading));   } else {      return(disk_buffer_check_write_segments(currdisk, currioreq));   }}void disk_buffer_set_segment (disk *currdisk, diskreq *currdiskreq){   segment     *seg = currdiskreq->seg;   segment     *tmp_seg;   diskreq     *tmp_diskreq;   ioreq_event *tmp_ioreq;   int          is_read = (currdiskreq->ioreqlist->flags & READ);if (disk_printhack && (simtime >= disk_printhacktime)) {fprintf (outputfile, "%12.6f  %8p  Entering disk_buffer_set_segment\n",simtime,currdiskreq);fflush(outputfile);}

⌨️ 快捷键说明

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