📄 disksim_bus.c
字号:
/* * 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 2typedef 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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -