void OS::start() { // read in all the .s files system("ls *.s > progs"); fstream readProgs; readProgs.open("progs", ios::in); if (!readProgs.is_open()) { cout << "could not open progs.\n"; exit(1); } string line; getline(readProgs, line); //begin while loops when !progs end of file while (!readProgs.eof()) { as.assemble(line); // assemble each file using the asembler //create PCB for each file, put in jobs list, and put in ready queue PCB * p = new PCB; jobs.push_back(p); readyQ.push(p); p->state = "ready"; string fileName = line.erase(line.length() -2, 2); // set file names for input and output p->originalfilename = fileName + ".o"; p->readfilename = fileName + ".in"; p->writefilename = fileName + ".out"; p->stfilename = fileName + ".st"; // Open input and output file streams in PCB p->openReadInFileStream(); p->openWriteOutFileStream(); //read into memory, modify PCB with values for base and limit int base, limit; vm.loadIntoMemory(p->originalfilename, &base, &limit); p->base = base; p->limit = limit; p->pc = base; getline(readProgs, line); } // end reading into memory readProgs.close(); system("rm progs"); // copy first item in readyQ to running , load pcb data to vm running = readyQ.front(); readyQ.pop(); givePCBToVM(); int code = 0; while (!done()) // main while loop main processing { code = 0; vm.run(); // runs current process in vm, returns error code stored for later // get return code from status register code = vm.sr; code = code & 0xe0; code >>= 5; // update clocks for context switch masterClock += 5; contextSwitchClock += 5; // update all processes that aren't terminated with addition to context switch time for (list<PCB *>::iterator it = jobs.begin(); it != jobs.end(); it++) if(!strcmp((*it)->state.c_str(), "terminated")) (*it)->contextSwitchTime += 5; // First item in main loop // move items from waitQ into readyQ if interrupt time hit if(!waitQ.empty()) { while (waitQ.front()->interruptTime <= masterClock) { PCB * temp = waitQ.front(); waitQ.pop(); readyQ.push(temp); temp->state = "ready"; if(waitQ.empty()) break; } } // Second item in main loop // Update waiting time for all items in ready queue with latest cycle time from vm.run() for (list<PCB *>::iterator it = jobs.begin(); it != jobs.end(); it++) if(strcmp((*it)->state.c_str(), "ready")) (*it)->waitingTime += vm.clock; if(!(running == NULL)) { // update master clock and cpu time masterClock += vm.clock; running->cpuTime += vm.clock; // main switch to handle return code, if terminated set, output errorcode. switch (code) { case 0: getPCBFromVM(); readyQ.push(running); break; case 1: running->state = "terminated"; break; case 2: running->state = "terminated"; outputErrorCode("Out-of-Bound Reference"); break; case 3: running->state = "terminated"; outputErrorCode("Stack Overflow"); break; case 4: running->state = "terminated"; outputErrorCode("Stack Underflow"); break; case 5: running->state = "terminated"; outputErrorCode("Invalid OPCode"); break; case 6: { int readIn; running->readIntoRegister >> readIn; int readReg = vm.sr; readReg &= 0x300; readReg >>= 8; if(readReg < 0 || readReg > 3) { outputErrorCode("Invalid IO Register"); break; } vm.reg[readReg] = readIn; masterClock++; running->ioTime += 27; running->cpuTime++; waitQ.push(running); running->state = "waiting"; getPCBFromVM(); running->interruptTime = masterClock + 28; break; } case 7: { int writeToReg = vm.sr; writeToReg &= 0x300; writeToReg >>= 8; int temp = vm.reg[writeToReg] & 0x8000; if (temp) temp = vm.reg[writeToReg] | 0xffff0000; else temp = vm.reg[writeToReg] & 0xffff; running->writeToRegister << temp << endl; masterClock++; running->ioTime += 27; running->cpuTime++; waitQ.push(running); running->state = "waiting"; getPCBFromVM(); running->interruptTime = masterClock + 28; break; } default: outputErrorCode("Invalid Return Code"); running->state = "terminated"; break; } running = NULL; } // end if running loop // Third item in main loop // if all items in waitQ, update masterclock to get first item out of waitQ if(readyQ.empty() && !waitQ.empty()) { int temp = waitQ.front()->interruptTime - masterClock; masterClock += temp; idleClock += temp; readyQ.push(waitQ.front()); waitQ.front()->state = "ready"; waitQ.pop(); // update idle time for all non terminated process in jobs list for (list<PCB *>::iterator it = jobs.begin(); it != jobs.end(); it++) if(!strcmp((*it)->state.c_str(), "terminated")) (*it)->idleTime += temp; } // move next process from readyQ into running state, copy over pcb contents if(!readyQ.empty()) { running = readyQ.front(); running->state = "running"; readyQ.pop(); givePCBToVM(); } } // end main process loop
void OS::start() { // Get the s files system("ls *.s > progs"); fstream readProgs; readProgs.open("progs", ios::in); if (!readProgs.is_open()) { cout << "cant open progs\n"; exit(1); } string line; getline(readProgs, line); while (!readProgs.eof()) { as.assemble(line); // assemble the files //make the PCB for each file, put the jobs list, and then the ready queue PCB * p = new PCB; jobs.push_back(p); readyQ.push(p); p->state = "ready"; string fileName = line.erase(line.length() -2, 2); // assign file names, input and outputs p->originalfilename = fileName + ".o"; p->readfilename = fileName + ".in"; p->writefilename = fileName + ".out"; p->stfilename = fileName + ".st"; // Read in files p->openReadInFileStream(); p->openWriteOutFileStream(); //read into mem int base, limit; vm.loadIntoMemory(p->originalfilename, &base, &limit); p->base = base; p->limit = limit; p->pc = base; getline(readProgs, line); } readProgs.close(); system("rm progs"); // copy item 1 in readyQueue to running , load pcb data to vm running = readyQ.front(); readyQ.pop(); givePCBToVM(); int code = 0; while (!done()) // main loops { code = 0; vm.run(); code = vm.sr; code = code & 0xe0; code >>= 5; masterClock += 5; contextSwitchClock += 5; for (list<PCB *>::iterator it = jobs.begin(); it != jobs.end(); it++) if(!strcmp((*it)->state.c_str(), "terminated")) (*it)->contextSwitchTime += 5; // if interrupt move. if(!waitQ.empty()) { while (waitQ.front()->interruptTime <= masterClock) { PCB * temp = waitQ.front(); waitQ.pop(); readyQ.push(temp); temp->state = "ready"; if(waitQ.empty()) break; } } for (list<PCB *>::iterator it = jobs.begin(); it != jobs.end(); it++) if(strcmp((*it)->state.c_str(), "ready")) (*it)->waitingTime += vm.clock; if(!(running == NULL)) { //update clocks masterClock += vm.clock; running->cpuTime += vm.clock; //them errors cases switch (code) { case 0: getPCBFromVM(); readyQ.push(running); break; case 1: running->state = "terminated"; break; case 2: running->state = "terminated"; outputErrorCode("Out-of-Bound Reference"); break; case 3: running->state = "terminated"; outputErrorCode("Stack Overflow"); break; case 4: running->state = "terminated"; outputErrorCode("Stack Underflow"); break; case 5: running->state = "terminated"; outputErrorCode("Invalid OPCode"); break; case 6: { int readIn; running->readIntoRegister >> readIn; int readReg = vm.sr; readReg &= 0x300; readReg >>= 8; if(readReg < 0 || readReg > 3) { outputErrorCode("Invalid IO Register"); break; } vm.reg[readReg] = readIn; masterClock++; running->ioTime += 27; running->cpuTime++; waitQ.push(running); running->state = "waiting"; getPCBFromVM(); running->interruptTime = masterClock + 28; break; } case 7: { int writeToReg = vm.sr; writeToReg &= 0x300; writeToReg >>= 8; int temp = vm.reg[writeToReg] & 0x8000; if (temp) temp = vm.reg[writeToReg] | 0xffff0000; else temp = vm.reg[writeToReg] & 0xffff; running->writeToRegister << temp << endl; masterClock++; running->ioTime += 27; running->cpuTime++; waitQ.push(running); running->state = "waiting"; getPCBFromVM(); running->interruptTime = masterClock + 28; break; } default: outputErrorCode("Invalid Return Code"); running->state = "terminated"; break; } running = NULL; } //update clock after item 1 if(readyQ.empty() && !waitQ.empty()) { int temp = waitQ.front()->interruptTime - masterClock; masterClock += temp; idleClock += temp; readyQ.push(waitQ.front()); waitQ.front()->state = "ready"; waitQ.pop(); for (list<PCB *>::iterator it = jobs.begin(); it != jobs.end(); it++) if(!strcmp((*it)->state.c_str(), "terminated")) (*it)->idleTime += temp; } if(!readyQ.empty()) { running = readyQ.front(); running->state = "running"; readyQ.pop(); givePCBToVM(); } }