I had to reset my compiler, i just need someone to compile and run on their C++ compiler and give me the result. It’s going to take the rest of the night for me to install cygwin. The file is attached.
#define ENABLE_COMMANDER
#define ENABLE_REPORTER
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
class Instruction
{
public:
char operation;
int intArg;
string stringArg;
}
;
class Cpu {
public:
vector
int programCounter;
int value;
int timeSlice;
int timeSliceUsed;
};
enum State {
STATE_READY,
STATE_RUNNING,
STATE_BLOCKED,
STATE_END
};
class PcbEntry {
public:
int processId;
int parentProcessId;
vector
unsigned int programCounter;
int value;
unsigned int priority;
State state;
unsigned int startTime;
unsigned int timeUsed;
};
// The number of valid priorities.
#define NUM_PRIORITIES 4
// An array that maps priorities to their allotted time slices.
static const unsigned int PRIORITY_TIME_SLICES[NUM_PRIORITIES] = {
1,
2,
4,
8
};
unsigned int timestamp = 0;
Cpu cpu;
// For the states below, -1 indicates empty (since it is an invalid index).
int runningState = -1; // The index of the running process in the PCB table.
// readyStates is an array of queues. Each queue holds PCB indices for ready processes
// of a particular priority.
deque
deque
deque
// In this implementation, we’ll never explicitly clear PCB entries and the
// index in the table will always be the process ID. These choices waste memory,
// but since this program is just a simulation it the easiest approach.
// Additionally, debugging is simpler since table slots and process IDs are
// never re-used.
vector
double cumulativeTimeDiff = 0;
int numTerminatedProcesses = 0;
// Sadly, C++ has no built-in way to trim strings:
string &trim(string &argument)
{
string whitespace(” \t\n\v\f\r”);
size_t found = argument.find_last_not_of(whitespace);
if (found != string::npos) {
argument.erase(found + 1);
argument.erase(0, argument.find_first_not_of(whitespace));
}
else {
argument.clear(); // all whitespace
}
return argument;
}
bool createProgram(const string &filename, vector
{
ifstream file;
int lineNum = 0;
program.clear();
file.open(filename.c_str());
if (!file.is_open()) {
cout << "Error opening file " << filename << endl;
return false;
}
while (file.good()) {
string line;
getline(file, line);
trim(line);
if (line.size() > 0) {
Instruction instruction;
instruction.operation = toupper(line[0]);
instruction.stringArg = trim(line.erase(0, 1));
stringstream argStream(instruction.stringArg);
switch (instruction.operation) {
case ‘S’:
// Integer argument.
case ‘A’:
// Integer argument.
case ‘D’:
// Integer argument.
case ‘F’:
// Integer argument.
if (!(argStream >> instruction.intArg)) {
cout << filename << ":" << lineNum
<< " - Invalid integer argument "
<< instruction.stringArg << " for "
<< instruction.operation << " operation" << endl;
file.close();
return false;
}
break;
case ‘B’:
// No argument.
case ‘E’:
// No argument.
break;
case ‘R’:
// String argument.
// Note that since the string is trimmed on both ends,
// filenames with leading or trailing whitespace (unlikely)
// will not work.
if (instruction.stringArg.size() == 0) {
cout << filename << ":" << lineNum
<< " - Missing string argument" << endl;
file.close();
return false;
}
break;
default:
cout << filename << ":" << lineNum
<< " - Invalid operation, " << instruction.operation
<< endl;
file.close();
return false;
}
program.push_back(instruction);
}
lineNum++;
}
file.close();
return true;
}
// Implements the S operation.
void set(int value)
{
cpu.value = value;
cout << "Set CPU value to " << value << endl;
}
// Implements the A operation.
void add(int value)
{
cpu.value += value;
cout << "Incremented CPU value by " << value << endl;
}
// Implements the D operation.
void decrement(int value)
{
cpu.value -= value;
cout << "Decremented CPU value by " << value << endl;
}
// Performs scheduling.
void schedule()
{
// TODO: Debug and test
//If runningState != -1 AND the cpu.timeSliceUsed equals or exceeds
// cpu.timeSlice:
cout <<" cpu timeslice Used " << cpu.timeSliceUsed< cout <<" cpu timeslice " << cpu.timeSlice< if ((runningState != -1) && (cpu.timeSliceUsed >= cpu.timeSlice)){ // 1. Get the PCB entry for runningState. PcbEntry *myPCB = pcbTable[runningState]; // 2. Lower the process priority (remember since the highest priority is zero, // you actually have to increment the priority to lower it). Also make sure to // not increment the priority past its maximum value. if (myPCB->priority >= 0 && myPCB->priority < (NUM_PRIORITIES - 1)) myPCB->priority++; // 3. Push runningState on to the end of the correct readyStates queue (hint: use // pcbEntry.priority to select the correct queue. switch (myPCB->priority) { case 0 : readyStates[0].push_back(runningState);
break; case 1 : readyStates[1].push_back(runningState); break; case 2 : readyStates[2].push_back(runningState); break; case 3 : readyStates[3].push_back(runningState); break; default: cout << "Invalid running state" << endl; break; } // 4. Update the pcbEntry: // a. Set state to STATE_READY. // b. Set the programCounter to cpu.programCounter. // c. Set the value to cpu.value. // d. Increment timeUsed by cpu.timeSliceUsed. myPCB->state = STATE_READY; myPCB->programCounter = cpu.programCounter; myPCB->value = cpu.value; myPCB->timeUsed = myPCB->timeUsed + cpu.timeSliceUsed; cout << " time this process has used = " << myPCB->timeUsed << endl; cout << " scheduler is ending process and decreasing priority to "<< myPCB->priority <<"\n" << endl; // 5. Set runningState to -1. runningState = -1; } if (runningState != -1) { //the correct priority program is running cout << " correct process is running exiting scheduler" << endl; return; } cout << " loading new process from "; // TODO: Debug and test // Get a new process to run, if possible, from the ready queue in // priority order. Remember that the highest priority is zero! The code below // needs to be updated/replaced since right now it only uses the highest priority // queue. if(!readyStates[0].empty()){ runningState = readyStates[0].front(); cout << "priority 0 " << endl; readyStates[0].pop_front(); } else if(!readyStates[1].empty()){ runningState = readyStates[1].front(); cout << "priority 1" << endl; readyStates[1].pop_front(); } else if(!readyStates[2].empty()){ runningState = readyStates[2].front(); cout << "priority 2 " << endl; readyStates[2].pop_front(); } else if(!readyStates[3].empty()){ runningState = readyStates[3].front(); cout << "priority 3 " << endl; readyStates[3].pop_front(); } else cout << "ERROR ready state has invalid state entries"; // Make sure there is a process to run. if (runningState != -1) { // Mark the process as running. PcbEntry *pcbEntry = pcbTable[runningState]; pcbEntry->state = STATE_RUNNING; // Update the CPU with new PCB entry details. cpu.pProgram = &pcbEntry->program; cpu.programCounter = pcbEntry->programCounter; cpu.value = pcbEntry->value; // TODO: Debug and test // Set cpu.timeSlice to the correct value (hint: use the // global PRIORITY_TIME_SLICES array and pcbEntry->priority) switch (pcbEntry->priority) { cpu.timeSlice = PRIORITY_TIME_SLICES[0]; cout << " setting cpu.timeslice to 1"< break; cpu.timeSlice = PRIORITY_TIME_SLICES[1]; cout << " setting cpu.timeslice to 2"< break; cpu.timeSlice = PRIORITY_TIME_SLICES[2]; cout << " setting cpu.timeslice to 4"< break; cpu.timeSlice = PRIORITY_TIME_SLICES[3]; cout << " setting cpu.timeslice to 8"< break; cout << "ERROR setting cpu timeslice Invalid priority" << endl; break; } // TODO: Debug and test // Set cpu->timeSliceUsed to zero. cpu.timeSliceUsed = 0; cout << "Process running, pid = " << pcbEntry->processId << endl; } // Implements the B operation. void block() { //TODO there is a problem with pcb time used counter will this fix it pcbEntry->timeUsed += cpu.timeSliceUsed + 1;//add 1 for CPU time to block the process // TODO: Debug and test // Raise the process priority (remember since the highest priority is zero, // you actually have to decrement the priority to raise it). Also make sure to // not decrement the priority below zero. if (pcbEntry->priority > 0) pcbEntry->priority–; blockedState.push_back(runningState); pcbEntry->state = STATE_BLOCKED; pcbEntry->programCounter = cpu.programCounter; pcbEntry->value = cpu.value; runningState = -1; cout << "Blocked process, pid = " << pcbEntry->processId << endl; } // Implements the E operation. void end() { //TODO there is a problem with pcb timused will this fix it? pcbEntry->timeUsed = pcbEntry->timeUsed + cpu.timeSliceUsed + 1;//add 1 to account for e operation // Add 1 to account for the time to execute the E operation. cumulativeTimeDiff += (double)(timestamp + 1 – pcbEntry->startTime); numTerminatedProcesses++; cout << "Ended process, pid = " << pcbEntry->processId << endl; pcbEntry->state = STATE_END; deadState.push_back(runningState); runningState = -1; // Implements the F operation. void fork(int value) { int pcbIndex = (int)pcbTable.size(); PcbEntry *runningPcbEntry = pcbTable[runningState]; PcbEntry *pcbEntry = new PcbEntry(); pcbEntry->processId = pcbIndex; pcbEntry->parentProcessId = runningPcbEntry->processId; pcbEntry->program = runningPcbEntry->program; pcbEntry->programCounter = cpu.programCounter; pcbEntry->priority = runningPcbEntry->priority; pcbEntry->state = STATE_READY; pcbEntry->startTime = timestamp + 1; pcbEntry->timeUsed = 0; pcbTable.push_back(pcbEntry); // TODO: debug and test //Update the line below to use the correct readyStates queue. readyStates[pcbEntry->priority].push_back(pcbIndex); cout << "Forked new process, pid = " << pcbEntry->processId << endl; if ((value < 0) || (cpu.programCounter + value >= (int)cpu.pProgram->size())) { cout << "Error executing F operation, ending parent process" << endl; end(); } cpu.programCounter += value; } // Implements the R operation. void replace(string &argument) { if (!createProgram(argument, *cpu.pProgram)) { cout << "Error executing R operation, ending process" << endl; end(); cpu.programCounter = 0; cout << "Replaced process with " << argument << ", pid = " << pcbTable[runningState]->processId << endl; } // Implements the Q command. void quantum() { if (runningState == -1) { cout << "No processes are running" << endl; ++timestamp; return; if (cpu.programCounter < (int)cpu.pProgram->size()) { instruction = (*cpu.pProgram)[cpu.programCounter]; cpu.programCounter++; } else { cout << "End of program reached without E operation" << endl; instruction.operation = ‘E’; } switch (instruction.operation) { set(instruction.intArg); break; add(instruction.intArg); break; decrement(instruction.intArg); break; block(); break; end(); break; fork(instruction.intArg); break; replace(instruction.stringArg); break; timestamp++; // TODO: degug and test // Increment cpu.timeSliceUsed. cpu.timeSliceUsed++; schedule(); } // Implements the U command. void unblock() { if (!blockedState.empty()) { int pcbIndex = blockedState.front(); PcbEntry *pcbEntry = pcbTable[pcbIndex]; blockedState.pop_front(); // TODO: debug and test. PHIL << "this process does not increment the timeStamp, because it comes from Commander?" // Update the line below to use the correct readyStates queue. readyStates[pcbEntry->priority].push_back(pcbIndex); pcbEntry->state = STATE_READY; cout << "Unblocked process, pid = " << pcbEntry->processId << endl; } schedule(); void printReadyQue(int *myArray){ for (unsigned int j = 0; j < NUM_PRIORITIES; j++){ if (!readyStates[j].empty()){ cout << "READY STATE PRIORITY " << j << " QUEUE:\n pid | ppid | priority | value | start time | cpu time used |" << endl; for (unsigned int i = 0; i < readyStates[j].size(); i++) { int pcbIndex = readyStates[j][i]; PcbEntry *pcbEntry = pcbTable[pcbIndex]; printf(“% *d % *d % *d % *d % *d % *d \n” , 7 , pcbEntry->processId , 11, pcbEntry->parentProcessId, 10, pcbEntry->priority, 10, pcbEntry->value, 10, pcbEntry->startTime, 10, pcbEntry->timeUsed); myArray[j] = myArray[j]+1;//increment prioriety myArray[4] += pcbEntry->timeUsed;//sum } } } void printProcess(int *myArray){ int myTimeUsed = 0; const int NUM_STATE = 4; State myState[NUM_STATE] = {STATE_READY , STATE_RUNNING, STATE_BLOCKED, STATE_END}; for (int j =1; j < NUM_STATE; j++){ switch (j) { case 1: cout << "RUNNING PROCESSSES:\n pid | ppid | priority | value | start time | cpu time used |" << endl; break; case 2: if (!blockedState.empty()) cout << "BLOCKED PROCESSSES:\n pid | ppid | priority | value | start time | cpu time used |" << endl; break; case 3: if (!deadState.empty()) cout << "DEAD PROCESSSES:\n pid | ppid | priority | value | start time | cpu time used |" << endl; break; default: cout << "ERROR!!!!!"; break; } for(unsigned int readyEntry = 0; readyEntry < pcbTable.size(); readyEntry++){ if (pcbTable[readyEntry]->state == myState[j] ){ if (pcbTable[readyEntry]->state == STATE_RUNNING)myTimeUsed = pcbTable[runningState]->timeUsed+cpu.timeSliceUsed; else myTimeUsed = pcbTable[readyEntry]->timeUsed; printf(“% *d % *d % *d % *d % *d % *d \n” , 7 , pcbTable[readyEntry]->processId , 11, pcbTable[readyEntry]->parentProcessId, 10, pcbTable[readyEntry]->priority, 10, pcbTable[readyEntry]->value, 10, pcbTable[readyEntry]->startTime, 10, myTimeUsed); myArray[pcbTable[readyEntry]->priority]++;//increment prioriety myArray[4] += myTimeUsed; } void printPriorieties(int *prioritieList){ cout << endl; for (int i =0; i<4; i++){ if ( prioritieList[i] != 0) cout << "number of processes with priority "<< i << " is: " << prioritieList[i] << endl; } if ((int)timestamp == prioritieList[4]) cout << "\nCURRENT TIME: " << timestamp << " = " << "total CPU TIME USED: "<< prioritieList[4] << endl; else cout << "PCB total time does not match this can only happen if no process was running" << endl; } // Implements the P command. void print() { #ifdef ENABLE_REPORTER pid_t pid; pid = fork(); if (pid == -1) { cout << "fork:" << strerror(errno) << endl; return; if (pid != 0) { // Wait for the reporter process to exit. wait(NULL); return; #endif #ifdef ENABLE_REPORTER //Implement all of the printing logic. int prioritieList[NUM_PRIORITIES + 1] = {0,0,0,0,0};//+ one for sum[4] counter cout << "\n----------------------------------------------------------------------" << endl; //cout << "CURRENT TIME: " << timestamp<< endl; printReadyQue(prioritieList);//prints the processes in ready state by que printProcess(prioritieList);// prints the rest of the processes printPriorieties(prioritieList); cout << "----------------------------------------------------------------------\n"< _exit(EXIT_SUCCESS); #endif // Function that implements the process manager. int runProcessManager(int fileDescriptor) { // Attempt to create the init process. if (!createProgram(“/home/philwilliammee/eclipseworkspace/CDT/ilab3/src/init” , pcbEntry->program)) { delete pcbEntry; return EXIT_FAILURE; } pcbEntry->processId = (int)pcbTable.size(); pcbEntry->parentProcessId = -1; pcbEntry->programCounter = 0; pcbEntry->value = 0; pcbEntry->priority = 0; pcbEntry->state = STATE_RUNNING; pcbEntry->startTime = 0; pcbEntry->timeUsed = 0; pcbTable.push_back(pcbEntry); runningState = pcbEntry->processId; cout << "Running init process, pid = " << pcbEntry->processId << endl; cpu.pProgram = &(pcbEntry->program); cpu.programCounter = pcbEntry->programCounter; timestamp = 0; double avgTurnaroundTime = 0; // Loop until a ‘T’ is read, then terminate. char ch; do { // Read a command character from the pipe. if (read(fileDescriptor, &ch, sizeof(ch)) != sizeof(ch)) { // Assume the parent process exited, breaking the pipe. break; // Ignore whitespace characters. if (isspace(ch)) { continue; } // Convert commands to a common case so both lower and uppercase // commands can be used. ch = toupper(ch); switch (ch) { case ‘Q’: quantum(); break; case ‘U’: unblock(); break; case ‘P’: print(); break; case ‘T’: if (numTerminatedProcesses != 0) { avgTurnaroundTime = cumulativeTimeDiff / (double)numTerminatedProcesses; } cout << "The average turnaround time is " << avgTurnaroundTime << "." << endl; break; cout << "Unknown command, " << ch << endl; break; } while (ch != ‘T’); // Cleanup any remaining PCB entries. for (vector it != pcbTable.end(); it++) { delete *it; } pcbTable.clear(); return EXIT_SUCCESS; } // Main function that implements the commander. int main(int argc, char *argv[]) { #ifdef ENABLE_COMMANDER int pipeDescriptors[2]; pid_t processMgrPid; char ch; int result; // Create a pipe. if (pipe(pipeDescriptors) == -1) { // Print an error message to help debugging. cout << "pipe: " << strerror(errno) << endl; return EXIT_FAILURE; // Create the process manager process. processMgrPid = fork(); if (processMgrPid == -1) { // Print an error message to help debugging. cout << "fork: " << strerror(errno) << endl; return EXIT_FAILURE; if (processMgrPid == 0) { // The process manager process is running. // Close the unused write end of the pipe for the process manager // process. close(pipeDescriptors[1]); // Run the process manager. result = runProcessManager(pipeDescriptors[0]); // Close the read end of the pipe for the process manager process (for // cleanup purposes). close(pipeDescriptors[0]); _exit(result); } else { // The commander process is running. // Close the unused read end of the pipe for the commander process. close(pipeDescriptors[0]); // Loop until a ‘T’ is written or until the pipe is broken. do { sleep(1); cout << "Input a command: "; // Read a command character from the standard input. cin >> ch; cout << endl; // Pass commands to the process manager process via the pipe. if (write(pipeDescriptors[1], &ch, sizeof(ch)) != sizeof(ch)) { // Assume the child process exited, breaking the pipe. break; } while (ch != ‘T’); // Wait for the process manager to exit. wait(&result); // Close the write end of the pipe for the commander process (for // cleanup purposes). return result; #else // Run the Process Manager directly. return runProcessManager(fileno(stdin)); #endif
case 0 :
case 1 :
case 2 :
case 3 :
default:
}
PcbEntry *pcbEntry = pcbTable[runningState];
PcbEntry *pcbEntry = pcbTable[runningState];
}
pcbEntry->value = cpu.value;
return;
}
Instruction instruction;
}
case ‘S’:
case ‘A’:
case ‘D’:
case ‘B’:
case ‘E’:
case ‘F’:
case ‘R’:
}
}
}
}
}
}
}
}
// TODO: debug and test
}
PcbEntry *pcbEntry = new PcbEntry();
cpu.value = pcbEntry->value;
}
default:
}
}
}
}
close(pipeDescriptors[1]);
}
}