📄 disksim_ioqueue.c
字号:
*surfptr = 0; break; case MAP_IGNORESPARING: case MAP_ZONEONLY: case MAP_ADDSLIPS: case MAP_FULL: device_get_mapping(cylmaptype, curr->iolist->devno, blkno, cylptr, surfptr, NULL); break; case MAP_FROMTRACE: /* this yucky cast is being allowed for convenience. We know * it can't really hurt us... */ *cylptr = (int) curr->iolist->buf; *surfptr = 0; break; case MAP_AVGCYLMAP: *cylptr = blkno / queue->sectpercyl; *surfptr = 0; break; default: fprintf(stderr, "Unknown cylinder mapping type: %d\n", queue->cylmaptype); exit(1); }}void ioqueue_set_concatok_function (ioqueue *queue, int (**concatok)(void *,int,int,int,int), void *concatokparam){ queue->concatok = concatok; queue->concatokparam = concatokparam;}void ioqueue_set_idlework_function (ioqueue *queue, void (**idlework)(void *,int), void *idleworkparam, double idledelay){ queue->idlework = idlework; queue->idleworkparam = idleworkparam; queue->idledelay = idledelay; queue->idledetect = NULL;}void ioqueue_set_enablement_function (ioqueue *queue, int (**enablement)(ioreq_event *)){ queue->base.enablement = enablement; queue->timeout.enablement = enablement; queue->priority.enablement = enablement;}static void ioqueue_idledetected (timer_event *timereq){ ioqueue *queue = (ioqueue *) timereq->ptr; queue->idledetect = NULL; (*queue->idlework)(queue->idleworkparam, queue->devno); addtoextraq((event *)timereq);}void ioqueue_reset_idledetecter (ioqueue *queue, int timechange){ timer_event *idledetect = queue->idledetect; int listlen = queue->base.listlen + queue->timeout.listlen + queue->priority.listlen; if ((listlen) || ((idledetect) && (!timechange))) { return; } if (idledetect) { if (!(removefromintq((event *)idledetect))) { fprintf(stderr, "existing idledetect event not on intq in ioqueue_reset_idledetecter\n"); exit(1); } } else { idledetect = (timer_event *) getfromextraq(); idledetect->type = TIMER_EXPIRED; idledetect->func = &disksim->timerfunc_ioqueue; idledetect->ptr = queue; queue->idledetect = idledetect; } idledetect->time = simtime + queue->idledelay; addtointq((event *)idledetect);}static void ioqueue_update_arrival_stats (ioqueue *queue, ioreq_event *curr){ double tdiff; if (queue->printintarrstats) { tdiff = simtime - queue->lastarr; queue->lastarr = simtime; stat_update(&queue->intarrstats, tdiff); if (curr->flags & READ) { tdiff = simtime - queue->lastread; queue->lastread = simtime; stat_update(&queue->readintarrstats, tdiff); } else { tdiff = simtime - queue->lastwrite; queue->lastwrite = simtime; stat_update(&queue->writeintarrstats, tdiff); } } if (queue->printsizestats) { stat_update(&queue->reqsizestats, (double) curr->bcount); if (curr->flags & READ) { stat_update(&queue->readsizestats, (double) curr->bcount); } else { stat_update(&queue->writesizestats, (double) curr->bcount); } } if (curr->blkno == queue->seqblkno) { if ((curr->flags & READ) && (queue->seqflags & READ)) { queue->seqreads++; } else if (!(curr->flags & READ) && !(queue->seqflags & READ)) { queue->seqwrites++; } } queue->seqblkno = curr->blkno + curr->bcount; queue->seqflags = curr->flags;}static void ioqueue_update_subqueue_statistics (subqueue *queue){ double tdiff = simtime - queue->lastalt; queue->runlistlen += tdiff * queue->listlen; queue->runreadlen += tdiff * queue->readlen; if (queue->readlen > queue->maxreadlen) { queue->maxreadlen = queue->readlen; } if ((queue->listlen - queue->readlen) > queue->maxwritelen) { queue->maxwritelen = queue->listlen - queue->readlen; } queue->runoutstanding += tdiff * queue->numoutstanding; if (queue->numoutstanding > queue->maxoutstanding) { queue->maxoutstanding = queue->numoutstanding; } if (queue->listlen > queue->maxlistlen) { queue->maxlistlen = queue->listlen; } if ((queue->listlen - queue->numoutstanding) > queue->maxqlen) { queue->maxqlen = queue->listlen - queue->numoutstanding; } queue->lastalt = simtime;}static void remove_tsps(iobuf *tmp);static void ioqueue_remove_from_subqueue (subqueue *queue, iobuf *tmp){ if(queue->sched_alg == TSPS){ remove_tsps(tmp); } if ((queue->list == tmp) && (tmp == tmp->next)) { queue->list = NULL; } else { tmp->next->prev = tmp->prev; tmp->prev->next = tmp->next; if (queue->list == tmp) { queue->list = tmp->prev; } } tmp->next = NULL; tmp->prev = NULL;}/* queue->list not NULL when entered */static void ioqueue_insert_fcfs_to_queue (subqueue *queue, iobuf *temp){ temp->next = queue->list->next; temp->prev = queue->list; temp->next->prev = temp; temp->prev->next = temp; queue->list = temp;}/* queue->list not NULL when entered */static void ioqueue_insert_ordered_to_queue (subqueue *queue, iobuf *temp){ iobuf *head; iobuf *run; head = queue->list->next; if ((temp->cylinder < head->cylinder) || ((temp->cylinder == head->cylinder) && (temp->surface < head->surface)) || ((temp->cylinder == head->cylinder) && (temp->surface == head->surface) && (temp->blkno < head->blkno))) { queue->list->next = temp; temp->next = head; temp->prev = queue->list; head->prev = temp; } else if ((temp->cylinder > queue->list->cylinder) || ((temp->cylinder == queue->list->cylinder) && (temp->surface > queue->list->surface)) || ((temp->cylinder == queue->list->cylinder) && (temp->surface == queue->list->surface) && (temp->blkno >= queue->list->blkno))) { temp->next = head; temp->prev = queue->list; head->prev = temp; queue->list->next = temp; queue->list = temp; } else { run = head; while ((temp->cylinder > run->next->cylinder) || ((temp->cylinder == run->next->cylinder) && (temp->surface > run->next->surface)) || ((temp->cylinder == run->next->cylinder) && (temp->surface == run->next->surface) && (temp->blkno >= run->next->blkno))) { run = run->next; } temp->next = run->next; temp->prev = run; temp->next->prev = temp; run->next = temp; }}static int ioqueue_check_concat (subqueue *queue, iobuf *req1, iobuf *req2, int concatmax){ ioreq_event *tmp; int seqscheme = queue->bigqueue->seqscheme; int (**concatok)(void *,int,int,int,int) = queue->bigqueue->concatok; void *concatokparam = queue->bigqueue->concatokparam; if (req1->next != req2) { fprintf(stderr, "Non-adjacent requests sent to ioqueue_check_concat\n"); exit(1); } if (req1->flags & READ) { if (!(seqscheme & IOQUEUE_CONCAT_READS) || !(req2->flags & READ)) { return(0); } } else { if (!(seqscheme & IOQUEUE_CONCAT_WRITES) || (req2->flags & READ)) { return(0); } } if ((req1 == queue->list) || (req1 == req2) || !READY_TO_GO(req1,queue) || !READY_TO_GO(req2,queue) || ((req1->blkno + req1->totalsize) != req2->blkno) || ((req1->totalsize + req2->totalsize) > concatmax)) { return(0); } if (concatok) { if ((*concatok)(concatokparam, req1->blkno, req1->totalsize, req2->blkno, req2->totalsize) == 0) { return(0); } } tmp = req1->iolist; if (tmp == NULL) { req1->iolist = req2->iolist; } else { while (tmp->next) { tmp = tmp->next; } tmp->next = req2->iolist; } req1->next = req2->next; req1->next->prev = req1; req1->reqcnt += req2->reqcnt; req1->totalsize += req2->totalsize; if (queue->list == req2) { queue->list = req1; } queue->iobufcnt--; addtoextraq((event *) req2); return(1);}static void ioqueue_insert_new_request (subqueue *queue, iobuf *temp){ int concatmax; ioqueue_update_subqueue_statistics(queue); queue->iobufcnt++; if (queue->list == NULL) { queue->list = temp; temp->next = temp; temp->prev = temp; } else { if ((queue->sched_alg == FCFS) || (queue->sched_alg == PRI_VSCAN_LBN)) { ioqueue_insert_fcfs_to_queue(queue, temp); } else { ioqueue_insert_ordered_to_queue(queue, temp); } } concatmax = queue->bigqueue->concatmax; if (concatmax) { temp = temp->prev; if (!(ioqueue_check_concat(queue, temp, temp->next, concatmax))) { temp = temp->next; } ioqueue_check_concat(queue, temp, temp->next, concatmax); } queue->listlen++; if (temp->flags & READ) { queue->readlen++; queue->numreads++; } else { queue->numwrites++; }}/* Returns 0 if request is sequential from a previous request (and detection *//* enabled). Otherwise returns 1. *//* Assuming no command queueing. */static int ioqueue_seqstream_head (ioqueue *queue, iobuf *listhead, iobuf *current){ int idiff; int ret = 0; if (!(queue->seqscheme & (IOQUEUE_SEQSTREAM_READS|IOQUEUE_SEQSTREAM_WRITES|IOQUEUE_SEQSTREAM_EITHER))) { return(1); } idiff = queue->seqstreamdiff; if ((current == listhead) || !READY_TO_GO(current->prev,(&queue->base))) { ret = 1; } if (ret == 0) { if (current->flags & READ) { if (current->prev->flags & READ) { if (!(queue->seqscheme & (IOQUEUE_SEQSTREAM_READS|IOQUEUE_SEQSTREAM_EITHER))) { ret = 1; } } else { if (!(queue->seqscheme & IOQUEUE_SEQSTREAM_EITHER)) { ret = 1; } } if ((current->prev->blkno != current->blkno) && (((current->prev->blkno + current->prev->totalsize + idiff) < current->blkno))) { ret = 1; } } else { if (current->prev->flags & READ) { if (!(queue->seqscheme & IOQUEUE_SEQSTREAM_EITHER)) { ret = 1; } } else { if (!(queue->seqscheme & (IOQUEUE_SEQSTREAM_WRITES|IOQUEUE_SEQSTREAM_EITHER))) { ret = 1; } } if ((current->prev->blkno != current->blkno) && ((current->prev->blkno + current->prev->totalsize) != current->blkno)) { ret = 1; } } } return(ret);}/* Queue contains >= 2 items when called */static iobuf * ioqueue_get_request_from_fcfs_queue (subqueue *queue){ iobuf *tmp; int i; tmp = queue->list->next; for (i = 0; i < queue->iobufcnt; i++) { if (queue->force_absolute_fcfs) { if (tmp->state == WAITING) { if (READY_TO_GO(tmp,queue)) { return(tmp); } else { return(NULL); } } } else { if (READY_TO_GO(tmp,queue)) { return(tmp); } } tmp = tmp->next; } return(NULL);}/* Queue contains >= 2 items when called */static int ioqueue_get_priority_level (ioqueue *ioqueue, iobuf *req){ int ret = 0; if (ioqueue->priority_mix == 1) { if ((req->flags & TIME_CRITICAL) || (req->flags & READ)) { ret = 1; } } else if (ioqueue->priority_mix == 2) { if (req->flags & TIME_CRITICAL) { ret = 2; } else if (req->flags & READ) { ret = 1; } } else if (ioqueue->priority_mix == 3) { if (req->flags & READ) { ret = 2; } else if (req->flags & TIME_CRITICAL) { ret = 1; } } else if (ioqueue->priority_mix == 4) { if (req->flags & TIME_CRITICAL) { ret = (req->flags & READ) ? 2 : 3; } else { ret = (req->flags & READ) ? 1 : 0; } } else if (ioqueue->priority_mix == 5) { if (req->flags & READ) { ret = 1; } } else if (ioqueue->priority_mix == 6) { if (req->flags & TIME_CRITICAL) { ret = 1; } } return(ret);}static iobuf * ioqueue_get_request_from_pri_lbn_vscan_queue (subqueue *queue, int numlbns, int vscan_value){ int schedalg; int priority_factor; int age_factor; iobuf *tmp; int curr_effpri = 0, best_effpri = 0; iobuf *ret = NULL; int i;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -