📄 disksim_diskctlr.c
字号:
if(!(currdiskreq->flags & HDA_OWNED)) { ddbg_assert2(ioqueue_get_specific_request(currdisk->queue,tmpioreq), "ioreq_event not found"); disk_interferestats(currdisk, tmpioreq); } evtfound = (int)ioqueue_physical_access_done(currdisk->queue,tmpioreq); ddbg_assert2(evtfound != 0, "ioreq_event not found"); tmpioreq = tmpioreq->next; } if((currdisk->keeprequestdata == -1) && !currdiskreq->seg->diskreqlist->seg_next) { ddbg_assert2((currdiskreq->outblkno <= currdiskreq->seg->endblkno), "Unable to erase request data from segment"); currdiskreq->seg->startblkno = currdiskreq->outblkno; } if((currdiskreq == currdisk->effectivehda) || (currdiskreq == currdisk->currenthda)) { if(currdiskreq->seg->access->type == NULL_EVENT) { disk_release_hda(currdisk,currdiskreq); } else { if(currdisk->preseeking != NO_PRESEEK) { disk_check_prefetch_swap(currdisk); } } } } else { /* WRITE */ if((currdiskreq == currdisk->effectivehda) || (currdiskreq == currdisk->currenthda)) { if(currdiskreq->seg->access->type == NULL_EVENT) { disk_release_hda(currdisk,currdiskreq); } } } curr->time = simtime; curr->type = IO_INTERRUPT_ARRIVE; curr->cause = COMPLETION; if(currdisk->const_acctime) { delay = 0.0; } else { if(curr->flags & READ) { delay = currdisk->overhead_complete_read; } else { delay = currdisk->overhead_complete_write; } } disk_send_event_up_path(curr, (delay * currdisk->timescale)); currdisk->outstate = DISK_WAIT_FOR_CONTROLLER;}static void disk_reconnection_or_transfer_complete (ioreq_event *curr){ disk *currdisk = getdisk(curr->devno); diskreq *currdiskreq; ioreq_event *tmpioreq; double delay; currdiskreq = currdisk->effectivebus; if(!currdiskreq) { currdiskreq = currdisk->effectivebus = currdisk->currentbus; } ddbg_assert2(currdiskreq != 0, "effectivebus and currentbus are NULL"); if(disk_printhack && (simtime >= disk_printhacktime)) { fprintf (outputfile, "%12.6f %8p " "Entering disk_reconnection_or_transfer_complete for disk %d\n", simtime, currdiskreq, curr->devno); fflush(outputfile); } tmpioreq = currdiskreq->ioreqlist; while (tmpioreq) { if(tmpioreq->blkno == curr->blkno) { break; } tmpioreq = tmpioreq->next; } ddbg_assert2(tmpioreq != 0, "ioreq_event not found in effectivebus"); switch (currdisk->outstate) { case DISK_WAIT_FOR_CONTROLLER: case DISK_TRANSFERING: break; default: ddbg_assert3(0, ("Disk not waiting to transfer - devno %d, state %d\n", curr->devno, currdisk->outstate)); } currdisk->effectivebus = currdiskreq; currdisk->outstate = DISK_TRANSFERING; curr->type = DEVICE_DATA_TRANSFER_COMPLETE; curr = disk_buffer_transfer_size(currdisk, currdiskreq, curr); if(disk_printhack && (simtime >= disk_printhacktime)) { fprintf (outputfile, " disk_buffer_transfer_size set bcount to %d\n", curr->bcount); fflush(outputfile); } if(curr->bcount == -2) { ddbg_assert2(currdisk->outwait == 0, "non-NULL outwait found"); currdisk->outwait = curr; } else if(curr->bcount == -1) { curr->type = IO_INTERRUPT_ARRIVE; curr->cause = DISCONNECT; if(tmpioreq->flags & READ) { delay = ((currdisk->lastflags & READ) ? currdisk->overhead_disconnect_read_afterread : currdisk->overhead_disconnect_read_afterwrite); } else { delay = ((currdiskreq->flags & EXTRA_WRITE_DISCONNECT) ? currdisk->extradisc_disconnect2 : currdisk->overhead_disconnect_write); } disk_send_event_up_path(curr, (delay * currdisk->timescale)); currdisk->outstate = DISK_WAIT_FOR_CONTROLLER; } else if(curr->bcount == 0) { disk_request_complete(currdisk, currdiskreq, curr); } else if(curr->bcount > 0) { currdisk->starttrans = simtime; currdisk->blksdone = 0; disk_send_event_up_path(curr, (double) 0.0); }}/* If no SEG_OWNER exists, give seg to first read diskreq with HDA_OWNED but not effectivehda, or first diskreq with BUFFER_APPEND, or effectivehda if no such diskreqs exist (and the seg is appropriate)*/static void disk_find_new_seg_owner(disk *currdisk, segment *seg){ diskreq *currdiskreq = seg->diskreqlist; diskreq *bestdiskreq = NULL; if(disk_printhack && (simtime >= disk_printhacktime)) { fprintf (outputfile, "%12.6f Entering disk_find_new_seg_owner for disk %d\n", simtime, currdisk->devno); fflush(outputfile); } ddbg_assert(seg != NULL); ddbg_assert(seg->recyclereq == NULL); while (currdiskreq) { if(currdiskreq->flags & SEG_OWNED) { return; } if(!bestdiskreq && (currdiskreq != currdisk->effectivehda) && (currdiskreq->flags & HDA_OWNED) && (currdiskreq->ioreqlist) && (currdiskreq->ioreqlist->flags & READ)) { bestdiskreq = currdiskreq; } currdiskreq = currdiskreq->seg_next; } if(!bestdiskreq) { currdiskreq = seg->diskreqlist; while (currdiskreq) { if(currdiskreq->hittype == BUFFER_APPEND) { bestdiskreq = currdiskreq; break; } currdiskreq = currdiskreq->seg_next; } } if(bestdiskreq) { disk_buffer_attempt_seg_ownership(currdisk,bestdiskreq); } else if(currdisk->effectivehda && (currdisk->effectivehda->seg == seg)) { disk_buffer_attempt_seg_ownership(currdisk,currdisk->effectivehda); }}/* * If pure prefetch, release the hda and free the diskreq. * If active read, release the hda if preseeking level is appropriate. * If fast write, release the hda, remove the event(s) from the ioqueue, * and, if COMPLETION_RECEIVED, free all structures. If * LIMITED_FASTWRITE and an appended request exists, make it the * next effectivehda. * If slow write, call the completion routine and release the hda if * preseeking level is appropriate. */static void disk_release_hda(disk *currdisk, diskreq *currdiskreq){ ioreq_event *tmpioreq; ioreq_event *holdioreq; segment *seg = currdiskreq->seg; diskreq *tmpdiskreq; diskreq *nextdiskreq = NULL; int release_hda = FALSE; int free_structs = FALSE; if(disk_printhack && (simtime >= disk_printhacktime)) { fprintf (outputfile, "%12.6f %8p Entering disk_release_hda for disk %d\n", simtime, currdiskreq,currdisk->devno); fflush(outputfile); } ddbg_assert(currdiskreq != NULL); ddbg_assert3((currdiskreq == currdisk->effectivehda), ("currdiskreq 0x%x, effectivehda 0x%x", currdiskreq, currdisk->effectivehda)); ddbg_assert(seg != NULL); if(!currdiskreq->ioreqlist) { ddbg_assert2((currdiskreq->flags & COMPLETION_RECEIVED), "COMPLETION_RECEIVED not flagged for pure prefetch"); release_hda = TRUE; free_structs = TRUE; seg->state = ((currdisk->enablecache || seg->diskreqlist->seg_next) ? BUFFER_CLEAN : BUFFER_EMPTY); } else if(currdiskreq->ioreqlist->flags & READ) { if((currdisk->preseeking == PRESEEK_BEFORE_COMPLETION) || ((currdisk->preseeking == PRESEEK_DURING_COMPLETION) && (currdiskreq->flags & COMPLETION_SENT))) { int cleanOrEmpty; release_hda = TRUE; cleanOrEmpty = !(currdiskreq->flags & COMPLETION_SENT) ? BUFFER_CLEAN : BUFFER_EMPTY; seg->state = (currdisk->enablecache || seg->diskreqlist->seg_next || cleanOrEmpty); } } else if((currdiskreq->flags & COMPLETION_RECEIVED) || (currdisk->preseeking == PRESEEK_BEFORE_COMPLETION) || ((currdisk->preseeking == PRESEEK_DURING_COMPLETION) && (currdiskreq->flags & COMPLETION_SENT))) { release_hda = TRUE; if(currdiskreq->flags & COMPLETION_RECEIVED) { free_structs = TRUE; } /* check to see if seg should be left DIRTY */ tmpdiskreq = seg->diskreqlist; while (tmpdiskreq) { if(tmpdiskreq != currdiskreq) { tmpioreq = tmpdiskreq->ioreqlist; ddbg_assert(tmpioreq != NULL); if(!(tmpioreq->flags & READ)) { while (tmpioreq->next) { tmpioreq = tmpioreq->next; } if(tmpdiskreq->inblkno < (tmpioreq->blkno + tmpioreq->bcount)) { seg->state = BUFFER_DIRTY; if((tmpdiskreq->hittype == BUFFER_APPEND) && (currdisk->fastwrites == LIMITED_FASTWRITE)) { tmpioreq = currdiskreq->ioreqlist; ddbg_assert(tmpioreq != NULL); while (tmpioreq->next) { tmpioreq = tmpioreq->next; } if(tmpdiskreq->ioreqlist->blkno == (tmpioreq->blkno + tmpioreq->bcount)) { nextdiskreq = tmpdiskreq; } } break; } } } tmpdiskreq = tmpdiskreq->seg_next; } if(!tmpdiskreq) { if(seg->diskreqlist->seg_next) { seg->state = BUFFER_CLEAN; } else { int clean = (currdisk->enablecache && currdisk->readhitsonwritedata); if(clean) { seg->state = BUFFER_CLEAN; } else { seg->state = BUFFER_EMPTY; } } currdisk->numdirty--; if((disk_printhack > 1) && (simtime >= disk_printhacktime)) { fprintf (outputfile, " numdirty-- = %d\n",currdisk->numdirty); fflush(outputfile); } ddbg_assert3(((currdisk->numdirty >= 0) && (currdisk->numdirty <= currdisk->numwritesegs)), ("numdirty: %d", currdisk->numdirty)); } } if(disk_printhack && (simtime >= disk_printhacktime)) { fprintf (outputfile, " free_structs = %d, release_hda = %d\n", free_structs, release_hda); fflush(outputfile); } if(free_structs) { disk_buffer_remove_from_seg(currdiskreq); tmpioreq = currdiskreq->ioreqlist; while (tmpioreq) { holdioreq = tmpioreq->next; addtoextraq((event *) tmpioreq); tmpioreq = holdioreq; } addtoextraq((event *) currdiskreq); if(seg->recyclereq) { /* I don't think the following code ever gets used... */ fprintf(stderr,"GOT HERE! SURPRISE!\n"); ddbg_assert2(seg->diskreqlist == 0, "non-NULL diskreqlist found for recycled seg"); nextdiskreq = seg->recyclereq; disk_buffer_set_segment(currdisk,seg->recyclereq); disk_buffer_attempt_seg_ownership(currdisk,seg->recyclereq); seg->recyclereq = NULL; } else if(seg->diskreqlist) { disk_find_new_seg_owner(currdisk,seg); } } if(release_hda) { if(currdisk->currenthda == currdisk->effectivehda) { currdisk->currenthda = NULL; } currdisk->effectivehda = NULL; ddbg_assert2(seg->access->type == NULL_EVENT, "non-NULL seg->access->type found upon releasing hda"); disk_check_hda(currdisk, nextdiskreq, TRUE); } } /* Set up an ioreq_event for a request if it needs bus service. If * data is ready for transfer, bcount is set to the amount. */static ioreq_event * disk_request_needs_bus(disk *currdisk, diskreq *currdiskreq, int check_watermark){ ioreq_event *busioreq = NULL; ioreq_event *tmpioreq = currdiskreq->ioreqlist; diskreq *seg_owner; segment *seg = currdiskreq->seg; if((currdisk->outstate != DISK_IDLE) && !currdisk->outwait) { return 0; } if((currdiskreq->flags & FINAL_WRITE_RECONNECTION_1) && !(currdiskreq->flags & FINAL_WRITE_RECONNECTION_2)) { return 0; } if(currdisk->const_acctime) { if((currdiskreq == currdisk->currenthda) && (currdiskreq->overhead_done <= simtime)) { 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; } busioreq->bcount = 0; } return busioreq; } if(seg && (currdiskreq != seg->recyclereq) && tmpioreq && !(currdiskreq->flags & COMPLETION_SENT)) { while (tmpioreq && tmpioreq->next) { if(currdiskreq->outblkno < (tmpioreq->blkno + tmpioreq->bcount)) { break; } tmpioreq = tmpioreq->next; } if(currdiskreq->ioreqlist->flags & READ) { ddbg_assert2(currdiskreq->outblkno < (tmpioreq->blkno + tmpioreq->bcount), "read completion detected in disk_request_needs_bus"); if((seg->endblkno > currdiskreq->outblkno) && (seg->startblkno <= currdiskreq->outblkno) && (!check_watermark || (seg->endblkno >= (tmpioreq->blkno + tmpioreq->bcount)) || ((seg->endblkno - currdiskreq->outblkno) >= currdiskreq->watermark))) { if(currdisk->outwait) { busioreq = currdisk->outwait; currdisk->outwait = NULL; busioreq->time = simtime; } else { busioreq = ioreq_copy(tmpioreq); busioreq->time = simtime;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -