#include #include #include #include #include #include #include #include #include "memories/FirstFitMemory.cpp" #include "memories/BestFitMemory.cpp" #include "memories/WorstFitMemory.cpp" using namespace std; #define MAX_ARGS 3 /***************************************************************************** * This function parses a line from instruction file, into usable arguments. * * Maximum of 3 args for 'A' instruction. * *****************************************************************************/ vector extractInst(string line, string delimiter){ vector args; // Loop to split the line (use delimiter) into individual args. for (int i=0; i < MAX_ARGS; i++){ string curr_inst = line.substr(0, line.find(delimiter)); curr_inst = curr_inst.substr(0, line.find("\r")); args.push_back(curr_inst); line.erase(0, line.find(delimiter) + delimiter.length()); } return args; }; /********************************************************************* * Checks the argument for wrong data type/format and illegal chars. * **********************************************************************/ bool parsingHasIssues(string arg){ // Check for chars that are not numbers for(char c : arg){ if(!isdigit(c)){ return true; } }; // All positions are digits. return false; }; /***************************************************************** * Convert a memory block into text to save its state in a file. * ******************************************************************/ string blockToText(MemBlock* block){ string temp; if(block->getId() >= 0){ // Program temp = to_string(block->getId()) + ";" + to_string(block->getStart()) + ";" + to_string(block->getEnd()) + "\n"; } else { // Hole temp = to_string(block->getStart()) + ";" + to_string(block->getEnd()) + "\n"; }; return temp; }; /********************************** * Sorting condition for Snapshot * ***********************************/ bool compareBlockId(MemBlock* b1, MemBlock* b2){ return (b1->getId() < b2->getId()); }; /*************************************************************************** * This function takes a snapshot of the memory when "O" command is called. * ****************************************************************************/ void makeSnapshot(FauxMemory* mem, ofstream* file, string strategy){ // Add a header (*file) << strategy + "\n"; // Categorise blocks vector holes; vector programs; for(auto block : (*mem->getAllBlocks())){ if (block->getId() >= 0){programs.push_back(block);} else{holes.push_back(block);}; }; // Sort program blocks by ID sort(programs.begin(), programs.end(), compareBlockId); // Write blocks to file // Program blocks (*file) << "Allocated blocks\n"; for(auto program : programs){ (*file) << blockToText(program); }; // Hole blocks (*file) << "Free blocks\n"; for(auto hole : holes){ (*file) << blockToText(hole); }; // Fragmentation (*file) << "Fragmentation\n"; (*file) << to_string(mem->fragmentation()) << "\n"; // Errors (*file) << "Errors\n"; if((*mem->getAllErrors()).size() == 0){ (*file) << "None\n"; }else{ for(auto error : (*mem->getAllErrors())){ (*file) << error << "\n"; }; }; }; /********************************* * Main simulation of the memory. * **********************************/ int main(int argc, char *argv[]){ // Check args for file name if(argc != 2){ cout << "Usage: ./Main instruction_file.in"; exit(1); } // Declarations string in_file = argv[1]; ifstream insrtuct_file(in_file); int intermed_counter = 1; // Check if the file can be read and initialised into a stream. // If file reading is not possible, program exits. if (insrtuct_file.fail()){ cout << "Error! No file with instructions found. \n"; cout << "Shutting down...\n"; exit(2); }; // Read and execute memory instructions from the file. string curr_line; string delimiter = ";"; int curr_inst = 1; // First line must be max size of "bytes" in memory first. // Following lines -read all args for each line in the file. // All args semi-colon separated. // // First line: getline(insrtuct_file, curr_line); // Declare memories with different strategies vector memories; memories.push_back(new FitFirstMemory(stoi(curr_line))); memories.push_back(new BestFitMemory(stoi(curr_line))); memories.push_back(new WorstFitMemory(stoi(curr_line))); // These are the instructions that are given to the memory. // Please note, it is assumed that instructions are given in a correct format. // No error checking for the file. // // Other lines: while(getline(insrtuct_file, curr_line)){ vector inst = extractInst(curr_line, delimiter); // Select action based on first arg (args[0]): //Allocate if(inst[0].compare("A") == 0){ for(auto memory : memories){ // Check that no parsing gremlins if(parsingHasIssues(inst[2])){ cout << "Allocation error has occured!\n"; memory->addAllocError(curr_inst); } else if(!memory->allocMem(new ProgramBlock(stoi(inst[1]), stoi(inst[2])))) { cout << "Allocation error has occured!\n"; memory->addAllocError(curr_inst); }; }; //Deallocate }else if (inst[0].compare("D") == 0){ for(auto memory : memories){ if(parsingHasIssues(inst[1])){ cout << "Deallocation error has occured!\n"; memory->addDallocError(curr_inst, stoi(inst[1])); } else if(!memory->deallocMem(stoi(inst[1]))) { cout << "Deallocation error has occured!\n"; memory->addDallocError(curr_inst, stoi(inst[1])); }; }; // Compact }else if (inst[0].compare("C") == 0){ for(auto memory : memories){ memory->compactMem(); }; // Output status }else if (inst[0].compare("O") == 0){ // Open output file with specified name string out_file_s = in_file; size_t end = out_file_s.find("."); out_file_s = out_file_s.substr(0, end) + ".out" + to_string(intermed_counter); ofstream out_file(out_file_s); // Write to file for(auto memory : memories){ makeSnapshot(memory, &out_file, memory->getStrategy()); out_file << "\n"; }; intermed_counter ++; out_file.close(); }; // Increment instruction counter for the next cycle. curr_inst++; }; // Output final state of memories to a '.out' file string out_file_s = in_file; size_t end = out_file_s.find("."); out_file_s = out_file_s.substr(0, end) + ".out"; ofstream out_file(out_file_s); for(auto memory : memories){ makeSnapshot(memory, &out_file, memory->getStrategy()); out_file << "\n"; }; // Tidy up before finishing execution. out_file.close(); insrtuct_file.close(); return 0; };