I just need someone to compile this code and give me the screen shot

profilejontha11
lab3_7.rtf

#define ENABLE_COMMANDER

#define ENABLE_REPORTER

#include <cctype> // for toupper()

#include <cstdlib> // for EXIT_SUCCESS and EXIT_FAILURE

#include <cstring> // for strerror()

#include <cerrno> // for errno

#include <deque> // for deque (used for ready and blocked queues)

#include <fstream> // for ifstream (used for reading simulated process programs)

#include <iostream> // for cout, endl, and cin

#include <sstream> // for stringstream (for parsing simulated process programs)

#include <sys/wait.h> // for wait()

#include <unistd.h> // for pipe(), read(), write(), close(), fork(), and _exit()

#include <vector> // for vector (used for PCB table)

using namespace std;

class Instruction {

public:

char operation;

int intArg;

string stringArg;

};

class Cpu {

public:

vector<Instruction> *pProgram;

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<Instruction> program;

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<int> readyStates[NUM_PRIORITIES];

deque<int> blockedState; // A queue fo PCB indices for blocked processes.

deque<int> deadState;

// 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<PcbEntry *> pcbTable;

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<Instruction> &program)

{

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<<endl;

cout <<" cpu timeslice " << cpu.timeSlice<<endl;

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)

{

case 0 :

cpu.timeSlice = PRIORITY_TIME_SLICES[0];

cout << " setting cpu.timeslice to 1"<<endl;

break;

case 1 :

cpu.timeSlice = PRIORITY_TIME_SLICES[1];

cout << " setting cpu.timeslice to 2"<<endl;

break;

case 2 :

cpu.timeSlice = PRIORITY_TIME_SLICES[2];

cout << " setting cpu.timeslice to 4"<<endl;

break;

case 3 :

cpu.timeSlice = PRIORITY_TIME_SLICES[3];

cout << " setting cpu.timeslice to 8"<<endl;

break;

default:

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()

{

PcbEntry *pcbEntry = pcbTable[runningState];

//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()

{

PcbEntry *pcbEntry = pcbTable[runningState];

//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->value = cpu.value;

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();

return;

}

cpu.programCounter = 0;

cout << "Replaced process with " << argument << ", pid = "

<< pcbTable[runningState]->processId << endl;

}

// Implements the Q command.

void quantum()

{

Instruction instruction;

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) {

case 'S':

set(instruction.intArg);

break;

case 'A':

add(instruction.intArg);

break;

case 'D':

decrement(instruction.intArg);

break;

case 'B':

block();

break;

case 'E':

end();

break;

case 'F':

fork(instruction.intArg);

break;

case 'R':

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

// TODO: debug and test

//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"<<endl;

_exit(EXIT_SUCCESS);

#endif

}

// Function that implements the process manager.

int runProcessManager(int fileDescriptor)

{

PcbEntry *pcbEntry = new PcbEntry();

// 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;

cpu.value = pcbEntry->value;

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;

default:

cout << "Unknown command, " << ch << endl;

break;

}

} while (ch != 'T');

// Cleanup any remaining PCB entries.

for (vector<PcbEntry *>::iterator it = pcbTable.begin();

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).

close(pipeDescriptors[1]);

}

return result;

#else

// Run the Process Manager directly.

return runProcessManager(fileno(stdin));

#endif

}