📄 disksim_iodriver.c
字号:
if (iodrivers[iodriverno]->devices[(req->devno)].queuectlr != -1) { int ctlrno = iodrivers[iodriverno]->devices[(req->devno)].queuectlr; ctl = &iodrivers[iodriverno]->ctlrs[ctlrno]; tmp = ctl->oversized; numreqs = 1; while (((numreqs) || (tmp != ctl->oversized)) && (tmp) && (tmp->next) && ((tmp->next->devno != req->devno) || (tmp->next->opid != req->opid) || (req->blkno < tmp->next->blkno) || (req->blkno >= (tmp->next->blkno + tmp->next->bcount)))) {/*fprintf (outputfile, "oversized request in list: opid %d, blkno %d, bcount %d\n", tmp->opid, tmp->blkno, tmp->bcount);*/ numreqs = 0; tmp = tmp->next; } if ((tmp) && (tmp->next->devno == req->devno) && (tmp->next->opid == req->opid) && (req->blkno >= tmp->next->blkno) && (req->blkno < (tmp->next->blkno + tmp->next->bcount))) {fprintf (outputfile, "%f, part of oversized request completed: opid %d, blkno %d, bcount %d, maxreqsize %d\n", simtime, req->opid, req->blkno, req->bcount, ctl->maxreqsize); if ((req->blkno + ctl->maxreqsize) < (tmp->next->blkno + tmp->next->bcount)) {fprintf (outputfile, "more to go\n"); req->blkno += ctl->maxreqsize; req->bcount = min(ctl->maxreqsize, (tmp->next->blkno + tmp->next->bcount - req->blkno)); goto schedule_next; } else {fprintf (outputfile, "done for real\n"); addtoextraq((event *) req); req = tmp->next; tmp->next = tmp->next->next; if (ctl->oversized == req) { ctl->oversized = (req != req->next) ? req->next : NULL; } req->next = NULL; } } } devno = req->devno; req = ioqueue_physical_access_done(iodrivers[iodriverno]->devices[devno].queue, req); if (ctl) { ctl->numoutstanding--; } if (disksim->traceformat == VALIDATE) { tmp = (ioreq_event *) getfromextraq(); io_validate_do_stats1(); tmp = iotrace_validate_get_ioreq_event(disksim->iotracefile, tmp); if (tmp) { io_validate_do_stats2(tmp); tmp->type = IO_REQUEST_ARRIVE; addtointq((event *) tmp); } else { disksim_simstop(); } } else if (disksim->closedios) { tmp = (ioreq_event *) io_get_next_external_event(disksim->iotracefile); if (tmp) { io_using_external_event ((event *)tmp); tmp->time = simtime + disksim->closedthinktime; tmp->type = IO_REQUEST_ARRIVE; addtointq((event *) tmp); } else { disksim_simstop(); } } while (req) { tmp = req; req = req->next; tmp->next = NULL; update_iodriver_statistics(); if ((numreqs = logorg_mapcomplete(sysorgs, numsysorgs, tmp)) == COMPLETE) { /* update up overall I/O system stats for this completed request */ ioreq_event *temp = ioqueue_get_specific_request (overallqueue, tmp); ioreq_event *temp2 = ioqueue_physical_access_done (overallqueue, temp); ASSERT (temp2 != NULL); addtoextraq((event *)temp); temp = NULL; if (iodrivers[iodriverno]->type != STANDALONE) { iodriver_add_to_intrp_eventlist(intrp, io_done_notify(tmp), iodrivers[iodriverno]->scale); } else { io_done_notify (tmp); } } else if (numreqs > 0) { for (i=0; i<numreqs; i++) { del = tmp->next; tmp->next = del->next; del->next = NULL; del->type = IO_REQUEST_ARRIVE; del->flags |= MAPPED; skip |= (del->devno == devno); if (iodrivers[iodriverno]->type == STANDALONE) { del->time += simtime + 0.0000000001; /* to affect an ordering */ addtointq((event *) del); } else { iodriver_add_to_intrp_eventlist(intrp, (event *) del, iodrivers[iodriverno]->scale); } } } addtoextraq((event *) tmp); } if ((iodrivers[iodriverno]->consttime == IODRIVER_TRACED_QUEUE_TIMES) || (iodrivers[iodriverno]->consttime == IODRIVER_TRACED_BOTH_TIMES)) { if (ioqueue_get_number_in_queue(iodrivers[iodriverno]->devices[devno].queue) > 0) { iodrivers[iodriverno]->devices[devno].flag = 1; iodrivers[iodriverno]->devices[devno].lastevent = simtime; } return; } if (skip) { return; } /* fprintf(outputfile, "iodriver_access_complete:: calling ioqueue_get_next_request\n"); */ req = ioqueue_get_next_request(iodrivers[iodriverno]->devices[devno].queue); /* fprintf (outputfile, "next scheduled: req %p, req->blkno %d, req->flags %x\n", req, ((req) ? req->blkno : 0), ((req) ? req->flags : 0)); */schedule_next: if (req) { req->type = IO_ACCESS_ARRIVE; req->next = NULL; if (ctl) { ctl->numoutstanding++; } if (iodrivers[iodriverno]->type == STANDALONE) { req->time = simtime; addtointq((event *) req); } else { iodriver_add_to_intrp_eventlist(intrp, (event *) req, iodrivers[iodriverno]->scale); } }}void iodriver_respond_to_device (int iodriverno, intr_event *intrp){ ioreq_event *req = NULL; int devno; int cause; if ((iodrivers[iodriverno]->consttime != 0.0) && (iodrivers[iodriverno]->consttime != IODRIVER_TRACED_QUEUE_TIMES)) { if (iodrivers[iodriverno]->type == STANDALONE) { addtoextraq((event *) intrp->infoptr); } return; } req = (ioreq_event *) intrp->infoptr;/*fprintf (outputfile, "%f, Responding to device - cause = %d, blkno %d\n", simtime, req->cause, req->blkno);*/ req->type = IO_INTERRUPT_COMPLETE; devno = req->devno; cause = req->cause; switch (cause) { case COMPLETION: if (iodrivers[iodriverno]->type != STANDALONE) { req = ioreq_copy((ioreq_event *) intrp->infoptr); } case DISCONNECT: case RECONNECT: iodriver_send_event_down_path(req); break; case READY_TO_TRANSFER: addtoextraq((event *) req); break; default: fprintf(stderr, "Unknown io_interrupt cause - %d\n", req->cause); exit(1); } iodriver_check_c700_based_status(iodrivers[iodriverno], devno, cause, IO_INTERRUPT_COMPLETE, 0);}void iodriver_interrupt_complete (int iodriverno, intr_event *intrp){/*fprintf (outputfile, "%f, Interrupt completing - cause = %d, blkno %d\n", simtime, ((ioreq_event *) intrp->infoptr)->cause, ((ioreq_event *) intrp->infoptr)->blkno);*/ if (iodrivers[iodriverno]->type == STANDALONE) { if (((ioreq_event *) intrp->infoptr)->cause == COMPLETION) { iodriver_access_complete(iodriverno, intrp); } iodriver_respond_to_device(iodriverno, intrp); } addtoextraq((event *) intrp);}static double iodriver_get_time_to_handle_interrupt (iodriver *curriodriver, int cause, int read){ double retval = 0.0; if (cause == DISCONNECT) { retval = (read) ? IODRIVER_READ_DISCONNECT_TIME : IODRIVER_WRITE_DISCONNECT_TIME; } else if (cause == RECONNECT) { retval = IODRIVER_RECONNECT_TIME; } else if (cause == COMPLETION) { retval = (IODRIVER_BASE_COMPLETION_TIME - IODRIVER_COMPLETION_RESPTODEV_TIME) * (double) 5; /* because it gets divided by five later */ } else if (cause != READY_TO_TRANSFER) { fprintf(stderr, "Unknown interrupt at time_to_handle_interrupt: %d\n", cause); exit(1); } return(curriodriver->scale * retval);}static double iodriver_get_time_to_respond_to_device (iodriver *curriodriver, int cause, double fifthoftotal){ double retval; if (cause == COMPLETION) { retval = IODRIVER_COMPLETION_RESPTODEV_TIME; } else { /* arbitrarily chosen based on some observations */ retval = fifthoftotal * (double) 4; } return(curriodriver->scale * retval);}void iodriver_interrupt_arrive (int iodriverno, intr_event *intrp){ event *tmp; ioreq_event *infoptr = (ioreq_event *) intrp->infoptr;/*fprintf (outputfile, "%f, Interrupt arriving - cause = %d, blkno %d\n", simtime, infoptr->cause, infoptr->blkno);*/ if ((iodrivers[iodriverno]->consttime == 0.0) || (iodrivers[iodriverno]->consttime == IODRIVER_TRACED_QUEUE_TIMES)) { intrp->time = iodriver_get_time_to_handle_interrupt(iodrivers[iodriverno], infoptr->cause, (infoptr->flags & READ)); iodriver_check_c700_based_status(iodrivers[iodriverno], infoptr->devno, infoptr->cause, IO_INTERRUPT_ARRIVE, infoptr->blkno); } else { intrp->time = 0.0; } if (iodrivers[iodriverno]->type == STANDALONE) { intrp->time += simtime; intrp->type = IO_INTERRUPT_COMPLETE; addtointq((event *) intrp); } else { tmp = getfromextraq(); intrp->time /= (double) 5; tmp->time = intrp->time; tmp->type = INTEND_EVENT; tmp->next = NULL; ((intr_event *)tmp)->vector = IO_INTERRUPT; intrp->eventlist = tmp; if (infoptr->cause == COMPLETION) { tmp = getfromextraq(); tmp->time = 0.0; tmp->type = IO_ACCESS_COMPLETE; tmp->next = intrp->eventlist; ((ioreq_event *)tmp)->tempptr1 = intrp; intrp->eventlist = tmp; } tmp = getfromextraq(); tmp->time = iodriver_get_time_to_respond_to_device(iodrivers[iodriverno], infoptr->cause, intrp->time); tmp->type = IO_RESPOND_TO_DEVICE; tmp->next = intrp->eventlist; ((ioreq_event *)tmp)->tempptr1 = intrp; intrp->eventlist = tmp; }}double iodriver_tick (){ int i, j; double ret = 0.0; for (i = 0; i < numiodrivers; i++) { for (j = 0; j < iodrivers[i]->numdevices; j++) { ret += ioqueue_tick(iodrivers[i]->devices[j].queue); } } return(0.0);}event * iodriver_request (int iodriverno, ioreq_event *curr){ ioreq_event *temp = NULL; ioreq_event *ret = NULL; ioreq_event *retlist = NULL; int numreqs;/* printf ("Entered iodriver_request - simtime %f, devno %d, blkno %d, cause %d\n", simtime, curr->devno, curr->blkno, curr->cause); fprintf (outputfile, "Entered iodriver_request - simtime %f, devno %d, blkno %d, cause %d\n", simtime, curr->devno, curr->blkno, curr->cause); fprintf (stderr, "Entered iodriver_request - simtime %f, devno %d, blkno %d, cause %d\n", simtime, curr->devno, curr->blkno, curr->cause);*/ if (outios) { fprintf(outios, "%.6f\t%d\t%d\t%d\t%x\n", simtime, curr->devno, curr->blkno, curr->bcount, curr->flags); }#if 0 fprintf (stderr, "Entered iodriver_request - simtime %f, devno %d, blkno %d, cause %d\n", simtime, curr->devno, curr->blkno, curr->cause);#endif /* add to the overall queue to start tracking */ ret = ioreq_copy (curr); ioqueue_add_new_request (overallqueue, ret); ret = NULL; disksim->totalreqs++; if ((disksim->checkpoint_iocnt > 0) && ((disksim->totalreqs % disksim->checkpoint_iocnt) == 0)) { disksim_register_checkpoint (simtime); } if (disksim->totalreqs == disksim->warmup_iocnt) { warmuptime = simtime; resetstats(); } numreqs = logorg_maprequest(sysorgs, numsysorgs, curr); temp = curr->next; for (; numreqs>0; numreqs--) { /* Request list size must match numreqs */ ASSERT(curr != NULL); curr->next = NULL; if ((iodrivers[iodriverno]->consttime == IODRIVER_TRACED_QUEUE_TIMES) || (iodrivers[iodriverno]->consttime == IODRIVER_TRACED_BOTH_TIMES)) { ret = ioreq_copy(curr); ret->time = simtime + (double) ret->tempint1 / (double) 1000; ret->type = IO_TRACE_REQUEST_START; addtointq((event *) ret); ret = NULL; if ((curr->slotno == 1) && (ioqueue_get_number_in_queue(iodrivers[iodriverno]->devices[(curr->devno)].queue) == 0)) { iodrivers[(iodriverno)]->devices[(curr->devno)].flag = 2; iodrivers[(iodriverno)]->devices[(curr->devno)].lastevent = simtime; } } ret = handle_new_request(iodrivers[iodriverno], curr); if ((ret) && (iodrivers[iodriverno]->type == STANDALONE) && (ret->time == 0.0)) { ret->type = IO_ACCESS_ARRIVE; ret->time = simtime; iodriver_schedule(iodriverno, ret); } else if (ret) { ret->type = IO_ACCESS_ARRIVE; ret->next = retlist; ret->prev = NULL; retlist = ret; } curr = temp; temp = (temp) ? temp->next : NULL; } if (iodrivers[iodriverno]->type == STANDALONE) { while (retlist) { ret = retlist; retlist = ret->next; ret->next = NULL; ret->time += simtime; addtointq((event *) ret); } }/*fprintf (outputfile, "leaving iodriver_request: retlist %p\n", retlist);*/ return((event *) retlist);}void iodriver_trace_request_start (int iodriverno, ioreq_event *curr){ ioreq_event *tmp; device *currdev = &iodrivers[iodriverno]->devices[(curr->devno)]; double tdiff = simtime - currdev->lastevent; if (currdev->flag == 1) { stat_update(&initiatenextstats, tdiff); } else if (currdev->flag == 2) { stat_update(&emptyqueuestats, tdiff); } currdev->flag = 0; tmp = ioqueue_get_specific_request(currdev->queue, curr); addtoextraq((event *) curr); ASSERT(tmp != NULL); schedule_disk_access(iodrivers[iodriverno], tmp); tmp->time = simtime; tmp->type = IO_ACCESS_ARRIVE; tmp->slotno = 0; if (tmp->time == simtime) { iodriver_schedule(iodriverno, tmp); } else { addtointq((event *) tmp); }}static void iodriver_set_ctl_to_device (int iodriverno, device * dev){ int i; ctlr *tmp; dev->ctl = NULL; for (i=0; i < iodrivers[iodriverno]->numctlrs; i++) { tmp = &iodrivers[iodriverno]->ctlrs[i]; if ((tmp->slotpath.value & dev->slotpath.value) == tmp->slotpath.value) { if ((tmp->buspath.value & dev->buspath.value) == tmp->buspath.value) { if (tmp->flags & DRIVER_C700) { dev->ctl = tmp; return; } else { dev->ctl = tmp; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -