⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 disksim_ioqueue.c

📁 目前最精确的磁盘模拟器的第3版
💻 C
📖 第 1 页 / 共 5 页
字号:
         *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 + -