int trace_read_trailer(trace_interface_t * trace, int restore_position) { off_t original_next_insn_ctr; size_t trailer_size, num_procs = 0; uint32_t magic_number; FILE * stream; int i; if (!trace || trace->trace_version != 60) return -1; stream = trace->trace_stream; // Save current file position if (restore_position) { original_next_insn_ctr = trace->trace_next_insn_ctr; } // Read end of trace if (fseeko(stream, trace->trace_byte_size - 12, SEEK_SET) != 0) { fprintf(stderr, "libtracereader: failed seeking end of trace.\n"); return -1; } // Read trailer size if (fread(&trailer_size, 4, 1, stream) != 1) { fprintf(stderr, "libtracereader: failed reading trailer size.\n"); return -1; } // Read number of processes size if (fread(&num_procs, 4, 1, stream) != 1) { fprintf(stderr, "libtracereader: failed reading number ot trailer processes .\n"); return -1; } // Read magic number if (fread(&magic_number, 4, 1, stream) != 1) { fprintf(stderr, "libtracereader: failed reading trailer magic number.\n"); return -1; } // Make sure it looks like a trailer if (magic_number != TRAILER_END) { fprintf(stderr, "libtracereader: invalid trailer magic number.\n"); return -1; } if (num_procs > 0) { // Seek start of trailer process information off_t proc_filepos = trace->trace_byte_size - (trailer_size + 12); if (fseeko(stream, proc_filepos, SEEK_SET) != 0) { fprintf(stderr, "libtracereader: failed seeking trailer processes.\n"); return -1; } // Read processes and modules proc_t * procs = NULL; module_t ** mods = NULL; if (read_processes(stream, num_procs, &procs, &mods) != 0) { fprintf(stderr, "libtracereader: failed reading trailer processes.\n"); return -1; } // Free current processes and modules structures if (trace->trace_procs) { free(trace->trace_procs); trace->trace_procs = NULL; } if (trace->trace_mods) { for (i = 0; i < trace->trace_nprocs; i++) { if (trace->trace_mods[i]) free(trace->trace_mods[i]); } free(trace->trace_mods); trace->trace_mods = NULL; } // Update process and module information trace->trace_procs = procs; trace->trace_mods = mods; trace->trace_nprocs = num_procs; } // Restore original position if (restore_position) { if (trace_seek_insn(trace, original_next_insn_ctr) != 0) { return -1; } } return 0; }
trace_interface_t * trace_open(const char * trace_path) { FILE * stream = NULL; FILE * idx_stream = NULL; struct stat file_info; theader_t trace_header; char index_path[128] = {0}; size_t num_proc_mods; int i; /* Open trace file */ if ((stream = fopen(trace_path, "r")) == NULL) { fprintf(stderr, "libtracereader: could not open %s.\n", trace_path); return NULL; } /* Get size of trace file */ if (fstat(fileno(stream), &file_info) != 0) { fprintf(stderr, "libtracereader: fstat failed on trace file.\n"); return NULL; } if (file_info.st_size < sizeof(trace_header)) { fprintf(stderr, "libtracereader: trace is too small.\n"); return NULL; } /* Read header from trace file */ if (fread(&trace_header, sizeof(trace_header), 1, stream) != 1) { fprintf(stderr, "libtracereader: could not read trace header.\n"); return NULL; } if (trace_header.magicnumber != MAGIC_NUMBER) { fprintf(stderr, "libtracereader: invalid trace file.\n"); return NULL; } /* Allocate trace interface */ trace_interface_t * trace = (trace_interface_t *) malloc (sizeof(trace_interface_t)); if (!trace) { fprintf(stderr, "libtracereader: failed to allocate trace interface.\n"); return NULL; } trace->trace_stream = stream; trace->trace_version = trace_header.version; trace->trace_nprocs = trace_header.n_procs; trace->trace_byte_size = file_info.st_size; trace->trace_procs = NULL; trace->trace_mods = NULL; trace->trace_path = NULL; /* Set read instruction function pointer */ switch (trace_header.version) { case 50: trace->trace_read_next_insn = read_instruction_v50; break; case 60: trace->trace_read_next_insn = read_instruction_v60; break; default: fprintf(stderr, "libtracereader: unsupported trace version.\n"); goto fail; } /* Read process information from trace file */ if (read_processes(trace->trace_stream, trace_header.n_procs, &(trace->trace_procs), &(trace->trace_mods)) != 0) { goto fail; } /* Copy file path */ size_t path_len = strlen(trace_path); trace->trace_path = (char *) malloc (path_len + 1); if (trace->trace_path == NULL) { fprintf(stderr, "libtracereader: could not allocate memory for trace path.\n"); goto fail; } strncpy(trace->trace_path, trace_path, path_len); /* Fill remaining fields in trace_file */ trace->trace_first_filepos = ftello(stream); trace->trace_next_insn_ctr = 1; /* Read trailer if needed */ if (trace_header.version == 60) { trace_read_trailer(trace, 1); } /* Open index file if it exists */ snprintf(index_path, sizeof(index_path), "%s.idx", trace_path); if ((idx_stream = fopen(index_path, "r")) != NULL) { trace->trace_idx_stream = idx_stream; if (fstat(fileno(idx_stream), &file_info) != 0) { fprintf(stderr, "libtracereader: fstat failed on trace file.\n"); goto fail; } trace->trace_num_insn = file_info.st_size / 8; } else { trace->trace_idx_stream = NULL; trace->trace_num_insn = -1; } /* Initialize disassembler */ xed2_init(); return trace; fail: if (trace->trace_path) { free(trace->trace_path); trace->trace_path = NULL; } if (trace->trace_procs) { free(trace->trace_procs); trace->trace_procs = NULL; } if (trace->trace_mods) { for (i = 0; i < trace_header.n_procs; i++) { if (trace->trace_mods[i]) free(trace->trace_mods[i]); } free(trace->trace_mods); trace->trace_mods = NULL; } if (trace) free(trace); return NULL; }
int main(int argc, char **argv) { char input; char *target; // Target input file name. char *alg; // fcfs or multi. int memsize; // Given virtual memsize. if (argc != 7) { print_usage(argv[0]); return -1; } // Getting the options for program execution. while ((input = getopt(argc, argv, "f:a:m:")) != EOF) { switch ( input ) { case 'f': // Ascertaining which file to read the input from. target = optarg; break; case 'a': // Ascertaining which algorithm to use. if(strcmp(optarg, FCFS) == 0) alg = optarg; else if(strcmp(optarg, MULTI) == 0) alg = optarg; else { // Exit if optarg unknown fprintf(stderr, "Invalid scheduling option %s\n", optarg); print_usage(argv[0]); exit(1); } break; case 'm': // Ascertaining total memory size. memsize = atoi(optarg); break; default: // Should not get here. print_usage(argv[0]); return -1; } } /* ** Here we read processes into disk. Throughout the life of the ** simulation, this disk linked list will hold both processes that ** haven't yet been started (future processes whose start times are ** greater than the current simulation time) as well as processes ** that have been swapped back to disk because memory was too full. */ int num_processes = 0; Process *disk_head = read_processes(target, memsize, &num_processes); if (disk_head == NULL) { fprintf(stderr, "%s couldn't be read properly, exiting...\n", target); return -1; } Memory *memory = create_memory(memsize); simulate(disk_head, num_processes, memory, alg); return 0; }