⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 disksim_simpledisk.c

📁 目前最精确的磁盘模拟器的第3版
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * 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 + -