static void simpledisk_request_arrive (ioreq_event *curr) { ioreq_event *intrp; simpledisk_t *currdisk; #ifdef DEBUG_SIMPLEDISK fprintf (outputfile, "*** %f: simpledisk_request_arrive - devno %d, blkno %d, bcount %d, flags 0x%x\n", simtime, curr->devno, curr->blkno, curr->bcount, curr->flags ); #endif currdisk = getsimpledisk(curr->devno); /* verify that request is valid. */ if ((curr->blkno < 0) || (curr->bcount <= 0) || ((curr->blkno + curr->bcount) > currdisk->numblocks)) { fprintf(stderr, "Invalid set of blocks requested from simpledisk - blkno %lld, bcount %d, numblocks %lld\n", curr->blkno, curr->bcount, currdisk->numblocks); exit(1); } /* create a new request, set it up for initial interrupt */ currdisk->busowned = simpledisk_get_busno(curr); if (ioqueue_get_reqoutstanding (currdisk->queue) == 0) { ioqueue_add_new_request(currdisk->queue, curr); curr = ioqueue_get_next_request (currdisk->queue); intrp = curr; /* initiate media access if request is a READ */ if (curr->flags & READ) { ioreq_event *tmp = ioreq_copy (curr); currdisk->media_busy = TRUE; stat_update (&currdisk->stat.acctimestats, currdisk->acctime); tmp->time = simtime + currdisk->acctime; tmp->type = DEVICE_ACCESS_COMPLETE; addtointq ((event *)tmp); } /* if not disconnecting, then the READY_TO_TRANSFER is like a RECONNECT */ currdisk->reconnect_reason = IO_INTERRUPT_ARRIVE; if (curr->flags & READ) { intrp->cause = (currdisk->neverdisconnect) ? READY_TO_TRANSFER : DISCONNECT; } else { intrp->cause = READY_TO_TRANSFER; } } else { intrp = ioreq_copy(curr); ioqueue_add_new_request(currdisk->queue, curr); intrp->cause = DISCONNECT; } intrp->type = IO_INTERRUPT_ARRIVE; simpledisk_send_event_up_path(intrp, currdisk->bus_transaction_latency); }
static ioreq_event * handle_new_request (iodriver *curriodriver, ioreq_event *curr) { struct ioq *queue = curriodriver->devices[(curr->devno)].queue; ioreq_event *ret = NULL; /* fprintf(outputfile, "\n*** handle_new_request:: time %f, devno %d, blkno %d, bcount %d\n\n", simtime, curr->devno, curr->blkno, curr->bcount); fprintf(outputfile, "handle_new_request:: calling ioqueue_add_new_request\n"); */ ioqueue_add_new_request(queue, curr); if (check_send_out_request(curriodriver, curr->devno)) { /* fprintf(outputfile, "handle_new_request:: calling ioqueue_get_next_request\n"); */ ret = ioqueue_get_next_request(queue); if (ret != NULL) { schedule_disk_access(curriodriver, ret); ret->time = IODRIVER_IMMEDSCHED_TIME * curriodriver->scale; } } return(ret); }
static void ssd_media_access_request_element (ioreq_event *curr) { ssd_t *currdisk = getssd(curr->devno); int blkno = curr->blkno; int count = curr->bcount; /* **** CAREFUL ... HIJACKING tempint2 and tempptr2 fields here **** */ curr->tempint2 = count; while (count != 0) { // find the element (package) to direct the request int elem_num = currdisk->timing_t->choose_element(currdisk->timing_t, blkno); ssd_element *elem = &currdisk->elements[elem_num]; // create a new sub-request for the element ioreq_event *tmp = (ioreq_event *)getfromextraq(); tmp->devno = curr->devno; tmp->busno = curr->busno; tmp->flags = curr->flags; tmp->blkno = blkno; tmp->bcount = ssd_choose_aligned_count(currdisk->params.page_size, blkno, count); ASSERT(tmp->bcount == currdisk->params.page_size); tmp->tempptr2 = curr; blkno += tmp->bcount; count -= tmp->bcount; elem->metadata.reqs_waiting ++; // add the request to the corresponding element's queue ioqueue_add_new_request(elem->queue, (ioreq_event *)tmp); ssd_activate_elem(currdisk, elem_num); } }
static void ssd_request_arrive (ioreq_event *curr) { ssd_t *currdisk; // fprintf (outputfile, "Entering ssd_request_arrive: %12.6f\n", simtime); // fprintf (outputfile, "ssd = %d, blkno = %d, bcount = %d, read = %d\n",curr->devno, curr->blkno, curr->bcount, (READ & curr->flags)); currdisk = getssd(curr->devno); // verify that request is valid. if ((curr->blkno < 0) || (curr->bcount <= 0) || ((curr->blkno + curr->bcount) > currdisk->numblocks)) { fprintf(outputfile3, "Invalid set of blocks requested from ssd - blkno %d, bcount %d, numblocks %d\n", curr->blkno, curr->bcount, currdisk->numblocks); exit(1); } /* create a new request, set it up for initial interrupt */ ioqueue_add_new_request(currdisk->queue, curr); if (currdisk->channel_activity == NULL) { curr = ioqueue_get_next_request(currdisk->queue); currdisk->busowned = ssd_get_busno(curr); currdisk->channel_activity = curr; currdisk->reconnect_reason = IO_INTERRUPT_ARRIVE; if (curr->flags & READ) { ssd_media_access_request (curr); ssd_check_channel_activity(currdisk); } else { curr->cause = READY_TO_TRANSFER; curr->type = IO_INTERRUPT_ARRIVE; ssd_send_event_up_path(curr, currdisk->bus_transaction_latency); } } }
static void controller_smart_issue_access (void *issuefuncparam, ioreq_event *curr) { controller *currctlr = issuefuncparam; struct ioq *queue = currctlr->devices[curr->devno].queue; int numout = ioqueue_get_reqoutstanding(queue); /* in case the cache changes to which device the request is sent */ //fprintf (stderr, "busno %x, buspath %x, slotno %x, slotpath %x\n", curr->busno, currctlr->devices[curr->devno].buspath.value, curr->slotno, currctlr->devices[curr->devno].slotpath.value); curr->busno = currctlr->devices[curr->devno].buspath.value; curr->slotno = currctlr->devices[curr->devno].slotpath.value; ioqueue_add_new_request(queue, curr); if (numout < currctlr->devices[curr->devno].maxoutstanding) { ioreq_event *sched = ioqueue_get_next_request(queue); controller_send_event_down_path(currctlr, sched, currctlr->ovrhd_disk_request); } }
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 %lld, cause %d\n", simtime, curr->devno, curr->blkno, curr->cause); fprintf (outputfile, "Entered iodriver_request - simtime %f, devno %d, blkno %lld, cause %d\n", simtime, curr->devno, curr->blkno, curr->cause); fprintf (stderr, "Entered iodriver_request - simtime %f, devno %d, blkno %lld, cause %d\n", simtime, curr->devno, curr->blkno, curr->cause); */ if (NULL != OUTIOS) { fprintf(OUTIOS, "%.6f,%d,%lld,%d,%x,%d,%p\n", simtime, curr->devno, curr->blkno, curr->bcount, curr->flags, OVERALLQUEUE->base.listlen + 1, curr ); fflush( OUTIOS ); } #if 0 fprintf (stderr, "Entered iodriver_request - simtime %f, devno %d, blkno %lld, 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); }
static void ssd_media_access_request_element (ioreq_event *curr) { ssd_t *currdisk = getssd(curr->devno); int blkno = curr->blkno; int count = curr->bcount; //added by tiel int i = 0; double max_threshold = currdisk->params.nelements * currdisk->params.page_size; /* **** CAREFUL ... HIJACKING tempint2 and tempptr2 fields here **** */ curr->tempint2 = count; //while (count != 0) { while (count > 0) { // find the element (package) to direct the request int elem_num = ssd_choose_element(currdisk->user_params, blkno); ssd_element *elem = &currdisk->elements[elem_num]; // create a new sub-request for the element ioreq_event *tmp = (ioreq_event *)getfromextraq(); tmp->devno = curr->devno; tmp->busno = curr->busno; tmp->flags = curr->flags; tmp->blkno = blkno; tmp->bcount = ssd_choose_aligned_count(currdisk->params.page_size, blkno, count); /*if(curr->bcount > max_threshold) tmp->tempint1 = 1;*/ //ASSERT(tmp->bcount == currdisk->params.page_size); tmp->tempptr2 = curr; blkno += tmp->bcount; count -= tmp->bcount; elem->metadata.reqs_waiting ++; // add the request to the corresponding element's queue ioqueue_add_new_request(elem->queue, (ioreq_event *)tmp); // added by tiel // activate request create simtime, type, elem_num { int ch_num; double wtime, ctime; ioreq_event *temp = (ioreq_event *)getfromextraq(); temp->type = SSD_ACTIVATE_ELEM; //Insert Channel/Way delay //Channel Number = Chip number % Number of Channel ch_num = elem_num % currdisk->params.nchannel; wtime = currdisk->CH[ch_num].arrival_time + ssd_data_transfer_cost(currdisk,currdisk->params.page_size); ctime = simtime + (i * currdisk->params.channel_switch_delay); if(currdisk->params.nchannel == currdisk->params.nelements){ temp->time = ctime; currdisk->CH[ch_num].ccount++; }else if(simtime > wtime || currdisk->CH[ch_num].flag == -1){ //channel data setting currdisk->CH[ch_num].arrival_time = ctime; currdisk->CH[ch_num].flag = curr->flags; temp->time = ctime; currdisk->CH[ch_num].ccount++; }else if(currdisk->CH[ch_num].flag ==READ){ if(wtime > ctime){ if(curr->flags == READ){ temp->time = wtime; }else{ temp->time = wtime + currdisk->params.page_read_latency; } currdisk->CH[ch_num].wcount++; }else{ temp->time = ctime; currdisk->CH[ch_num].ccount++; } currdisk->CH[ch_num].arrival_time = temp->time; currdisk->CH[ch_num].flag = curr->flags; }else if(currdisk->CH[ch_num].flag == WRITE){ if(wtime > ctime){ temp->time = wtime; currdisk->CH[ch_num].wcount++; }else{ temp->time = ctime; currdisk->CH[ch_num].ccount++; } currdisk->CH[ch_num].arrival_time = temp->time; currdisk->CH[ch_num].flag = curr->flags; } temp->ssd_elem_num = elem_num; addtointq ((event *)temp); i ++; } } }