📄 disksim.c
字号:
io_setcallbacks(); pf_setcallbacks();}static void initialize (){ int val = (disksim->synthgen) ? 0 : 1; iotrace_initialize_file (disksim->iotracefile, disksim->traceformat, PRINT_TRACEFILE_HEADER); while (disksim->intq) { addtoextraq(getfromintq()); } if (disksim->external_control | disksim->synthgen | disksim->iotrace) { io_initialize(val); } if (disksim->synthgen) { pf_initialize(disksim->seedval); } else { DISKSIM_srand48(disksim->seedval); } simtime = 0.0;}void disksim_cleanstats (){ if (disksim->external_control | disksim->synthgen | disksim->iotrace) { io_cleanstats(); } if (disksim->synthgen) { pf_cleanstats(); }}void disksim_set_external_io_done_notify (disksim_iodone_notify_t fn){ disksim->external_io_done_notify = fn;}event *io_done_notify (ioreq_event *curr){ if (disksim->synthgen) { return pf_io_done_notify(curr, 0); } if (disksim->external_control) { disksim->external_io_done_notify (curr, disksim->notify_ctx); } return(NULL);}INLINE static event * getnextevent(void){ event *curr = getfromintq(); event *temp; if (curr) { simtime = curr->time; if (curr->type == NULL_EVENT) { if ((disksim->iotrace) && io_using_external_event(curr)) { temp = io_get_next_external_event(disksim->iotracefile); if (!temp) { disksim->stop_sim = TRUE; } else { // OK } } else { fprintf(stderr, "NULL_EVENT not linked to any external source\n"); exit(1); } if (temp) { temp->type = NULL_EVENT; addtointq(temp); } } // curr->type == NULL_EVENT } else { fprintf (outputfile, "Returning NULL from getnextevent\n"); fflush (outputfile); } return curr;}void disksim_checkpoint (char *checkpointfilename){ FILE *checkpointfile;//printf ("disksim_checkpoint: simtime %f, totalreqs %d\n", simtime, disksim->totalreqs); if (disksim->checkpoint_disable) { fprintf (outputfile, "Checkpoint at simtime %f skipped because checkpointing is disabled\n", simtime); return; } if ((checkpointfile = fopen(checkpointfilename, "w")) == NULL) { fprintf (outputfile, "Checkpoint at simtime %f skipped because checkpointfile cannot be opened for write access\n", simtime); return; } if (disksim->iotracefile) { if (strcmp (disksim->iotracefilename, "stdin") == 0) { fprintf (outputfile, "Checkpoint at simtime %f skipped because iotrace comes from stdin\n", simtime); return; } fflush (disksim->iotracefile); fgetpos (disksim->iotracefile, &disksim->iotracefileposition); } if (outios) { fflush (outios); fgetpos (outios, &disksim->outiosfileposition); } if (outputfile) { fflush (outputfile); fgetpos (outputfile, &disksim->outputfileposition); } rewind (checkpointfile); fwrite (disksim, disksim->totallength, 1, checkpointfile); fflush (checkpointfile); fclose (checkpointfile);}void disksim_simstop (){ disksim->stop_sim = TRUE;}void disksim_register_checkpoint (double attime){ event *checkpoint = getfromextraq (); checkpoint->type = CHECKPOINT; checkpoint->time = attime; addtointq(checkpoint);}static void prime_simulation (){ event *curr; if (disksim->warmup_event) { addtointq((event *)disksim->warmup_event); disksim->warmup_event = NULL; } if (disksim->checkpoint_interval > 0.0) { disksim_register_checkpoint (disksim->checkpoint_interval); } if (disksim->iotrace) { if ((curr = io_get_next_external_event(disksim->iotracefile)) == NULL) { disksim_cleanstats(); return; } if ((disksim->traceformat != VALIDATE) && (disksim->closedios == 0)) { curr->type = NULL_EVENT; } else if (disksim->closedios) { int iocnt; io_using_external_event(curr); curr->time = simtime + disksim->closedthinktime; for (iocnt=1; iocnt < disksim->closedios; iocnt++) { curr->next = io_get_next_external_event(disksim->iotracefile); if (curr->next) { io_using_external_event(curr->next); curr->time = simtime + disksim->closedthinktime; addtointq(curr->next); } } } // XXX yuck ... special case for 1st req if(disksim->traceformat == VALIDATE) { ioreq_event *tmp = (ioreq_event *)curr; disksim_exectrace("Request issue: simtime %f, devno %d, blkno %d, time %f\n", simtime, tmp->devno, tmp->blkno, tmp->time); } addtointq(curr); }}void disksim_simulate_event (int num){ event *curr; if ((curr = getnextevent()) == NULL) { disksim_simstop (); } else { switch(disksim->trace_mode) { case DISKSIM_NONE: case DISKSIM_MASTER:/* fprintf(outputfile, "*** DEBUG TRACE\t%f\t%d\t%d\n", *//* simtime, curr->type, num); *//* fflush(outputfile); */ break; case DISKSIM_SLAVE: break; } simtime = curr->time; if (curr->type == INTR_EVENT) { intr_acknowledge (curr); } else if ((curr->type >= IO_MIN_EVENT) && (curr->type <= IO_MAX_EVENT)) { io_internal_event ((ioreq_event *)curr); } else if ((curr->type >= PF_MIN_EVENT) && (curr->type <= PF_MAX_EVENT)) { pf_internal_event(curr); } else if (curr->type == TIMER_EXPIRED) { timer_event *timeout = (timer_event *) curr; (*timeout->func) (timeout); } else if ((curr->type >= MEMS_MIN_EVENT) && (curr->type <= MEMS_MAX_EVENT)) { io_internal_event ((ioreq_event *)curr); } else if (curr->type == CHECKPOINT) { if (disksim->checkpoint_interval) { disksim_register_checkpoint(simtime + disksim->checkpoint_interval); } disksim_checkpoint (disksim->checkpointfilename); } else if (curr->type == STOP_SIM) { disksim_simstop (); } else if (curr->type == EXIT_DISKSIM) { exit (0); } else { fprintf(stderr, "Unrecognized event in simulate: %d\n", curr->type); exit(1); } #ifdef FDEBUG fprintf (outputfile, "Event handled, going for next\n"); fflush (outputfile);#endif } }static void disksim_setup_outputfile (char *filename, char *mode){ if (strcmp(filename, "stdout") == 0) { outputfile = stdout; } else { if ((outputfile = fopen(filename,mode)) == NULL) { fprintf(stderr, "Outfile %s cannot be opened for write access\n", filename); exit(1); } } if (strlen(filename) <= 255) { strcpy (disksim->outputfilename, filename); } else { fprintf (stderr, "Name of output file is too long (>255 bytes); checkpointing disabled\n"); disksim->checkpoint_disable = 1; } setvbuf(outputfile, 0, _IONBF, 0); }static void disksim_setup_iotracefile (char *filename){ if (strcmp(filename, "0") != 0) { assert (disksim->external_control == 0); disksim->iotrace = 1; if (strcmp(filename, "stdin") == 0) { disksim->iotracefile = stdin; } else { if ((disksim->iotracefile = fopen(filename,"rb")) == NULL) { fprintf(stderr, "Tracefile %s cannot be opened for read access\n", filename); exit(1); } } } else { disksim->iotracefile = NULL; } if (strlen(filename) <= 255) { strcpy (disksim->iotracefilename, filename); } else { fprintf (stderr, "Name of iotrace file is too long (>255 bytes); checkpointing disabled\n"); disksim->checkpoint_disable = 1; }}static void setEndian(void) { int n = 0x11223344; char *c = (char *)&n; if(c[0] == 0x11) { disksim->endian = _BIG_ENDIAN; } else { disksim->endian = _LITTLE_ENDIAN; } }void disksim_setup_disksim (int argc, char **argv){ setEndian(); StaticAssert (sizeof(intchar) == 4); if (argc < 6) { fprintf(stderr,"Usage: %s paramfile outfile format iotrace synthgen?\n", argv[0]); exit(1); }#ifdef FDEBUG fprintf (stderr, "%s %s %s %s %s %s\n", argv[0], argv[1], argv[2], argv[3], argv[4], argv[5]);#endif if ((argc - 6) % 3) { fprintf(stderr, "Parameter file overrides must be 3-tuples\n"); exit(1); } disksim_setup_outputfile (argv[2], "w"); fprintf (outputfile, "\n*** Output file name: %s\n", argv[2]); fflush (outputfile); if(strcmp (argv[3], "external") == 0) { disksim->external_control = 1; } else { iotrace_set_format(argv[3]); } fprintf (outputfile, "*** Input trace format: %s\n", argv[3]); fflush (outputfile); disksim_setup_iotracefile (argv[4]); fprintf (outputfile, "*** I/O trace used: %s\n", argv[4]); fflush (outputfile); if(strcmp(argv[5], "0") != 0) { disksim->synthgen = 1; disksim->iotrace = 0; } fprintf(outputfile, "*** Synthgen to be used?: %d\n\n", disksim->synthgen); fflush(outputfile); disksim->overrides = argv + 6; disksim->overrides_len = argc - 6; // asserts go to stderr by default ddbg_assert_setfile(stderr); disksim->tracepipes[0] = 8; disksim->tracepipes[1] = 9; /* disksim->tracepipes[0] = dup(8); *//* disksim->tracepipes[1] = dup(9); *//* close(8); *//* close(9); *//* if(!strcmp(argv[6], "master")) { *//* printf("*** Running in MASTER mode\n"); *//* disksim->trace_mode = DISKSIM_MASTER; *//* close(disksim->tracepipes[0]); *//* } *//* else if(!strcmp(argv[6], "slave")) { *//* printf("*** Running in SLAVE mode\n"); *//* disksim->trace_mode = DISKSIM_SLAVE; *//* close(disksim->tracepipes[1]); *//* } *//* else { */ // printf("*** not running in master-slave mode\n"); disksim->trace_mode = DISKSIM_NONE;/* } */ if(disksim_loadparams(argv[1], disksim->synthgen)) { fprintf(stderr, "*** error: FATAL: failed to load disksim parameter file.\n"); exit(1); } else { fprintf(outputfile, "loadparams complete\n"); fflush(outputfile); /* config_release_typetbl(); */ } if(!disksim->iosim_info) { /* if the user didn't provide an iosim block */ iosim_initialize_iosim_info (); } initialize(); fprintf(outputfile, "Initialization complete\n"); fflush(outputfile); prime_simulation(); // XXX abstract this fclose(statdeffile); statdeffile = NULL;}void disksim_restore_from_checkpoint (char *filename){#ifdef SUPPORT_CHECKPOINTS int fd; void *startaddr; int totallength; int ret; fd = open (filename, O_RDWR); assert (fd >= 0); ret = read (fd, &startaddr, sizeof (void *)); assert (ret == sizeof(void *)); ret = read (fd, &totallength, sizeof (int)); assert (ret == sizeof(int)); disksim = (disksim_t *) mmap (startaddr, totallength, (PROT_READ|PROT_WRITE), (MAP_PRIVATE), fd, 0); //printf ("mmap at %p, ret %d, len %d, addr %p\n", disksim, ret, totallength, startaddr); //perror(""); assert (disksim == startaddr); disksim_setup_outputfile (disksim->outputfilename, "r+"); if (outputfile != NULL) { ret = fsetpos (outputfile, &disksim->outputfileposition); assert (ret >= 0); } disksim_setup_iotracefile (disksim->iotracefilename); if (disksim->iotracefile != NULL) { ret = fsetpos (disksim->iotracefile, &disksim->iotracefileposition); assert (ret >= 0); } if ((strcmp(disksim->outiosfilename, "0") != 0) && (strcmp(disksim->outiosfilename, "null") != 0)) { if ((outios = fopen(disksim->outiosfilename, "r+")) == NULL) { fprintf(stderr, "Outios %s cannot be opened for write access\n", disksim->outiosfilename); exit(1); } ret = fsetpos (outios, &disksim->outiosfileposition); assert (ret >= 0); }#else assert ("Checkpoint/restore not supported on this platform" == 0);#endif setcallbacks();}void disksim_run_simulation (){ int event_count = 0; DISKSIM_srand48(1000003); while (disksim->stop_sim == FALSE) { disksim_simulate_event(event_count); // printf("disksim_run_simulation: event %d\n", event_count); event_count++; } // printf("disksim_run_simulation(): simulated %d events\n", event_count);}void disksim_cleanup(void) { int i; if (outputfile) { fclose (outputfile); } if (disksim->iotracefile) { fclose(disksim->iotracefile); } iodriver_cleanup(); if(outios) { fclose(outios); outios = NULL; }}void disksim_printstats(void) { fprintf(outputfile, "Simulation complete\n"); fflush(outputfile); disksim_cleanstats(); disksim_printstats2();}void disksim_cleanup_and_printstats (){ disksim_printstats(); disksim_cleanup();}int disksim_initialize_disksim_structure (struct disksim *disksim){ // disksim->startaddr = addr; // disksim->totallength = len; // disksim->curroffset = sizeof(disksim_t); disksim->closedthinktime = 0.0; warmuptime = 0.0; /* gets remapped to disksim->warmuptime */ simtime = 0.0; /* gets remapped to disksim->warmuptime */ disksim->lastphystime = 0.0; disksim->checkpoint_interval = 0.0; return 0;}voiddisksim_exectrace(char *fmt, ...) { if(disksim->exectrace) { va_list ap; va_start(ap, fmt); vfprintf(disksim->exectrace, fmt, ap); va_end(ap); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -