📄 disksim_bus.c
字号:
* priority device arbitrates for the bus within the arbitration time, * it will win. Maybe this window is small enough to be ignored for * this level of simulation. * */int bus_ownership_get(int busno, int slotno, ioreq_event *curr){ bus_event *tmp; struct bus *currbus = getbus (busno); if (currbus->type == INTERLEAVED) { return(TRUE); } tmp = (bus_event *) getfromextraq(); tmp->type = BUS_OWNERSHIP_GRANTED; tmp->devno = currbus->slots[slotno].devno; tmp->busno = busno; tmp->delayed_event = curr; tmp->wait_start = simtime; if (currbus->state == BUS_FREE) { tmp->devtype = currbus->slots[slotno].devtype; tmp->time = simtime + currbus->arbtime;/*fprintf (outputfile, "Granting ownership immediately - devno %d, devtype %d, busno %d\n", tmp->devno, tmp->devtype, tmp->busno);*/ currbus->arbwinner = tmp; addtointq((event *) tmp); currbus->state = BUS_OWNED; currbus->runidletime += simtime - currbus->lastowned; stat_update (&currbus->busidlestats, (simtime - currbus->lastowned)); } else { tmp->slotno = slotno;/*fprintf (outputfile, "Must wait for bus to become free - devno %d, slotno %d, busno %d\n", tmp->devno, tmp->slotno, tmp->busno);*/ tmp->next = NULL; if (currbus->owners) { bus_event *tail = currbus->owners; while (tail->next) { tail = tail->next; } tail->next = tmp; } else { currbus->owners = tmp; } } return(FALSE);}void bus_ownership_release(int busno){ bus_event *tmp; struct bus *currbus = getbus(busno);/*fprintf (outputfile, "Bus ownership being released - %d\n", busno);*/ ASSERT(currbus->arbwinner == NULL); if (currbus->owners == NULL) {/*fprintf (outputfile, "Bus has become free - %d\n", busno);*/ currbus->state = BUS_FREE; currbus->lastowned = simtime; } else { tmp = bus_arbitrate_for_ownership(currbus); tmp->devtype = currbus->slots[tmp->slotno].devtype; tmp->time = simtime + currbus->arbtime;/*fprintf (outputfile, "Bus ownership transfered - devno %d, devtype %d, busno %d\n", tmp->devno, tmp->devtype, tmp->busno);*/ currbus->arbwinner = tmp; addtointq((event *) tmp); }}void bus_remove_from_arbitration(int busno, ioreq_event *curr){ bus_event *tmp; bus_event *trv; struct bus *currbus = getbus(busno); if (currbus->arbwinner) { if (curr == currbus->arbwinner->delayed_event) { if (removefromintq((event *)currbus->arbwinner) != TRUE) { fprintf(stderr, "Ongoing arbwinner not in internal queue, at bus_remove_from_arbitration\n"); exit(1); } addtoextraq((event *) currbus->arbwinner); currbus->arbwinner = NULL; bus_ownership_release(busno); return; } } if (curr == currbus->owners->delayed_event) { tmp = currbus->owners; currbus->owners = tmp->next; } else { trv = currbus->owners; while ((trv->next) && (curr != trv->next->delayed_event)) { trv = trv->next; } ASSERT(trv->next != NULL); tmp = trv->next; trv->next = tmp->next; } addtoextraq((event *) tmp);}void bus_deliver_event(int busno, int slotno, ioreq_event *curr){ int devno; struct bus *currbus = getbus(busno); ASSERT2((slotno >= 0) && (slotno < currbus->numslots), "slotno", slotno, "busno", busno);/*fprintf (outputfile, "In middle of bus_deliver_event\n");*/ devno = currbus->slots[slotno].devno; switch (currbus->slots[slotno].devtype) { case CONTROLLER: controller_event_arrive(devno, curr); break; case DEVICE: ASSERT(devno == curr->devno); device_event_arrive(curr); break; default: fprintf(stderr, "Invalid device type in bus slot\n"); assert(0); }}int bus_get_data_transfered(ioreq_event *curr, int depth){ intchar slotno; intchar busno; int checkdevno; int ret;/*fprintf (outputfile, "Entered bus_get_data_transfered - devno %d, depth %d, busno %x, slotno %x\n", curr->devno, depth, curr->busno, curr->slotno);*/ busno.value = curr->busno; slotno.value = curr->slotno; while (depth) { struct bus *currbus = getbus(busno.byte[depth]); checkdevno = currbus->slots[(slotno.byte[depth] >> 4)].devno; switch (currbus->slots[(slotno.byte[depth] >> 4)].devtype) { case CONTROLLER: ret = controller_get_data_transfered(checkdevno, curr->devno); break; default: fprintf(stderr, "Invalid device type in bus_get_data_transfered\n"); exit(1); } if (ret != -1) { return(ret); } depth--; } return(-1);}/* temporary global variables */static int disksim_bus_printidlestats;static int disksim_bus_printarbwaitstats;int disksim_bus_stats_loadparams(struct lp_block *b) { /* unparse_block(b, outputfile); */#include "modules/disksim_bus_stats_param.c" return 1;}void bus_resetstats(){ int i; for (i=0; i<numbuses; i++) { struct bus *currbus = getbus(i); currbus->lastowned = simtime; currbus->runidletime = 0.0; stat_reset (&currbus->busidlestats); stat_reset (&currbus->arbwaitstats); }}void bus_setcallbacks (){}void bus_initialize(){ int i; StaticAssert (sizeof(bus_event) <= DISKSIM_EVENT_SIZE); for (i=0; i<numbuses; i++) { struct bus *currbus = getbus(i); currbus->state = BUS_FREE; addlisttoextraq((event **) &currbus->owners); stat_initialize (statdeffile, "Arbitration wait time", &currbus->arbwaitstats); stat_initialize (statdeffile, "Bus idle period length", &currbus->busidlestats); } bus_resetstats();}void bus_printstats(){ int i; char prefix[81]; fprintf (outputfile, "\nBUS STATISTICS\n"); fprintf (outputfile, "--------------\n\n"); for (i=0; i < disksim->businfo->buses_len; i++) { struct bus *currbus = getbus(i); if(!currbus) continue; if (currbus->printstats) { sprintf (prefix, "Bus #%d (%s) ", i, currbus->name); fprintf (outputfile, "Bus #%d\n", i); fprintf (outputfile, "Bus #%d Total utilization time: \t%.2f \t%6.5f\n", i, (simtime - warmuptime - currbus->runidletime), ((simtime - warmuptime - currbus->runidletime) / (simtime - warmuptime))); if (disksim->businfo->bus_printidlestats) { stat_print (&currbus->busidlestats, prefix); } if (disksim->businfo->bus_printarbwaitstats) { fprintf (outputfile, "Bus #%d Number of arbitrations: \t%d\n", i, stat_get_count (&currbus->arbwaitstats)); stat_print (&currbus->arbwaitstats, prefix); } fprintf (outputfile, "\n"); } }}void bus_cleanstats(){ int i; for (i=0; i<numbuses; i++) { struct bus *currbus = getbus(i); if (currbus->state == BUS_FREE) { currbus->runidletime += simtime - currbus->lastowned; stat_update (&currbus->busidlestats, (simtime - currbus->lastowned)); } }}bus *bus_copy(bus *orig) { bus *result = malloc(sizeof(bus)); if(result) return memcpy(result, orig, sizeof(bus)); else return 0;}/* bus constructor using new parser. Returns null on failure * or a pointer to an allocated/initialized bus struct on success * if parent is non-null, it will be copied and the new structure * initialized from it, i.e. you only need to provide parameters in * b that you want to override from parent */bus *disksim_bus_loadparams(struct lp_block *b, int *num){ struct bus *result; int c; if(!disksim->businfo) { disksim->businfo = malloc(sizeof(businfo_t)); bzero(disksim->businfo, sizeof(businfo_t)); } disksim->businfo->bus_printidlestats = disksim_bus_printidlestats; disksim->businfo->bus_printarbwaitstats = disksim_bus_printarbwaitstats; for(c = 0; c < numbuses; c++) { if(!disksim->businfo->buses[c]) { break; } } /* didn't find a free slot */ if(c == disksim->businfo->buses_len) { int newlen = c ? 2*c : 2; disksim->businfo->buses = realloc(disksim->businfo->buses, newlen * sizeof(int*)); if(newlen > 2) bzero(disksim->businfo->buses + c, (newlen/2)*sizeof(int *)); else bzero(disksim->businfo->buses, 2 * sizeof(int *)); disksim->businfo->buses_len = newlen; } result = malloc(sizeof(struct bus)); if(!result) { return 0; } numbuses++; disksim->businfo->buses[c] = result; bzero(result, sizeof(struct bus)); if(num) *num = c; result->name = strdup(b->name);#include "modules/disksim_bus_param.c" result->owners = NULL; result->depth = -1; return result;}int load_bus_topo(struct lp_topospec *t, int *parentctlno) { int c, d; struct bus *b; struct lp_topospec *ts = 0; int busno; int slotnum = 0; assert(!strcmp(t->type, disksim_mods[DISKSIM_MOD_BUS]->name)); /* lookup bus */ assert(b = getbusbyname(t->name, &busno)); b->numslots = 0; for(c = 0; c < t->l->values_len; c++) if(!t->l->values[c]) continue; /* else if(t->l->values[c]->t != TOPOSPEC) b->numslots++; */ else for(d = 0; d < t->l->values[c]->v.t.len; d++) if(t->l->values[c]->v.t.l[d].name || t->l->values[c]->v.t.l[d].l) b->numslots++; /* if this bus is the child of a controller */ if(parentctlno) { b->numslots++; } b->slots = malloc(b->numslots * sizeof(slot)); bzero(b->slots, b->numslots * sizeof(slot)); if(parentctlno) { b->slots[0].devtype = CONTROLLER; b->slots[0].devno = *parentctlno; slotnum = 1; } for(c = 0; c < t->l->values_len; c++) { if(!t->l->values[c]) continue; /* t->l->values[c] should be a topospec */ if(t->l->values[c]->t != TOPOSPEC) { fprintf(stderr, "*** error loading topology spec -- bad child device spec.\n"); return 0; } for(d = 0; d < t->l->values[c]->v.t.len; d++) { ts = &t->l->values[c]->v.t.l[d]; if(!ts->type) continue; } /* determine type */ switch(lp_mod_name(ts->type)) { case DISKSIM_MOD_CTLR: b->slots[slotnum].devtype = CONTROLLER; if(!getctlrbyname(ts->name, &b->slots[slotnum].devno)) { fprintf(stderr, "*** error: failed to load controller \"%s\" into slot %d of bus %s: no such controller \"%s\".\n", ts->name, c, t->name, ts->name); return 0; } if(!load_ctlr_topo(ts, &busno)) { fprintf(stderr, "*** error: failed to load controller topology spec for bus %s slot %d\n", t->name, c); return 0; } break; case DISKSIM_MOD_DISK: case DISKSIM_MOD_SIMPLEDISK: b->slots[slotnum].devtype = DEVICE; if(!getdevbyname(ts->name, &b->slots[slotnum].devno, 0, 0)) { fprintf(stderr, "*** error: failed to load device \"%s\" into slot %d of bus %s: no such device \"%s\".\n", ts->name, c, t->name, ts->name); return 0; } break; default: fprintf(stderr, "Error loading topology spec -- slot must contain a device or a controller (not %s).\n", ts->type); return 0; break; } /* eventually want to add pointer to device here to avoid table * lookups elsewhere */ slotnum++; } return 1; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -