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

📄 disksim.c

📁 disksim是一个非常优秀的磁盘仿真工具
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * DiskSim Storage Subsystem Simulation Environment (Version 4.0) * Revision Authors: John Bucy, Greg Ganger * Contributors: John Griffin, Jiri Schindler, Steve Schlosser * * Copyright (c) of Carnegie Mellon University, 2001-2008. * * 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_ioface.h"#include "disksim_pfface.h"#include "disksim_iotrace.h"#include "config.h"#include "modules/disksim_global_param.h"#include <stdio.h>#include <signal.h>#include <stdarg.h>#ifdef SUPPORT_CHECKPOINTS#include <unistd.h>#include <fcntl.h>#include <sys/mman.h>#endifdisksim_t *disksim = NULL;/* legacy hack for HPL traces... */#define PRINT_TRACEFILE_HEADER	FALSE/*** Functions to allocate and deallocate empty event structures ***//* Creates new, empty events (using malloc) and puts them on the extraq. *//* Called by getfromextraq when the queue is found to be empty.          */#define EXTRAEVENTS 32static void allocateextra (){   int i;   event *temp = NULL;   StaticAssert (sizeof(event) == DISKSIM_EVENT_SIZE);   temp = calloc(EXTRAEVENTS, sizeof(event));   //   if ((temp = (event *)DISKSIM_malloc(ALLOCSIZE)) == NULL) {   ddbg_assert(temp != 0);   //   for (i=0; i<((ALLOCSIZE/DISKSIM_EVENT_SIZE)-1); i++) {   for(i = 0; i < EXTRAEVENTS; i++) {      temp[i].next = &temp[i+1];   }   temp[EXTRAEVENTS-1].next = disksim->extraq;   disksim->extraq = temp;   disksim->extraqlen += EXTRAEVENTS;   //   disksim->extraqlen = ALLOCSIZE / DISKSIM_EVENT_SIZE;}/* A simple check to make sure that you're not adding an event   to the extraq that is already there! */int addtoextraq_check(event *ev){    event *temp = disksim->extraq;    while (temp != NULL) {	if (ev == temp) {	  // I did it this way so that I could break at this line -schlos	    ddbg_assert(ev != temp);	}	temp = temp->next;    }    return 1;}/* Deallocates an event structure, adding it to the extraq free pool. */  INLINE void addtoextraq (event *temp){  // addtoextraq_check(temp);   if (temp == NULL) {      return;   }   temp->next = disksim->extraq;   temp->prev = NULL;   disksim->extraq = temp;   disksim->extraqlen++;}/* Allocates an event structure from the extraq free pool; if empty, *//* calls allocateextra to create some more.                          */INLINE event * getfromextraq (){  event *temp;  if(disksim->extraqlen == 0) {    allocateextra();    temp = disksim->extraq;    disksim->extraq = disksim->extraq->next;  }  else if(disksim->extraqlen == 1) {    temp = disksim->extraq;    disksim->extraq = NULL;  }  else {    temp = disksim->extraq;    disksim->extraq = disksim->extraq->next;  }  disksim->extraqlen--;  temp->next = NULL;  temp->prev = NULL;  return temp;}/* Deallocates a list of event structures to the extraq free pool. */void addlisttoextraq (event **headptr){   event *tmp1, *tmp2;   tmp1 = *headptr;   if(!tmp1) return;   /*     while ((tmp = *headptr)) { *//*        *headptr = tmp->next; *//*        addtoextraq(tmp); *//*     } */   do {     tmp2 = tmp1->next;     addtoextraq(tmp1);     tmp1 = tmp2;   } while(tmp1 && (tmp1 != (*headptr)));   *headptr = NULL;}/* Returns a pointer to a copy of event passed as a parameter.  */event *event_copy (event *orig){   event *new = getfromextraq();   memmove((char *)new, (char *)orig, DISKSIM_EVENT_SIZE);/* bcopy ((char *)orig, (char *)new, DISKSIM_EVENT_SIZE); */   return((event *) new);}/*** Functions to manipulate intq, the queue of scheduled events ***//* Prints the intq to the output file, presumably for debug.  */static void disksim_dumpintq (){   event *tmp;   int i = 0;   tmp = disksim->intq;   while (tmp != NULL) {      i++;      fprintf (outputfile, "time %f, type %d\n", 	       tmp->time, tmp->type);      tmp = tmp->next;   }}/* Add an event to the intq.  The "time" field indicates when the event is *//* scheduled to occur, and the intq is maintained in ascending time order. *//* make this a binheap or something ... avoid walking the list */INLINE void addtointq (event *newint){  /* WARNING -- HORRIBLE HACK BELOW   * In order to make the Memulator run (which sometimes has events arrive   * "late") I've (JLG) commented out the following snippet.  A better   * solution should be arrived at...   */#if 0   if ((temp->time + DISKSIM_TIME_THRESHOLD) < simtime) {      fprintf(stderr, "Attempting to addtointq an event whose time has passed\n");      fprintf(stderr, "simtime %f, curr->time %f, type = %d\n", simtime, temp->time, temp->type);      exit(1);   }#endif   switch(disksim->trace_mode) {   case DISKSIM_MASTER:     if(write(disksim->tracepipes[1], (char *)newint, sizeof(event)) <= 0)       {	 //	 printf("addtointq() -- master write fd = %d\n", disksim->tracepipes[1]);	 //	 perror("addtointq() -- master write");       }     break;   case DISKSIM_SLAVE:     {       event tmpevt;       double timediff;       //       printf("addtointq() -- slave read\n");       ddbg_assert(read(disksim->tracepipes[0], (char *)&tmpevt, sizeof(event)) > 0);       timediff = fabs(tmpevt.time - newint->time);       /*         printf("remote event: %d %f, local event: %d %f\n", *//*  	      tmpevt.type,  *//*  	      tmpevt.time, *//*  	      newint->type,  *//*  	      newint->time); */       ddbg_assert(tmpevt.type == newint->type);       //       ddbg_assert(timediff <= 0.001);       newint->time = tmpevt.time;       if(timediff > 0.000001) {	 printf("*** SLAVE: addtointq() timediff = %f\n", timediff);       }       fflush(stdout);     }     break;   case DISKSIM_NONE:   default:     break;   }   if (disksim->intq == NULL) {      disksim->intq = newint;      newint->next = NULL;      newint->prev = NULL;   }    else if (newint->time < disksim->intq->time) {      newint->next = disksim->intq;      disksim->intq->prev = newint;      disksim->intq = newint;      newint->prev = NULL;   } else {      event *run = disksim->intq;      assert(run->next != run);      while (run->next != NULL) {         if (newint->time < run->next->time) {            break;         }         run = run->next;      }      newint->next = run->next;      run->next = newint;      newint->prev = run;      if (newint->next != NULL) {         newint->next->prev = newint;      }   }}/* Retrieves the next scheduled event from the head of the intq. */INLINE static event * getfromintq (){   event *temp = NULL;   if (disksim->intq == NULL) {      return(NULL);   }   temp = disksim->intq;   disksim->intq = disksim->intq->next;   if (disksim->intq != NULL) {      disksim->intq->prev = NULL;   }   temp->next = NULL;   temp->prev = NULL;   return(temp);}/* Removes a given event from the intq, thus descheduling it.  Returns *//* TRUE if the event was found, FALSE if it was not.                   */INLINE int removefromintq (event *curr){   event *tmp;   tmp = disksim->intq;   while (tmp != NULL) {      if (tmp == curr) {         break;      }      tmp = tmp->next;   }   if (tmp == NULL) {      return(FALSE);   }   if (curr->next != NULL) {      curr->next->prev = curr->prev;   }   if (curr->prev == NULL) {      disksim->intq = curr->next;   } else {      curr->prev->next = curr->next;   }   curr->next = NULL;   curr->prev = NULL;   return(TRUE);}/*** Functions to initialize the system and print statistics ***/void scanparam_int (char *parline, char *parname, int *parptr,                    int parchecks, int parminval, int parmaxval){   if (sscanf(parline, "%d", parptr) != 1) {      fprintf(stderr, "Error reading '%s'\n", parname);      exit(1);   }   if (((parchecks & 1) && (*parptr < parminval)) || ((parchecks & 2) && (*parptr > parmaxval))) {      fprintf(stderr, "Invalid value for '%s': %d\n", parname, *parptr);      exit(1);   }}void getparam_int (FILE *parfile, char *parname, int *parptr,                   int parchecks, int parminval, int parmaxval){   char line[201];   sprintf(line, "%s: %s", parname, "%d");   if (fscanf(parfile, line, parptr) != 1) {      fprintf(stderr, "Error reading '%s'\n", parname);      exit(1);   }   fgets(line, 200, parfile); /* this allows comments, kinda ugly hack */   if (((parchecks & 1) && (*parptr < parminval)) || ((parchecks & 2) && (*parptr > parmaxval))) {      fprintf(stderr, "Invalid value for '%s': %d\n", parname, *parptr);      exit(1);   }   fprintf (outputfile, "%s: %d\n", parname, *parptr);}void getparam_double (FILE *parfile, char *parname, double *parptr,                      int parchecks, double parminval, double parmaxval){   char line[201];   sprintf(line, "%s: %s", parname, "%lf");   if (fscanf(parfile, line, parptr) != 1) {      fprintf(stderr, "Error reading '%s'\n", parname);      assert(0);   }   fgets(line, 200, parfile);   if (((parchecks & 1) && (*parptr < parminval)) || ((parchecks & 2) && (*parptr > parmaxval)) || ((parchecks & 4) && (*parptr <= parminval))) {      fprintf(stderr, "Invalid value for '%s': %f\n", parname, *parptr);      assert(0);   }   fprintf (outputfile, "%s: %f\n", parname, *parptr);}void getparam_bool (FILE *parfile, char *parname, int *parptr){   char line[201];   sprintf(line, "%s %s", parname, "%d");   if (fscanf(parfile, line, parptr) != 1) {      fprintf(stderr, "Error reading '%s'\n", parname);      exit(1);   }   fgets(line, 200, parfile);   if ((*parptr != TRUE) && (*parptr != FALSE)) {      fprintf(stderr, "Invalid value for '%s': %d\n", parname, *parptr);      exit(1);   }   fprintf (outputfile, "%s %d\n", parname, *parptr);}void resetstats (){   if (disksim->external_control | disksim->synthgen | disksim->iotrace) {      io_resetstats();   }   if (disksim->synthgen) {      pf_resetstats();   }}static void stat_warmup_done (timer_event *timer){   warmuptime = simtime;   resetstats();   addtoextraq((event *)timer);}int disksim_global_loadparams(struct lp_block *b){  // #include "modules/disksim_global_param.c"  lp_loadparams(0, b, &disksim_global_mod);  //  printf("*** warning: seed hack -- using 1207981\n");  //  DISKSIM_srand48(1207981);  //  disksim->seedval = 1207981;  return 1;}void disksim_printstats2(){   fprintf (outputfile, "\nSIMULATION STATISTICS\n");   fprintf (outputfile, "---------------------\n\n");   fprintf (outputfile, "Total time of run:       %f\n\n", simtime);   fprintf (outputfile, "Warm-up time:            %f\n\n", warmuptime);   if (disksim->synthgen) {      pf_printstats();   }   if (disksim->external_control | disksim->synthgen | disksim->iotrace) {      io_printstats();   }}static void setcallbacks (){   disksim->issuefunc_ctlrsmart = NULL;   disksim->queuefind_ctlrsmart = NULL;   disksim->wakeupfunc_ctlrsmart = NULL;   disksim->donefunc_ctlrsmart_read = NULL;   disksim->donefunc_ctlrsmart_write = NULL;   disksim->donefunc_cachemem_empty = NULL;   disksim->donefunc_cachedev_empty = NULL;   disksim->idlework_cachemem = NULL;   disksim->idlework_cachedev = NULL;   disksim->concatok_cachemem = NULL;   disksim->enablement_disk = NULL;   disksim->timerfunc_disksim = NULL;   disksim->timerfunc_ioqueue = NULL;   disksim->timerfunc_cachemem = NULL;   disksim->timerfunc_cachedev = NULL;   disksim->timerfunc_disksim = stat_warmup_done;   disksim->external_io_done_notify = NULL;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -