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