?? disksim.c
字號(hào):
/* * 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 * 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;
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -