📄 disksim_diskctlr.c
字号:
// acctime = diskacctime(currdisk, // curr->tempptr1, // DISKACCTIME, // (curr->flags & READ), // simtime, // global_currcylno, // global_currsurface, // curr->cause, // 1, // 0); nsecs = currdisk->model->mech->dm_acctime(currdisk->model, &currdisk->mech_state, &pbn, 1, // len (curr->flags & READ), 0, // immed &currdisk->mech_state, 0); // breakdown acctime = dm_time_itod(nsecs); } curr->time = simtime + acctime; if(currdisk->stat.latency == (double) -1.0) { currdisk->stat.latency = (double) 0.0; currdisk->stat.xfertime = acctime - currdisk->stat.seektime; } else { currdisk->stat.xfertime += acctime; } if(((currdiskreq != seg->recyclereq) && disk_buffer_block_available(currdisk, seg, curr->blkno)) || ((curr->flags & READ) && (!currdisk->read_direct_to_buffer))) { curr->type = DEVICE_GOT_REMAPPED_SECTOR; } else { // get s/t for curr->blkno int st = currdisk->model->layout->dm_get_sectors_lbn(currdisk->model, curr->blkno); double rottime = currdisk->model->mech->dm_period(currdisk->model); // what is this? (appears again in disk_goto_remapped_sector) curr->time -= ((double) 1 / ((double)st * rottime)); curr->type = DEVICE_GOTO_REMAPPED_SECTOR; }} // disk_get_remapped_sector()static void disk_goto_remapped_sector (disk *currdisk, ioreq_event *curr){ double rotatetime = dm_time_itod(currdisk->model->mech->dm_period(currdisk->model)); diskreq *currdiskreq = currdisk->effectivehda; segment *seg; ddbg_assert2(currdiskreq != 0, "No effectivehda"); seg = currdiskreq->seg; if(seg->outstate == BUFFER_PREEMPT) { disk_release_hda(currdisk, currdiskreq); return; } if((currdiskreq != seg->recyclereq) && disk_buffer_block_available(currdisk, seg, curr->blkno)) { // XXX is curr->blkno the track we want?? int st = currdisk->model->layout->dm_get_sectors_lbn(currdisk->model, curr->blkno); double rottime = currdisk->model->mech->dm_period(currdisk->model); // what is this? curr->time += ((double) 1 / ((double)st * rottime)); curr->type = DEVICE_GOT_REMAPPED_SECTOR; } else { seg->time += rotatetime; currdisk->stat.xfertime += rotatetime; curr->time += rotatetime; curr->type = DEVICE_GOTO_REMAPPED_SECTOR; } addtointq((event *) curr);} // disk_goto_remapped_sector()static int disk_initiate_seek (disk *currdisk, segment *seg, ioreq_event *curr, int firstseek, double delay, double mintime){ struct dm_pbn destpbn; double seektime; int seekdist; int remapsector = 0; if(disk_printhack && (simtime >= disk_printhacktime)) { fprintf (outputfile, "%12.6f Entering disk_initiate_seek to %d for disk %d\n", simtime, curr->blkno, curr->devno); fflush(outputfile); } curr->type = NULL_EVENT; seg->time = simtime + delay; // remapsector = FALSE; // new ltop { uint64_t nsecs; struct dm_mech_state end; struct dm_mech_state begin = currdisk->mech_state; currdisk->model->layout->dm_translate_ltop(currdisk->model, curr->blkno, MAP_FULL, &destpbn, &remapsector); seekdist = abs(currdisk->mech_state.cyl - destpbn.cyl); end.cyl = destpbn.cyl; end.head = destpbn.head; end.theta = 0; curr->cause = destpbn.sector; // new acctime // seektime = diskacctime(currdisk, curr->tempptr1, DISKSEEKTIME, // (curr->flags & READ), seg->time, global_currcylno, // global_currsurface, curr->cause, curr->bcount, 0); nsecs = currdisk->model->mech->dm_seek_time(currdisk->model, &begin, &end, (curr->flags & READ)); seektime = dm_time_itod(nsecs); } if(seektime < mintime) { seg->time += mintime - seektime; } curr->time = seg->time + seektime; if((curr->flags & BUFFER_BACKGROUND) && (curr->flags & READ)) { if((currdisk->contread == BUFFER_READ_UNTIL_CYL_END) && (seekdist != 0)) { return FALSE; } if((currdisk->contread == BUFFER_READ_UNTIL_TRACK_END) && ((seekdist != 0) | (currdisk->mech_state.head != destpbn.head))) { return FALSE; } } if(firstseek) { currdisk->stat.seekdistance = seekdist; currdisk->stat.seektime = seektime; currdisk->stat.latency = (double) -1.0; currdisk->stat.xfertime = (double) -1.0; } else if(remapsector == 0) { currdisk->stat.xfertime += seektime; } curr->type = DEVICE_BUFFER_SEEKDONE; if(remapsector != 0) { disk_get_remapped_sector(currdisk, curr); } addtointq((event *) curr); /* fprintf (outputfile, "\nSeek from cyl %d head %d to cyl %d head %d, time %f\n", currdisk->currcylno, currdisk->currsurface, currcylno, currsurface, seektime); */ return TRUE;} // disk_initiate_seek()/* Attempt to start hda activity. * 1. If effectivehda already set, do nothing. * 2. If currdiskreq is NULL, attempt to find the appropriate next * request from the queue. */static voiddisk_get_effectivehda(disk *currdisk, diskreq *currdiskreq){ diskreq *nextdiskreq = currdiskreq; ioreq_event *nextioreq; // if we have a currenthda, make that the effectivehda if(currdisk->currenthda) { if(currdiskreq && (currdiskreq != currdisk->currenthda)) { fprintf(stderr, "currdiskreq != currenthda in disk_check_hda\n"); assert(0); } currdisk->effectivehda = currdisk->currenthda; } // ok. So no currenthda. Let's find a "next" io request (we'll // call it nextdiskreq) and make that the current/effective hda. else { if(nextdiskreq && nextdiskreq->ioreqlist) { nextioreq = ioreq_copy(nextdiskreq->ioreqlist); nextioreq->ioreq_hold_diskreq = nextdiskreq; nextioreq->ioreq_hold_disk = currdisk; if(!disk_enablement_function(nextioreq)) { nextdiskreq = NULL; } addtoextraq((event *)nextioreq); } // we don't have a nextdiskreq yet. check the disk's ioqueue for // one. if(!nextdiskreq) { nextioreq = ioqueue_show_next_request(currdisk->queue); if(nextioreq) { nextdiskreq = (diskreq*) nextioreq->ioreq_hold_diskreq; } } // if we don't have a nextdiskreq by now, we're going to fall out // of this without having figured out an effectivehda and bail // below if(nextdiskreq) { if(nextdiskreq->flags & HDA_OWNED) { fprintf(stderr, "disk_check_hda:" " diskreq was already HDA_OWNED\n"); assert(0); } // does this request have a disk cache segment associated with // it? if(nextdiskreq->seg && !(nextdiskreq->flags & SEG_OWNED) && (nextdiskreq->seg->recyclereq != nextdiskreq)) { disk_buffer_attempt_seg_ownership(currdisk, nextdiskreq); } if(!nextdiskreq->seg) { // hmmm ... no cache segment ... let's try to find one disk_buffer_select_segment(currdisk,nextdiskreq,FALSE); if(nextdiskreq->seg) { disk_buffer_set_segment(currdisk, nextdiskreq); disk_buffer_attempt_seg_ownership(currdisk, nextdiskreq); } else { // still no cache segment. try to "recycle" one. nextdiskreq->seg = disk_buffer_recyclable_segment(currdisk, (nextdiskreq->ioreqlist->flags & READ)); if(nextdiskreq->seg) { nextdiskreq->seg->recyclereq = nextdiskreq; } } // else { // nextdiskreq->seg == 0 } // if(!nextdiskreq->seg) // so if we succeeded in finding a cache segment above, // do something with the ioreqs on the nextdiskreq->ioreqlist. if(nextdiskreq->seg) { nextioreq = nextdiskreq->ioreqlist; while(nextioreq) { if(!ioqueue_get_specific_request(currdisk->queue, nextioreq)) { fprintf(stderr, "disk_get_effectivehda()" " ioreq_event not found by" " ioqueue_get_specific_request call\n"); assert(0); } nextioreq = nextioreq->next; } } // if(nextdiskreq->seg) // what if we didn't find a segment? currdisk->currenthda = currdisk->effectivehda = nextdiskreq; nextdiskreq->flags |= HDA_OWNED; } // if(nextdiskreq) } // else { // currdisk->currenthda == 0 if(disk_printhack && (simtime >= disk_printhacktime)) { fprintf (outputfile, " " "effectivehda = %8p\n", currdisk->effectivehda); fflush(outputfile); }} // disk_get_effectivehda()// handle the case for disk_check_hda when requests are pending// (i.e. not pure prefetch)static void disk_check_hda_pending(disk *currdisk, ioreq_event *nextioreq, diskreq *nextdiskreq, segment *seg, int ok_to_check_bus, double *mintime, int *immediate_release, int *initiate_seek) { nextioreq = nextdiskreq->ioreqlist; while (nextioreq->next) { nextioreq = nextioreq->next; } seg->access->flags = nextioreq->flags; // is the request a READ? if(nextioreq->flags & READ) { if(seg->access->type != NULL_EVENT) { /* * if((seg->access->blkno != seg->endblkno) && * (seg->access->blkno != (seg->endblkno + 1)) && * (seg->access->blkno != * currdisk->firstblkontrack)) { fprintf(stderr, * "non-NULL seg->access->type with incorrect * seg->access->blkno found for read segment in * disk_check_hda\n"); exit(1); } */ } else { // here's our bug ... we have some bogus seg that ends on // the 1-past-the-end-of-the-disk block and we try // to access it here seg->access->blkno = seg->endblkno; } if(!seg->recyclereq) { seg->minreadaheadblkno = max(seg->minreadaheadblkno, min((nextioreq->blkno + nextioreq->bcount + currdisk->minreadahead), currdisk->model->dm_sectors)); seg->maxreadaheadblkno = max(seg->maxreadaheadblkno, min(disk_buffer_get_max_readahead(currdisk,seg,nextioreq), currdisk->model->dm_sectors)); } currdisk->immed = currdisk->immedread; seg->state = BUFFER_READING; if(seg->recyclereq) { seg->access->blkno = nextdiskreq->outblkno; *initiate_seek = TRUE; } else if((seg->endblkno < (nextioreq->blkno + nextioreq->bcount)) || (seg->startblkno > nextdiskreq->outblkno)) { *initiate_seek = TRUE; } else if(seg->endblkno < max(seg->maxreadaheadblkno, disk_buffer_get_max_readahead(currdisk, seg, nextioreq))) { seg->access->flags |= BUFFER_BACKGROUND; if(currdisk->readaheadifidle) { /* Check for type != NULL_EVENT below negates this */ *initiate_seek = TRUE; } } // else if(seg->endblkno < ... else { *immediate_release = TRUE; } if(seg->access->type != NULL_EVENT) { if(*immediate_release) { fprintf(stderr,"CHECK: immediate_release reset!\n"); fflush(stderr); } *initiate_seek = FALSE; *immediate_release = FALSE; } // if(seg->access->type != NULL_EVENT) } // deal with a READ req // ... or is the request a WRITE? else { if(seg->access->type != NULL_EVENT) { fprintf(stderr, "non-NULL seg->access->type found" " for write segment in disk_check_hda\n"); assert(0); } /* prepare minimum seek time for seek if not sequential writes */ if((nextdiskreq->hittype != BUFFER_APPEND) || (seg->access->flags & READ) || (seg->access->blkno != nextdiskreq->ioreqlist->blkno) || (seg->access->bcount != 1) || (seg->access->time != simtime)) { *mintime = currdisk->minimum_seek_delay; } /* * else { fprintf(stderr,"Sequential write stream detected * at %f\n", simtime); } */ seg->access->blkno = nextdiskreq->inblkno; if(nextdiskreq->flags & COMPLETION_RECEIVED) { seg->access->flags |= BUFFER_BACKGROUND; } currdisk->immed = currdisk->immedwrite; if((seg->state != BUFFER_WRITING) && (seg->state != BUFFER_DIRTY)) { currdisk->numdirty++; if((disk_printhack > 1) && (simtime >= disk_printhacktime)) { fprintf (outputfile, " " "numdirty++ = %d\n",currdisk->numdirty); fflush(outputfile); } assert(currdisk->numdirty >= 0); assert(currdisk->numdirty <= currdisk->numwritesegs);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -