📄 disksim_diskcache.c
字号:
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 + -