rendered paste body/*
Bhaktavatsalam Nallanthighal
Poly ID: 0394896
Operating Systems Project I, Fall 2010
Prof. John Sterling
*/
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
#include <deque>
using namespace std;
typedef struct Configuration_t {
public:
string ProcessFile;
double ContextSwitchDelay;
double IOdelay;
double AgingRatio;
bool Debug;
ostream& dump(ostream& outputStream=cout) {
outputStream << "ProcessFile=" << ProcessFile << endl
<< "ContextSwitchDelay=" << ContextSwitchDelay << endl
<< "IOdelay=" << IOdelay << endl
<< "AgingRatio=" << AgingRatio << endl
<< "Debug=";
if(Debug==1) {
cout << "true" << endl;
}
else {
cout << "false" << endl;
}
return outputStream;
}
} Configuration;
Configuration configuration;
class Process {
public:
Process(string infoString) {
istringstream pinfoStream(infoString);
pinfoStream >> pid;
pinfoStream >> arrivalTime;
pinfoStream >> totalCPUTime;
pinfoStream >> averageCPUBurst;
/* It never ran... er... executed */
remainingCPUTime = totalCPUTime;
/* Not in burst */
remainingBurstTime = 0;
}
ostream& dump(ostream& outputStream=cout) {
outputStream << pid << "\t"
<< arrivalTime << "\t"
<< totalCPUTime << "\t"
<< averageCPUBurst << endl;
return outputStream;
}
void StartRunning() {
remainingBurstTime = averageCPUBurst;
}
void DoRun() {
--remainingBurstTime;
--remainingCPUTime;
}
void StartWaiting() {
remainingWaitTime = configuration.IOdelay;
}
void DoWait() {
--remainingWaitTime;
}
/* The variables */
int pid;
int arrivalTime;
int totalCPUTime;
int averageCPUBurst;
/* Auxillary variables */
int remainingCPUTime;
int remainingBurstTime;
int remainingWaitTime;
};
/* Displays info about the programmer */
void displayMyInfo();
/* Returns structured configuration information read from the configuration file */
void readConfiguration(string);
/* Reads process descriptions file and reads in information into Process structures
represented by the input parametere */
void readProcessesInfo(vector<Process>&);
/* Execute the FCFS algorithm on the input provided */
string doFCFS(vector<Process>);
int main() {
/* Display my information */
displayMyInfo();
/* Read in the configuration information */
readConfiguration("scheduling.txt");
if(configuration.Debug) {
cout << "\nCONFIGURATION\n"
<< "==============" << endl;
configuration.dump();
}
/* Read in the processes information */
vector<Process> processes;
readProcessesInfo(processes);
if(configuration.Debug) {
cout << "\nPROCESSINFO\n"
<< "============" << endl;
for(size_t i=0; i<processes.size(); ++i) {
processes[i].dump();
}
}
/* Execute the FCFS algorithm on the data */
string FCFS_profile = doFCFS(processes);
//cout << FCFS_profile << endl;
}
void readProcessesInfo(vector<Process>& processes) {
/* Open the file into an input stream */
ifstream inputStream(configuration.ProcessFile.c_str());
if(inputStream.fail()) {
cout << "Could not open file: " << configuration.ProcessFile << endl;
exit(1);
}
string pinfoString;
while(getline(inputStream, pinfoString, '\n')) {
/* Create new Process object from the available information */
Process newProcess(pinfoString);
/* Push a copy onto the vector */
processes.push_back(newProcess);
}
/* Close the file input stream */
inputStream.close();
}
void readConfiguration(string filename) {
/* Open the file into an input stream */
ifstream inputStream(filename.c_str());
if(inputStream.fail()) {
cout << "Could not open file: " << filename << endl;
exit(1);
}
/* Read each line and extract information into the configuration structure */
string token;
while(getline(inputStream, token, '\n')) {
istringstream tokenStream(token);
string key;
getline(tokenStream, key, '=');
if(key == "ProcessFile") {
tokenStream >> configuration.ProcessFile;
}
else if(key == "ContextSwitchDelay") {
tokenStream >> configuration.ContextSwitchDelay;
}
else if(key == "AgingRatio") {
tokenStream >> configuration.AgingRatio;
}
else if(key == "Debug") {
string temp;
tokenStream >> temp;
if(temp == "true") {
configuration.Debug = true;
}
else {
configuration.Debug = false;
}
}
else if(key == "IOdelay") {
tokenStream >> configuration.IOdelay;
}
}
/* Close the file input stream*/
inputStream.close();
}
void displayMyInfo() {
cout << "Bhaktavatsalam Nallanthighal" << endl
<< "ID 0394896" << endl
<< "Operating Systems Project I" << endl
<< "Prof. John Sterling" << endl
<< "--------------------------------" << endl;
}
string doFCFS(vector<Process> processes) {
string profile = "";
unsigned int time = 0;
deque<Process *> readyQueue;
deque<Process *> waitingQueue;
Process *running = NULL;
cout << "\n============\nFCFS:\n============ " << endl;
/* While there still is a process that can be seen somewhere */
do {
for(size_t i=0; i<processes.size(); ++i) {
/* Arrive -> Ready */
if(processes[i].arrivalTime==time) {
cout << "Time " << time << ": Moving process " << processes[i].pid << " from arrival to ready." << endl;
readyQueue.push_back(&processes[i]);
}
}
for(size_t i=0; i<waitingQueue.size(); ++i) {
/* Waiting->Ready */
if(waitingQueue[i]->remainingWaitTime<=0) {
cout << "Time " << time << ": Moving process " << waitingQueue[i]->pid << " from waiting to ready." << endl;
readyQueue.push_back(waitingQueue[i]);
waitingQueue[i] = waitingQueue.back();
waitingQueue.pop_back();
}
/* Keep Waiting */
else {
waitingQueue[i]->DoWait();
}
}
/* Start running */
if(running==NULL) {
running = readyQueue.front();
readyQueue.pop_front();
cout << "Time " << time << ": Moving process " << running->pid
<< " from ready to running. Remaining time: " << running->remainingCPUTime << endl;
running->StartRunning();
running->DoRun();
}
else {
/* Running -> Waiting */
if(running->remainingBurstTime==0) {
/* Done Executing */
if(processes[i].remainingCPUTime<=0) {
cout << "Time " << time << ": Process " << processes[i].pid << " finished." << endl;
processes[i] = processes[processes.size()-1];
processes.pop_back();
}
else {
cout << "Time " << time << ": Process " << running->pid
<< " ending burst (" << running->averageCPUBurst
<< "). Remaining time: " << running->remainingCPUTime << endl;
running->StartWaiting();
running->DoWait();
waitingQueue.push_back(running);
running = NULL;
}
}
/* Continue Running */
else {
running->DoRun();
}
}
++time;
}
while(!(readyQueue.empty() && waitingQueue.empty() && running==NULL));
return profile;
}