📄 disksim_diskctlr.c
字号:
busioreq->type = IO_INTERRUPT_ARRIVE; busioreq->cause = RECONNECT; } busioreq->bcount = min(seg->endblkno,(tmpioreq->blkno + tmpioreq->bcount)) - currdiskreq->outblkno; } } else { /* WRITE */ seg_owner = disk_buffer_seg_owner(seg,FALSE); if(!seg_owner) { seg_owner = currdiskreq; } if((currdiskreq->inblkno >= (tmpioreq->blkno + tmpioreq->bcount)) || ((currdiskreq->outblkno == currdiskreq->ioreqlist->blkno) && (currdiskreq->hittype != BUFFER_APPEND)) || ((seg->endblkno == currdiskreq->outblkno) && (seg->endblkno < (tmpioreq->blkno + tmpioreq->bcount)) && ((seg->endblkno - seg_owner->inblkno) < seg->size) && (!check_watermark || ((seg->endblkno - currdiskreq->inblkno) <= currdiskreq->watermark)))) { 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; } if((currdiskreq->outblkno == currdiskreq->ioreqlist->blkno) && (currdiskreq->hittype != BUFFER_APPEND)) { busioreq->bcount = min(tmpioreq->bcount,seg->size); } else { int i1 = tmpioreq->blkno + tmpioreq->bcount - currdiskreq->outblkno; int i2 = seg->size - seg->endblkno + seg_owner->inblkno; busioreq->bcount = min(i1, i2); } } } } return busioreq;}/* * Queue priority list: * 10 HDA_OWNED, !currenthda & !effectivehda (completions and full read hits) * 9 effectivehda * 8 currenthda * 7 Appending limited fastwrite (LIMITED_FASTWRITE and BUFFER_APPEND) * 6 Full sneakyintermediateread with seg * 5 Partial sneakyintermediateread with seg * 4 Full sneakyintermediateread currently without seg * 3 Partial sneakyintermediateread currently without seg * 2 Write prebuffer to effectivehda->seg * 1 Write prebuffer to currenthda->seg * 0 Write prebuffer with other seg * -1 Write prebuffer currently without seg * * Not usable: * requests which don't need bus service * requests using recycled segs * requests with no available segs * * If a sneakyintermediateread is detected which has a seg, was marked as * a read hit, has not transferred any data yet, and is no longer a hit, * remove the diskreq from the segment. * * Possible improvements: * un-set segment if read hit is no longer a hit and no data has been * transferred yet. * * reverse queue order (oldest first) so that we don't have to peruse * the entire queue if a 10 is found */static diskreq * disk_select_bus_request(disk *currdisk, ioreq_event **busioreq){ diskreq *currdiskreq = currdisk->pendxfer; diskreq *bestdiskreq = NULL; ioreq_event *currioreq = 0; ioreq_event *tmpioreq; int curr_value; int best_value = -99; int curr_set_segment; int best_set_segment = FALSE; if(disk_printhack && (simtime >= disk_printhacktime)) { fprintf (outputfile, "%12.6f Entering disk_select_bus_request for disk %d\n", simtime, currdisk->devno); fflush(outputfile); } while (currdiskreq) { curr_value = -100; curr_set_segment = FALSE; ddbg_assert2(currdiskreq->ioreqlist != 0, "diskreq with NULL ioreqlist found in bus queue"); if(currdiskreq->seg && (currdiskreq->seg->recyclereq == currdiskreq)) { // dont do anything } else if(currdiskreq->flags & HDA_OWNED) { currioreq = disk_request_needs_bus(currdisk,currdiskreq,TRUE); if(currioreq) { if(currdiskreq == currdisk->effectivehda) { curr_value = 9; } else if(currdiskreq == currdisk->currenthda) { curr_value = 8; } else { curr_value = 10; } } } else if((best_value <= 7) && (currdisk->fastwrites == LIMITED_FASTWRITE) && (currdiskreq->hittype == BUFFER_APPEND)) { currioreq = disk_request_needs_bus(currdisk,currdiskreq,TRUE); if(currioreq) { curr_value = 7; } } else if((best_value <= 6) && (currdisk->sneakyintermediatereadhits) && (currdiskreq->ioreqlist->flags & READ)) { if(currdiskreq->seg) { currioreq = disk_request_needs_bus(currdisk,currdiskreq,TRUE); if(currioreq) { tmpioreq = currdiskreq->ioreqlist; while (tmpioreq->next) { tmpioreq = tmpioreq->next; } curr_value = ((currdiskreq->seg->endblkno >= (tmpioreq->blkno + tmpioreq->bcount)) ? 6 : 5); } else if(currdiskreq->outblkno == currdiskreq->ioreqlist->blkno) { /* Not entirely sure this works or is appropriate */ currioreq = disk_request_needs_bus(currdisk,currdiskreq,FALSE); if(currioreq) { addtoextraq((event *)currioreq); } else { if(disk_printhack && (simtime >= disk_printhacktime)) { fprintf (outputfile, "%12.6f " "sneakyintermediatereadhits removed diskreq " "from seg\n", simtime); fprintf (outputfile, " " "seg = %d-%d\n", currdiskreq->seg->startblkno, currdiskreq->seg->endblkno); fprintf (outputfile, " " "diskreq = %d, %d, %d (1==R)\n", currdiskreq->ioreqlist->blkno, currdiskreq->ioreqlist->bcount, (currdiskreq->ioreqlist->flags & READ)); fflush(outputfile); } disk_buffer_remove_from_seg(currdiskreq); } } } if(!currdiskreq->seg && (best_value <= 4)) { disk_buffer_select_segment(currdisk, currdiskreq, FALSE); if(currdiskreq->seg) { if(currdiskreq->hittype == BUFFER_NOMATCH) { currdiskreq->seg = NULL; } else { if(currdisk->reqwater) { currdiskreq->watermark = max(1, (int) ((double) min(currdiskreq->seg->size, currdiskreq->ioreqlist->bcount) * currdisk->readwater)); } else { currdiskreq->watermark = (int) (((double) currdiskreq->seg->size * currdisk->readwater) + (double) 0.9999999999); } currioreq = disk_request_needs_bus(currdisk,currdiskreq,TRUE); if(!currioreq) { currdiskreq->seg = NULL; currdiskreq->hittype = BUFFER_NOMATCH; } else { curr_value = ((currdiskreq->hittype == BUFFER_WHOLE) ? 4 : 3); curr_set_segment = TRUE; } } } } } else if((best_value <= 2) && (currdisk->writeprebuffering) && !(currdiskreq->ioreqlist->flags & READ)) { if(currdiskreq->seg) { currioreq = disk_request_needs_bus(currdisk,currdiskreq,TRUE); if(currioreq) { tmpioreq = currdiskreq->ioreqlist; while (tmpioreq->next) { tmpioreq = tmpioreq->next; } if(currdisk->effectivehda && (currdisk->effectivehda->seg == currdiskreq->seg)) { curr_value = 2; } else if(currdisk->currenthda && (currdisk->currenthda->seg == currdiskreq->seg)) { curr_value = 1; } else { curr_value = 0; } } } else if(best_value <= -1) { disk_buffer_select_segment(currdisk,currdiskreq,FALSE); if(currdiskreq->seg) { if(currdisk->reqwater) { currdiskreq->watermark = max(1, (int) ((double) min(currdiskreq->seg->size, currdiskreq->ioreqlist->bcount) * currdisk->writewater)); } else { currdiskreq->watermark = (int) (((double) currdiskreq->seg->size * currdisk->writewater) + (double) 0.9999999999); } currioreq = disk_request_needs_bus(currdisk,currdiskreq,TRUE); if(currioreq) { curr_value = -1; curr_set_segment = TRUE; } else { currdiskreq->seg = NULL; currdiskreq->hittype = BUFFER_NOMATCH; } } } } if(curr_value >= best_value) { if(*busioreq) { addtoextraq((event *) *busioreq); if(best_set_segment) { bestdiskreq->seg = NULL; bestdiskreq->hittype = BUFFER_NOMATCH; } } best_value = curr_value; best_set_segment = curr_set_segment; bestdiskreq = currdiskreq; *busioreq = currioreq; } else if(curr_set_segment) { currdiskreq->seg = NULL; currdiskreq->hittype = BUFFER_NOMATCH; } currdiskreq = currdiskreq->bus_next; } if(best_set_segment) { disk_buffer_set_segment(currdisk,bestdiskreq); } return(bestdiskreq);} // disk_select_bus_request()/* * Attempt to start bus activity. If currdiskreq doesn't match a * non-NULL effectivebus, do nothing. Otherwise, if currdiskreq * doesn't match a non-NULL currentbus, do nothing. Otherwise, if * there is already a request outstanding (buswait), do nothing. * Otherwise, check to see if currdiskreq needs some bus activity. If * currdiskreq is NULL, attempt to find the appropriate next request * from the queue. * * Queue priority list: * effectivebus (if non-NULL, this is the only choice possible) * currentbus (if non-NULL, this is the only choice possible) * see disk_select_bus_request */static void disk_check_bus (disk *currdisk, diskreq *currdiskreq){ diskreq *nextdiskreq = currdiskreq; diskreq *tmpdiskreq; ioreq_event *busioreq = NULL; double delay; if(disk_printhack && (simtime >= disk_printhacktime)) { fprintf (outputfile, "%12.6f %8p Entering disk_check_bus for disk %d\n", simtime, currdiskreq,currdisk->devno); fflush(outputfile); } if(currdisk->buswait) { return; } /* add checking here for acctime >= 0.0 */ if(currdiskreq) { if(currdisk->effectivebus) { if(currdisk->effectivebus != currdiskreq) { nextdiskreq = NULL; } } else if(currdisk->currentbus) { if(currdisk->currentbus != currdiskreq) { nextdiskreq = NULL; } } if(nextdiskreq) { /* Only truly affected call is the one from disk_check_hda. It * needs to be TRUE in order to match disk_completion's call. * Otherwise, preseeking is disadvantaged... */ busioreq = disk_request_needs_bus(currdisk,nextdiskreq,TRUE); if(!busioreq) { nextdiskreq = NULL; } } } else { if(currdisk->effectivebus) { busioreq = disk_request_needs_bus(currdisk,currdisk->effectivebus,TRUE); if(busioreq) { nextdiskreq = currdisk->effectivebus; } } else if(currdisk->currentbus) { busioreq = disk_request_needs_bus(currdisk,currdisk->currentbus,TRUE); if(busioreq) { nextdiskreq = currdisk->currentbus; } } else { nextdiskreq = disk_select_bus_request(currdisk,&busioreq); } } if(nextdiskreq) { if(disk_printhack && (simtime >= disk_printhacktime)) { fprintf (outputfile, " nextdiskreq = %8p\n", nextdiskreq); fflush(outputfile); } if((nextdiskreq != currdisk->currentbus) && (nextdiskreq != currdisk->effectivebus)) { /* remove nextdiskreq from bus queue */ if(currdisk->pendxfer == nextdiskreq) { currdisk->pendxfer = nextdiskreq->bus_next; } else { tmpdiskreq = currdisk->pendxfer; while (tmpdiskreq && (tmpdiskreq->bus_next != nextdiskreq)) { tmpdiskreq = tmpdiskreq->bus_next; } ddbg_assert2(tmpdiskreq != 0, "Next bus request not found in bus queue"); tmpdiskreq->bus_next = nextdiskreq->bus_next; } nextdiskreq->bus_next = NULL; } currdisk->currentbus = currdisk->effectivebus = nextdiskreq; if(busioreq->cause == RECONNECT) { if(nextdiskreq->ioreqlist->flags & READ) { disk_activate_read(currdisk, nextdiskreq, FALSE, FALSE); } else { disk_activate_write(currdisk, nextdiskreq, FALSE, FALSE); } if(currdisk->extradisc_diskreq == nextdiskreq) { currdisk->extradisc_diskreq = NULL; delay = currdisk->overhead_reselect_first; } else { delay = ((nextdiskreq->flags & EXTRA_WRITE_DISCONNECT) ? currdisk->overhead_reselect_other : currdisk->overhead_reselect_first); } if(busioreq->bcount > 0) { delay += currdisk->overhead_data_prep; } if(currdisk->const_acctime) { delay = 0.0; } else { nextdiskreq->seg->outstate = BUFFER_CONTACTING; } currdisk->outstate = DISK_WAIT_FOR_CONTROLLER; disk_send_event_up_path(busioreq, (delay * currdisk->timescale)); } else if(busioreq->cause == DEVICE_DATA_TRANSFER_COMPLETE) { disk_reconnection_or_transfer_complete(busioreq); } else { ddbg_assert2(0, "unexpected busioreq->cause in disk_check_bus"); } }} // disk_check_bus()static void disk_get_remapped_sector(disk *currdisk, ioreq_event *curr){ double acctime; segment *seg; diskreq *currdiskreq = currdisk->effectivehda; ddbg_assert2(currdiskreq != 0, "No effectivehda"); seg = currdiskreq->seg; // new ltop and acctime { uint64_t nsecs; struct dm_pbn pbn; currdisk->model->layout->dm_translate_ltop(currdisk->model, curr->blkno, MAP_FULL, &pbn, 0); curr->cause = pbn.sector;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -