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

📄 disksim_diskcache.c

📁 目前最精确的磁盘模拟器的第3版
💻 C
📖 第 1 页 / 共 4 页
字号:
   if (!seg) {      fprintf(stderr, "diskreq has NULL segment in disk_buffer_set_segment\n");      exit(1);   }   /* check to make sure segment/diskreq combination is valid */   if (is_read && (seg == currdisk->dedicatedwriteseg)) {      fprintf(stderr, "Read request about to use the write segment\n");      exit(1);   }   if (seg->recyclereq && (currdiskreq != seg->recyclereq)) {      fprintf(stderr, "non-recyclereq detected for recycled segment in disk_buffer_set_segment\n");      exit(1);   }   switch (seg->state) {      case BUFFER_EMPTY:	 if (currdiskreq == seg->recyclereq) {            fprintf(stderr, "seg->state of BUFFER_EMPTY for recyclereq in disk_buffer_set_segment\n");            exit(1);	 }	 break;      case BUFFER_CLEAN:	 if (currdiskreq == seg->recyclereq) {            fprintf(stderr, "seg->state of BUFFER_CLEAN for recyclereq in disk_buffer_set_segment\n");            exit(1);	 }	 if (is_read && currdiskreq->hittype != BUFFER_NOMATCH && !currdisk->readhitsonwritedata && seg->access && !(seg->access->flags & READ)) {            fprintf(stderr, "Unallowed read hit on write data disk_buffer_set_segment\n");            exit(1);	 }	 break;      case BUFFER_DIRTY:	 if (currdiskreq == seg->recyclereq) {            fprintf(stderr, "seg->state of BUFFER_DIRTY for recyclereq in disk_buffer_set_segment\n");            exit(1);	 }	 if (currdiskreq->hittype == BUFFER_NOMATCH) {            fprintf(stderr, "Attempt to overwrite dirty data in disk_buffer_set_segment\n");            exit(1);	 } else if (is_read && !currdisk->readhitsonwritedata) {            fprintf(stderr, "Unallowed read hit on write data disk_buffer_set_segment\n");            exit(1);	 }	 if (!is_read) {	    currdisk->stat.writecombs++;         }	 break;      case BUFFER_READING:	 if (currdiskreq == seg->recyclereq) {	    if (!(currdiskreq->ioreqlist->flags & READ)) {               fprintf(stderr, "seg->state of BUFFER_READING for write recyclereq in disk_buffer_set_segment\n");               exit(1);	    }	 } else if (!is_read || (currdiskreq->hittype == BUFFER_NOMATCH)) {	    if (!disk_buffer_stopable_access(currdisk,currdiskreq)) {               fprintf(stderr, "Attempt to re-target active read segment in disk_buffer_set_segment\n");               exit(1);	    }         }	 break;      case BUFFER_WRITING:	 if (currdiskreq == seg->recyclereq) {	    if (currdiskreq->ioreqlist->flags & READ) {               fprintf(stderr, "seg->state of BUFFER_WRITING for read recyclereq in disk_buffer_set_segment\n");               exit(1);	    }         } else {	    if ((currdiskreq->hittype == BUFFER_NOMATCH) || 	        (currdiskreq->hittype == BUFFER_PREPEND)) {               fprintf(stderr, "Attempt to re-target active write segment in disk_buffer_set_segment\n");               exit(1);	    }	    if (!is_read) {	       currdisk->stat.writecombs++;            }	 }	 break;      default:	 fprintf(stderr, "Invalid segment state in disk_buffer_set_segment - blkno %d, bcount %d, state %d\n", currdiskreq->ioreqlist->blkno, currdiskreq->ioreqlist->bcount, seg->state);         exit(1);   }   /* end of sanity checks, now do the work */   disk_buffer_stats(currdisk,currdiskreq->ioreqlist,seg,currdiskreq->hittype);   if (LRU_at_seg_list_head) {      /* place segment at beginning of disk's segment list (for LRU) */      if (seg->prev) {         seg->prev->next = seg->next;         if (seg->next) {	    seg->next->prev = seg->prev;         }         seg->next = currdisk->seglist;         currdisk->seglist->prev = seg;         seg->prev = NULL;         currdisk->seglist = seg;      }   } else {      /* place segment at end of disk's segment list (for LRU) */      if (seg->next) {         if (seg->prev) {            seg->prev->next = seg->next;         } else {   	 currdisk->seglist = seg->next;         }         seg->next->prev = seg->prev;         tmp_seg = currdisk->seglist;         while (tmp_seg->next) {   	 tmp_seg = tmp_seg->next;         }         tmp_seg->next = seg;         seg->prev = tmp_seg;         seg->next = NULL;      }   }   /* clear out clean, non-active, overlapping segments if write */   if (!is_read) {      tmp_seg = currdisk->seglist;      while (tmp_seg) {	 if (tmp_seg != seg) {            tmp_ioreq= currdiskreq->ioreqlist;            while (tmp_ioreq) {               if ((tmp_seg->state != BUFFER_EMPTY) &&                   disk_buffer_overlap(tmp_seg,tmp_ioreq)) {                  if ((tmp_seg->state == BUFFER_CLEAN) &&                      (tmp_seg->diskreqlist == NULL)) {                     tmp_seg->state = BUFFER_EMPTY;/*	          } else {                     fprintf(stderr, "Request overlaps with non-clean segment in disk_buffer_set_segment\n");                     exit(1);*/	          }               }               tmp_ioreq = tmp_ioreq->next;            }	 }         tmp_seg = tmp_seg->next;      }   }   /* add diskreq to seg's diskreq list, sorted in ascending blkno order */   if (!seg->diskreqlist) {      if (seg->access == NULL) {         seg->access = ioreq_copy(currdiskreq->ioreqlist);	 seg->access->type = NULL_EVENT;      }      seg->diskreqlist = currdiskreq;      currdiskreq->seg_next = NULL;   } else {				/* non-empty list */      diskreq *prev_diskreq = 0;      tmp_diskreq = seg->diskreqlist;      while (tmp_diskreq) {	 if (tmp_diskreq->ioreqlist && 	     (currdiskreq->ioreqlist->blkno < tmp_diskreq->ioreqlist->blkno)) {	    currdiskreq->seg_next = tmp_diskreq;            if (seg->diskreqlist == tmp_diskreq) {	       seg->diskreqlist = currdiskreq;	    } else {	       prev_diskreq->seg_next = currdiskreq;	    }	    break;         }         prev_diskreq = tmp_diskreq;	 tmp_diskreq = tmp_diskreq->seg_next;      }      if (!tmp_diskreq) {	 prev_diskreq->seg_next = currdiskreq;         currdiskreq->seg_next = NULL;      }   }   /* set watermark */   /* I'm still figuring out this watermark business -rcohen */   tmp_ioreq = currdiskreq->ioreqlist;   if (is_read) {      if (currdisk->reqwater) {         currdiskreq->watermark = max(1, (int) ((double) min(seg->size, tmp_ioreq->bcount) * currdisk->readwater));      } else {         currdiskreq->watermark = (int) (((double) seg->size * currdisk->readwater) + (double) 0.9999999999);      }   } else {			/* WRITE */      if (currdisk->reqwater) {         currdiskreq->watermark = max(1, (int) ((double) min(seg->size, tmp_ioreq->bcount) * currdisk->writewater));      } else {         currdiskreq->watermark = (int) (((double) seg->size * currdisk->writewater) + (double) 0.9999999999);      }   }}int disk_buffer_attempt_seg_ownership (disk *currdisk, diskreq *currdiskreq){   segment     *seg = currdiskreq->seg;   diskreq     *tmp_diskreq;   ioreq_event *currioreq = currdiskreq->ioreqlist;   int         currdiskreq_found = FALSE;   int         write_found = FALSE;   int	       write_incomplete = 0;   ioreq_event *tmpioreq;if (disk_printhack && (simtime >= disk_printhacktime)) {fprintf (outputfile, "%12.6f  %8p  Entering disk_buffer_attempt_seg_ownership\n",simtime,currdiskreq);fflush(outputfile);}   if (!seg) {      fprintf(stderr, "diskreq has NULL segment in disk_buffer_attempt_seg_ownership\n");      exit(1);   }   if (currdiskreq->flags & SEG_OWNED) {      fprintf(stderr, "diskreq already owns seg in disk_buffer_attempt_seg_ownership\n");      exit(1);   }   tmp_diskreq = seg->diskreqlist;   while (tmp_diskreq) {      if (tmp_diskreq->flags & SEG_OWNED) {         if (currdiskreq->hittype == BUFFER_PREPEND) {            if (seg->state != BUFFER_DIRTY) {               fprintf(stderr, "PREPEND of active request detected in disk_buffer_attempt_seg_ownership\n");               exit(1);	    }	    /* release ownership to new request and set up hold areas */	    tmp_diskreq->flags &= ~SEG_OWNED;	    tmp_diskreq->hittype = BUFFER_APPEND;	    if (seg->endblkno != seg->startblkno) {	       if (seg->hold_bcount != 0) {                  fprintf(stderr, "PREPEND of segment already 'holding' data detected in disk_buffer_attempt_seg_ownership\n");                  exit(1);	       }               seg->hold_blkno = seg->startblkno;	       seg->hold_bcount = seg->endblkno - seg->startblkno;	    }	 } else {	    break;         }      }      if (tmp_diskreq == currdiskreq) {	 currdiskreq_found = TRUE;      } else if (!currdiskreq_found && tmp_diskreq->ioreqlist && 		 !(tmp_diskreq->ioreqlist->flags & READ)) {	 write_found = TRUE;	 tmpioreq = tmp_diskreq->ioreqlist;	 while (tmpioreq->next) {	    tmpioreq = tmpioreq->next;	 }	 if (tmp_diskreq->inblkno < (tmpioreq->blkno + tmpioreq->bcount)) {	    write_incomplete = TRUE;	 }      }      tmp_diskreq = tmp_diskreq->seg_next;   }   if (!tmp_diskreq) {      ASSERT(!write_found || !write_incomplete);      currdiskreq->flags |= SEG_OWNED;      if (currioreq &&          (!currdisk->effectivehda || 	   (currdisk->effectivehda == currdiskreq) ||	   (currdisk->effectivehda->seg != seg))) {         seg->access->flags = currioreq->flags;      }      /* set state, startblkno, endblkno, and readahead fields */      if (!currioreq || (currioreq->flags & READ)) {	 /* check to see if the cache segment needs to be reset */#if 0	/* GROK: removed on 10/10/99, because it causes problems, but */	/* we are not sure that removing this won't break something   */	/* else down the road...                                      */	 if ((currdiskreq->hittype != BUFFER_NOMATCH) &&	     (seg->startblkno > currdiskreq->outblkno)) {	    currdiskreq->hittype = BUFFER_NOMATCH;         }#endif	 if (currdiskreq->hittype == BUFFER_NOMATCH) {            ASSERT(currioreq != NULL);	    ASSERT1(((seg->access->type == NULL_EVENT) ||		     (seg->recyclereq == currdiskreq)),"seg->access->type",seg->access->type);	    if (currdiskreq != seg->recyclereq) {	       seg->state = BUFFER_CLEAN;               seg->access->blkno = currdiskreq->outblkno;	    }	    seg->startblkno = seg->endblkno = currdiskreq->outblkno;	    seg->minreadaheadblkno = seg->maxreadaheadblkno = -1;	    seg->hold_bcount = 0;	 }         if (currioreq) {	    while (currioreq->next) {	       currioreq = currioreq->next;	    }	    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)) &&	        (currdisk->effectivehda == currdiskreq)) {               seg->access->flags |= BUFFER_BACKGROUND;            }	 }      } else {			/* WRITE */	 if (!currdisk->effectivehda || 	     (currdisk->effectivehda == currdiskreq) ||	     (currdisk->effectivehda->seg != seg)) {	    if ((currdiskreq != seg->recyclereq) &&		(seg->access->type == NULL_EVENT)){               seg->access->blkno = currdiskreq->inblkno;	    }            if (currdiskreq->flags & COMPLETION_RECEIVED) {               seg->access->flags |= BUFFER_BACKGROUND;            }	 }	 if (currdiskreq->hittype == BUFFER_NOMATCH) {	    seg->minreadaheadblkno = seg->maxreadaheadblkno = -1;	    seg->hold_bcount = 0;	    seg->startblkno = seg->endblkno = currdiskreq->inblkno;	    if (currdiskreq != seg->recyclereq) {	       seg->state = BUFFER_DIRTY;	       currdisk->numdirty++;if ((disk_printhack > 1) && (simtime >= disk_printhacktime)) {fprintf (outputfile, "                        numdirty++ = %d\n",currdisk->numdirty);fflush(outputfile);}	       ASSERT1(((currdisk->numdirty >= 0) && (currdisk->numdirty <= currdisk->numwritesegs)),"numdirty",currdisk->numdirty);	    }	 } else if (currdiskreq->hittype == BUFFER_PREPEND) {	    seg->startblkno = seg->endblkno = currdiskreq->inblkno;	 }      }   }if (disk_printhack && (simtime >= disk_printhacktime)) {fprintf (outputfile, "                        Ownership = %d\n",(currdiskreq->flags & SEG_OWNED));fflush(outputfile);}   return(currdiskreq->flags & SEG_OWNED);}int disk_buffer_get_max_readahead (disk *currdisk, segment *seg, ioreq_event *curr){   int endreq;   if (!(curr->flags & READ)) {      fprintf(stderr, "No read-ahead for write accesses, in disk_buffer_get_max_readahead\n");      exit(1);   }   endreq = curr->blkno + curr->bcount;   if (currdisk->contread == BUFFER_NO_READ_AHEAD) {      return(endreq);   } else if (currdisk->contread == BUFFER_DEC_PREFETCH_SCHEME) {      int startlbn;      int endlbn;      struct dm_pbn pbn;      //      band* bandptr;      curr->blkno += curr->bcount;      // bandptr =       // was MAP_FULL      currdisk->model->layout->dm_translate_ltop(currdisk->model, 						 curr->blkno, 						 MAP_FULL,						 &pbn, 						 0); // remapsector      currdisk->model->layout->dm_get_track_boundaries(currdisk->model,						       &pbn,						       &startlbn, 						       &endlbn,						       0); // remapsector      // new track_boundaries semantics      endlbn++;      curr->blkno -= curr->bcount;      if (seg->startblkno < startlbn) {	return (endlbn + currdisk->model->layout->dm_get_sectors_lbn(currdisk->model, curr->blkno));      } else {	  return(endlbn);      }   }   if (currdisk->maxreadahead) {      return(endreq + currdisk->maxreadahead);   }   if (currdisk->keeprequestdata > 0) {      if ((curr->bcount >= seg->size) 	  || ((seg->size - curr->bcount) < currdisk->minreadahead)) 	{	  return(endreq + currdisk->minreadahead);	}      return(curr->blkno + seg->size);   }   return(endreq + seg->size);}

⌨️ 快捷键说明

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