1 Star 0 Fork 1

wjh731/disksim_original

forked from 颜明博/disksim_original 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
disksim_bus.c 23.97 KB
一键复制 编辑 原始数据 按行查看 历史
颜明博 提交于 2018-06-25 19:31 . first commit
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849
/*
* DiskSim Storage Subsystem Simulation Environment (Version 3.0)
* Revision Authors: John Bucy, Greg Ganger
* Contributors: John Griffin, Jiri Schindler, Steve Schlosser
*
* Copyright (c) of Carnegie Mellon University, 2001, 2002, 2003.
*
* This software is being provided by the copyright holders under the
* following license. By obtaining, using and/or copying this software,
* you agree that you have read, understood, and will comply with the
* following terms and conditions:
*
* Permission to reproduce, use, and prepare derivative works of this
* software is granted provided the copyright and "No Warranty" statements
* are included with all reproductions and derivative works and associated
* documentation. This software may also be redistributed without charge
* provided that the copyright and "No Warranty" statements are included
* in all redistributions.
*
* NO WARRANTY. THIS SOFTWARE IS FURNISHED ON AN "AS IS" BASIS.
* CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY KIND, EITHER
* EXPRESSED OR IMPLIED AS TO THE MATTER INCLUDING, BUT NOT LIMITED
* TO: WARRANTY OF FITNESS FOR PURPOSE OR MERCHANTABILITY, EXCLUSIVITY
* OF RESULTS OR RESULTS OBTAINED FROM USE OF THIS SOFTWARE. CARNEGIE
* MELLON UNIVERSITY DOES NOT MAKE ANY WARRANTY OF ANY KIND WITH RESPECT
* TO FREEDOM FROM PATENT, TRADEMARK, OR COPYRIGHT INFRINGEMENT.
* COPYRIGHT HOLDERS WILL BEAR NO LIABILITY FOR ANY USE OF THIS SOFTWARE
* OR DOCUMENTATION.
*
*/
/*
* DiskSim Storage Subsystem Simulation Environment (Version 2.0)
* Revision Authors: Greg Ganger
* Contributors: Ross Cohen, John Griffin, Steve Schlosser
*
* Copyright (c) of Carnegie Mellon University, 1999.
*
* Permission to reproduce, use, and prepare derivative works of
* this software for internal use is granted provided the copyright
* and "No Warranty" statements are included with all reproductions
* and derivative works. This software may also be redistributed
* without charge provided that the copyright and "No Warranty"
* statements are included in all redistributions.
*
* NO WARRANTY. THIS SOFTWARE IS FURNISHED ON AN "AS IS" BASIS.
* CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY KIND, EITHER
* EXPRESSED OR IMPLIED AS TO THE MATTER INCLUDING, BUT NOT LIMITED
* TO: WARRANTY OF FITNESS FOR PURPOSE OR MERCHANTABILITY, EXCLUSIVITY
* OF RESULTS OR RESULTS OBTAINED FROM USE OF THIS SOFTWARE. CARNEGIE
* MELLON UNIVERSITY DOES NOT MAKE ANY WARRANTY OF ANY KIND WITH RESPECT
* TO FREEDOM FROM PATENT, TRADEMARK, OR COPYRIGHT INFRINGEMENT.
*/
/*
* DiskSim Storage Subsystem Simulation Environment
* Authors: Greg Ganger, Bruce Worthington, Yale Patt
*
* Copyright (C) 1993, 1995, 1997 The Regents of the University of Michigan
*
* This software is being provided by the copyright holders under the
* following license. By obtaining, using and/or copying this software,
* you agree that you have read, understood, and will comply with the
* following terms and conditions:
*
* Permission to use, copy, modify, distribute, and sell this software
* and its documentation for any purpose and without fee or royalty is
* hereby granted, provided that the full text of this NOTICE appears on
* ALL copies of the software and documentation or portions thereof,
* including modifications, that you make.
*
* THIS SOFTWARE IS PROVIDED "AS IS," AND COPYRIGHT HOLDERS MAKE NO
* REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED. BY WAY OF EXAMPLE,
* BUT NOT LIMITATION, COPYRIGHT HOLDERS MAKE NO REPRESENTATIONS OR
* WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR
* THAT THE USE OF THE SOFTWARE OR DOCUMENTATION WILL NOT INFRINGE ANY
* THIRD PARTY PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS. COPYRIGHT
* HOLDERS WILL BEAR NO LIABILITY FOR ANY USE OF THIS SOFTWARE OR
* DOCUMENTATION.
*
* This software is provided AS IS, WITHOUT REPRESENTATION FROM THE
* UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY PURPOSE, AND
* WITHOUT WARRANTY BY THE UNIVERSITY OF MICHIGAN OF ANY KIND, EITHER
* EXPRESSED OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE REGENTS
* OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE FOR ANY DAMAGES,
* INCLUDING SPECIAL , INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES,
* WITH RESPECT TO ANY CLAIM ARISING OUT OF OR IN CONNECTION WITH THE
* USE OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN IF IT HAS
* BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
*
* The names and trademarks of copyright holders or authors may NOT be
* used in advertising or publicity pertaining to the software without
* specific, written prior permission. Title to copyright in this software
* and any associated documentation will at all times remain with copyright
* holders.
*/
#include "disksim_global.h"
#include "disksim_iosim.h"
#include "disksim_stat.h"
#include "disksim_bus.h"
#include "disksim_ctlr.h"
#include "disksim_controller.h"
#include "config.h"
#include "modules/disksim_bus_param.h"
#include "disksim_device.h"
/* Bus types */
#define BUS_TYPE_MIN 1
#define EXCLUSIVE 1
#define INTERLEAVED 2
#define BUS_TYPE_MAX 2
/* Bus arbitration types */
#define BUS_ARB_TYPE_MIN 1
#define SLOTPRIORITY_ARB 1
#define FIFO_ARB 2
#define BUS_ARB_TYPE_MAX 2
/* Bus states */
#define BUS_FREE 1
#define BUS_OWNED 2
typedef struct {
int devtype;
int devno;
/* eventually want to add pointer to device here to avoid table
lookups */
} slot;
typedef struct bus_ev {
double time;
int type;
struct bus_ev *next;
struct bus_ev *prev;
int devno;
int devtype;
int busno;
int slotno;
ioreq_event *delayed_event;
double wait_start;
} bus_event;
typedef struct bus {
int state;
int type;
int arbtype;
bus_event *owners;
double arbtime;
double readblktranstime;
double writeblktranstime;
bus_event *arbwinner;
int printstats;
int depth;
int numslots;
slot *slots;
double lastowned;
double runidletime;
statgen arbwaitstats;
statgen busidlestats;
char *name;
} bus;
typedef struct businfo {
struct bus **buses;
int buses_len; /* allocated size of buses array */
int numbuses;
int bus_printidlestats;
int bus_printarbwaitstats;
} businfo_t;
#define numbuses (disksim->businfo->numbuses)
/* INLINE */ static struct bus * getbus (int busno)
{
/* ASSERT1((busno >= 0) && (busno < numbuses), "busno",busno); */
if((busno < 0) || (busno >= numbuses)) {
return 0;
}
else {
return disksim->businfo->buses[busno];
}
}
struct bus *getbusbyname(char *name, int *num) {
int c;
for(c = 0; c < numbuses; c++) {
if(disksim->businfo->buses[c])
if(!strcmp(disksim->businfo->buses[c]->name, name)) {
if(num) *num = c;
return disksim->businfo->buses[c];
}
}
return 0;
}
void bus_set_to_zero_depth (int busno)
{
struct bus *currbus = getbus(busno);
currbus->depth = 0;
}
int bus_get_controller_slot (int busno, int ctlno)
{
int i;
struct bus *currbus = getbus (busno);
for (i = 0; i < currbus->numslots; i++) {
if ((currbus->slots[i].devno == ctlno) && (currbus->slots[i].devtype == CONTROLLER)) {
/* slotno = i; */
/* break; */
return i;
}
}
fprintf(stderr, "Controller not connected to bus but called bus_get_controller_slot: %d %d\n", ctlno, busno);
exit(1);
}
void bus_set_depths()
{
int depth;
int busno;
int slotno;
intchar ret;
int i;
u_int devno;
for (depth = 0; depth < MAXDEPTH; depth++) {
/* fprintf (outputfile, "At depth %d\n", depth); */
for (busno = 0; busno < numbuses; busno++) {
struct bus *currbus = getbus(busno);
/* fprintf (outputfile, "At busno %d\n", busno); */
if (currbus->depth == depth) {
/* fprintf (outputfile, "Busno %d is at this depth - %d\n", busno, depth); */
for (slotno = 0; slotno < currbus->numslots; slotno++) {
/* fprintf (outputfile, "Deal with slotno %d of busno %d\n", slotno, busno); */
devno = currbus->slots[slotno].devno;
switch (currbus->slots[slotno].devtype) {
case CONTROLLER:
/* fprintf (outputfile, "Slotno %d contains controller number %d\n", slotno, devno); */
ret.value = controller_set_depth(devno, busno, depth, slotno);
break;
case DEVICE:
/* fprintf (outputfile, "Slotno %d contains disk number %d\n", slotno, devno); */
ret.value = device_set_depth(devno, busno, depth, slotno);
break;
default: fprintf(stderr, "Invalid device type in bus slot\n");
exit(1);
}
/* fprintf (outputfile, "Back from setting device depth\n"); */
if (ret.value != 0) {
/* fprintf (outputfile, "Non-zero return - %x\n", ret.value); */
for (i = 0; i < MAXDEPTH; i++) {
if (ret.byte[i] != 0) {
struct bus *currbus2 = getbus(ret.byte[i]);
/* fprintf (outputfile, "Set busno %x to have depth %d\n", ret.byte[i], (depth+1));*/
currbus2->depth = depth + 1;
}
}
}
}
}
}
}
}
double bus_get_transfer_time(int busno, int bcount, int read)
{
double blktranstime;
struct bus *currbus = getbus(busno);
blktranstime = (read) ? currbus->readblktranstime : currbus->writeblktranstime;
return((double) bcount * blktranstime);
}
/*
**-bus_delay
Adds a BUS_DELAY_COMPLETE event to the intq.
*/
void bus_delay(int busno, int devtype, int devno, double delay, ioreq_event *curr)
{
bus_event *tmp = (bus_event *) getfromextraq();
tmp->type = BUS_DELAY_COMPLETE;
tmp->time = simtime + delay;
tmp->devno = devno;
tmp->busno = busno;
tmp->devtype = devtype;
tmp->delayed_event = curr;
addtointq((event *) tmp);
}
void bus_event_arrive(ioreq_event *ptr)
{
bus_event *curr = (bus_event *) ptr;
if (curr->type == BUS_OWNERSHIP_GRANTED) {
struct bus *currbus = getbus(curr->busno);
ASSERT(curr == currbus->arbwinner);
currbus->arbwinner = NULL;
stat_update (&currbus->arbwaitstats, (simtime - curr->wait_start));
}
switch (curr->devtype) {
case CONTROLLER:
if (curr->type == BUS_DELAY_COMPLETE) {
controller_bus_delay_complete (curr->devno, curr->delayed_event, curr->busno);
} else {
controller_bus_ownership_grant (curr->devno, curr->delayed_event, curr->busno, (simtime - curr->wait_start));
}
break;
case DEVICE:
if (curr->type == BUS_DELAY_COMPLETE) {
device_bus_delay_complete (curr->devno, curr->delayed_event, curr->busno);
} else {
device_bus_ownership_grant (curr->devno, curr->delayed_event, curr->busno, (simtime - curr->wait_start));
}
break;
default:
fprintf(stderr, "Unknown device type at bus_event_arrive: %d, type %d\n", curr->devtype, curr->type);
exit(1);
}
addtoextraq((event *)curr);
}
static bus_event * bus_fifo_arbitration(bus *currbus)
{
bus_event *ret = currbus->owners;
ASSERT(currbus->owners != NULL);
currbus->owners = ret->next;
return(ret);
}
static bus_event * bus_slotpriority_arbitration(bus *currbus)
{
bus_event *ret = currbus->owners;
ASSERT(currbus->owners != NULL);
if (currbus->owners->next == NULL) {
currbus->owners = NULL;
return(ret);
} else {
bus_event *trv = ret;
while (trv->next) {
if (trv->next->slotno > ret->slotno) {
ret = trv->next;
}
trv = trv->next;
}
if (ret == currbus->owners) {
currbus->owners = ret->next;
ret->next = NULL;
} else {
trv = currbus->owners;
while ((trv->next != NULL) && (trv->next != ret)) {
trv = trv->next;
}
ASSERT(trv->next == ret);
trv->next = ret->next;
ret->next = NULL;
}
}
return(ret);
}
static bus_event * bus_arbitrate_for_ownership(bus *currbus)
{
switch (currbus->arbtype) {
case SLOTPRIORITY_ARB:
return(bus_slotpriority_arbitration(currbus));
case FIFO_ARB:
return(bus_fifo_arbitration(currbus));
default:
fprintf(stderr, "Unrecognized bus arbitration type in bus_arbitrate_for_ownership\n");
exit(1);
}
}
/*
* int bus_ownership_get(int busno, int slotno, ioreq_event *curr)
*
* Returns TRUE if the bus is immediately acquired, which only happens
* for an interleaved bus. In this case, this function does nothing
* else.
*
* Returns FALSE if there is a delay (always true with SCSI). A
* bus_event of type BUS_OWNERSHIP_GRANTED for this request is created.
* If the bus is initially BUS_BUSY, the event is added to the
* buses.owners queue If the bus is initially BUS_FREE, its state is
* changed to BUS_BUSY and is granted to this request. (I think:
* buses.arbwinner is set to this event). The event is scheduled on
* the intq for the current time plus buses.arbtime.
*
* Note that I don't think this really how SCSI works: If a higher
* 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:
case DISKSIM_MOD_SIMPLEFLASH:
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;
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/wjh731/disksim_original.git
git@gitee.com:wjh731/disksim_original.git
wjh731
disksim_original
disksim_original
master

搜索帮助