📄 disksim_simpledisk.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_simpledisk.h"#include "disksim_ioqueue.h"#include "disksim_bus.h"#include "config.h"#include "modules/disksim_simpledisk_param.h"/* read-only globals used during readparams phase */static char *statdesc_acctimestats = "Access time";typedef struct { statgen acctimestats; double requestedbus; double waitingforbus; int numbuswaits;} simpledisk_stat_t;typedef struct simpledisk { struct device_header hdr; double acctime; double overhead; double bus_transaction_latency; int numblocks; int devno; int inited; struct ioq *queue; int media_busy; int reconnect_reason; double blktranstime; int maxqlen; int busowned; ioreq_event *buswait; int neverdisconnect; int numinbuses; int inbuses[MAXINBUSES]; int depth[MAXINBUSES]; int slotno[MAXINBUSES]; int printstats; simpledisk_stat_t stat;} simpledisk_t;typedef struct simpledisk_info { struct simpledisk **simpledisks; int numsimpledisks; int simpledisks_len; /* allocated size of simpledisks */} simplediskinfo_t;/* private remapping #defines for variables from device_info_t */#define numsimpledisks (disksim->simplediskinfo->numsimpledisks)//#define simpledisks (disksim->simplediskinfo->simpledisks)struct simpledisk *getsimpledisk (int devno){ ASSERT1((devno >= 0) && (devno < MAXDEVICES), "devno", devno); return (disksim->simplediskinfo->simpledisks[devno]);}int simpledisk_set_depth (int devno, int inbusno, int depth, int slotno){ simpledisk_t *currdisk; int cnt; currdisk = getsimpledisk (devno); assert(currdisk); cnt = currdisk->numinbuses; currdisk->numinbuses++; if ((cnt + 1) > MAXINBUSES) { fprintf(stderr, "Too many inbuses specified for simpledisk %d - %d\n", devno, (cnt+1)); exit(1); } currdisk->inbuses[cnt] = inbusno; currdisk->depth[cnt] = depth; currdisk->slotno[cnt] = slotno; return(0);}int simpledisk_get_depth (int devno){ simpledisk_t *currdisk; currdisk = getsimpledisk (devno); return(currdisk->depth[0]);}int simpledisk_get_slotno (int devno){ simpledisk_t *currdisk; currdisk = getsimpledisk (devno); return(currdisk->slotno[0]);}int simpledisk_get_inbus (int devno){ simpledisk_t *currdisk; currdisk = getsimpledisk (devno); return(currdisk->inbuses[0]);}int simpledisk_get_maxoutstanding (int devno){ simpledisk_t *currdisk; currdisk = getsimpledisk (devno); return(currdisk->maxqlen);}double simpledisk_get_blktranstime (ioreq_event *curr){ simpledisk_t *currdisk; double tmptime; currdisk = getsimpledisk (curr->devno); tmptime = bus_get_transfer_time(simpledisk_get_busno(curr), 1, (curr->flags & READ)); if (tmptime < currdisk->blktranstime) { tmptime = currdisk->blktranstime; } return(tmptime);}int simpledisk_get_busno (ioreq_event *curr){ simpledisk_t *currdisk; intchar busno; int depth; currdisk = getsimpledisk (curr->devno); busno.value = curr->busno; depth = currdisk->depth[0]; return(busno.byte[depth]);}/* * simpledisk_send_event_up_path() * * Acquires the bus (if not already acquired), then uses bus_delay to * send the event up the path. * * If the bus is already owned by this device or can be acquired * immediately (interleaved bus), the event is sent immediately. * Otherwise, disk_bus_ownership_grant will later send the event. */ static void simpledisk_send_event_up_path (ioreq_event *curr, double delay){ simpledisk_t *currdisk; int busno; int slotno; // fprintf (outputfile, "simpledisk_send_event_up_path - devno %d, type %d, cause %d, blkno %d\n", curr->devno, curr->type, curr->cause, curr->blkno); currdisk = getsimpledisk (curr->devno); busno = simpledisk_get_busno(curr); slotno = currdisk->slotno[0]; /* Put new request at head of buswait queue */ curr->next = currdisk->buswait; currdisk->buswait = curr; curr->tempint1 = busno; curr->time = delay; if (currdisk->busowned == -1) { // fprintf (outputfile, "Must get ownership of the bus first\n"); if (curr->next) { //fprintf(stderr,"Multiple bus requestors detected in disk_send_event_up_path\n"); /* This should be ok -- counting on the bus module to sequence 'em */ } if (bus_ownership_get(busno, slotno, curr) == FALSE) { /* Remember when we started waiting (only place this is written) */ currdisk->stat.requestedbus = simtime; } else { bus_delay(busno, DEVICE, curr->devno, delay, curr); /* Never for SCSI */ } } else if (currdisk->busowned == busno) { //fprintf (outputfile, "Already own bus - so send it on up\n"); bus_delay(busno, DEVICE, curr->devno, delay, curr); } else { fprintf(stderr, "Wrong bus owned for transfer desired\n"); exit(1); }}/* **-simpledisk_bus_ownership_grant Calls bus_delay to handle the event that the disk has been granted the bus. I believe this is always initiated by a call to disk_send_even_up_path. */void simpledisk_bus_ownership_grant (int devno, ioreq_event *curr, int busno, double arbdelay){ simpledisk_t *currdisk; ioreq_event *tmp; currdisk = getsimpledisk (devno); tmp = currdisk->buswait; while ((tmp != NULL) && (tmp != curr)) { tmp = tmp->next; } if (tmp == NULL) { fprintf(stderr, "Bus ownership granted to unknown simpledisk request - devno %d, busno %d\n", devno, busno); exit(1); } currdisk->busowned = busno; currdisk->stat.waitingforbus += arbdelay; //ASSERT (arbdelay == (simtime - currdisk->stat.requestedbus)); currdisk->stat.numbuswaits++; bus_delay(busno, DEVICE, devno, tmp->time, tmp);}void simpledisk_bus_delay_complete (int devno, ioreq_event *curr, int sentbusno){ simpledisk_t *currdisk; intchar slotno; intchar busno; int depth; currdisk = getsimpledisk (devno); // fprintf (outputfile, "Entered disk_bus_delay_complete\n"); if (curr == currdisk->buswait) { currdisk->buswait = curr->next; } else { ioreq_event *tmp = currdisk->buswait; while ((tmp->next != NULL) && (tmp->next != curr)) { tmp = tmp->next; } if (tmp->next != curr) { fprintf(stderr, "Bus delay complete for unknown simpledisk request - devno %d, busno %d\n", devno, busno.value); exit(1); } tmp->next = curr->next; } busno.value = curr->busno; slotno.value = curr->slotno; depth = currdisk->depth[0]; slotno.byte[depth] = slotno.byte[depth] >> 4; curr->time = 0.0; if (depth == 0) { intr_request ((event *)curr); } else { bus_deliver_event(busno.byte[depth], slotno.byte[depth], curr); }}/* send completion up the line */static void simpledisk_request_complete(ioreq_event *curr){ simpledisk_t *currdisk; // fprintf (outputfile, "Entering simpledisk_request_complete: %12.6f\n", simtime); currdisk = getsimpledisk (curr->devno); if ((curr = ioqueue_physical_access_done(currdisk->queue,curr)) == NULL) { fprintf(stderr, "simpledisk_request_complete: ioreq_event not found by ioqueue_physical_access_done call\n"); exit(1); } /* send completion interrupt */ curr->type = IO_INTERRUPT_ARRIVE; curr->cause = COMPLETION; simpledisk_send_event_up_path(curr, currdisk->bus_transaction_latency);}static void simpledisk_bustransfer_complete (ioreq_event *curr){ simpledisk_t *currdisk; // fprintf (outputfile, "Entering simpledisk_bustransfer_complete for disk %d: %12.6f\n", curr->devno, simtime); currdisk = getsimpledisk (curr->devno); if (curr->flags & READ) { simpledisk_request_complete (curr); } else { simpledisk_t *currdisk = getsimpledisk (curr->devno); if (currdisk->neverdisconnect == FALSE) { /* disconnect from bus */ ioreq_event *tmp = ioreq_copy (curr); tmp->type = IO_INTERRUPT_ARRIVE; tmp->cause = DISCONNECT; simpledisk_send_event_up_path (tmp, currdisk->bus_transaction_latency); } /* do media access */ currdisk->media_busy = TRUE; stat_update (&currdisk->stat.acctimestats, currdisk->acctime); curr->time = simtime + currdisk->acctime; curr->type = DEVICE_ACCESS_COMPLETE; addtointq ((event *) curr); }}static void simpledisk_reconnect_done (ioreq_event *curr){ simpledisk_t *currdisk; // fprintf (outputfile, "Entering simpledisk_reconnect_done for disk %d: %12.6f\n", curr->devno, simtime); currdisk = getsimpledisk (curr->devno); if (curr->flags & READ) { if (currdisk->neverdisconnect) { /* Just holding on to bus; data transfer will be initiated when */ /* media access is complete. */ addtoextraq((event *) curr); } else { /* data transfer: curr->bcount, which is still set to original */ /* requested value, indicates how many blks to transfer. */ curr->type = DEVICE_DATA_TRANSFER_COMPLETE; simpledisk_send_event_up_path(curr, (double) 0.0); } } else { if (currdisk->reconnect_reason == DEVICE_ACCESS_COMPLETE) { simpledisk_request_complete (curr); } else { /* data transfer: curr->bcount, which is still set to original */ /* requested value, indicates how many blks to transfer. */ curr->type = DEVICE_DATA_TRANSFER_COMPLETE; simpledisk_send_event_up_path(curr, (double) 0.0); } }}static void simpledisk_request_arrive (ioreq_event *curr){ ioreq_event *intrp; simpledisk_t *currdisk; // fprintf (outputfile, "Entering simpledisk_request_arrive: %12.6f\n", simtime); // fprintf (outputfile, "simpledisk = %d, blkno = %d, bcount = %d, read = %d\n",curr->devno, curr->blkno, curr->bcount, (READ & curr->flags)); 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 %d, bcount %d, numblocks %d\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 void simpledisk_access_complete (ioreq_event *curr){ simpledisk_t *currdisk; // fprintf (outputfile, "Entering simpledisk_access_complete: %12.6f\n", simtime); currdisk = getsimpledisk (curr->devno); currdisk->media_busy = FALSE; if (currdisk->neverdisconnect) { /* already connected */ if (curr->flags & READ) { /* transfer data up the line: curr->bcount, which is still set to */ /* original requested value, indicates how many blks to transfer. */ curr->type = DEVICE_DATA_TRANSFER_COMPLETE; simpledisk_send_event_up_path(curr, (double) 0.0); } else {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -