Question: Objectives: Explore the Process state models from an implementation point of view. Practice using basic queue data types and implementing in C. Use C/C++ data
Objectives: Explore the Process state models from an implementation point of view. Practice using basic queue data types and implementing in C. Use C/C++ data structures to implement a process control block and round robin scheduling queues. Learn about Process switching and multiprogramming concepts. Description: In this assignment you will simulate a Three-State process model (ready, running and blocked) and a simple process control block structure as discussed in Chapter 3. Your program will read input and directives from a le. The input describes a time sequence of events that occur. These are the full set of events you will simulate: Event Description cpu The processor executes for 1 time step the currently running process new A new process is created and put at tail of the ready queue done The currently running process has nished wait X The currently running process has done an I/O operation and is waiting on event X event X Event X has occurred, the process waiting on that event should be made ready. 1 The input le will simply be a list of events that occur in the system, in the order they are to occur. For example: ----- simulation-01.sim -------- new cpu cpu cpu new cpu cpu cpu cpu wait 1 cpu cpu event 1 cpu cpu done cpu cpu cpu cpu exit ---------------------------------- Your task is to read in the events, and simulate the creation and execution of processes in the system as they move through the various three-states of their process life cycle. You need to Dene a simple process control block (PCB) to hold information about all processes currently running in your system. The PCB can be a simple C struct or a C++ class. At a minimum you need to have a eld for the process identier, the process state (Ready, Running or Blocked). You need to also keep track of the time step that the process entered the system, and the number of steps the process has been running. Minimal credit will be given to programs that at least handle new events and create a process in a simulated PCB. You will need a ready queue of some kind. You can use a simple C array to hold your queue, though you will need to implement some 2 simple queuing functions in that case. You may also use the C++ Standard Template Library (STL) vector and/or queue data structures to implement your queues. You will need to implement a simple dispatcher function. Whenever a cpu event occurs, and no process is currently running, you should select the next Ready process from your ready queue and start it running on the processor. You need to also implement a simple time slicing mechanism. The time slice value to use will be passed into your program when it is started. At the end of a cpu cycle, you should check if the currently running process has executed for its full time quantum. In that case, the currently running process should timeout, and be returned to the end of the Ready queue. new events should cause a new process to be created (including creating its PCB and lling it in). New events will be placed on the end of the ready queue after being created. You should assign each new event a process identier. The process identier should be a simple integer value, and you should start numbering processes from 1. For a done event, if a process is currently running it should then be released. It should be removed from the CPU, and not placed back on the ready or blocked queue. If a done occurs when the CPU is idle, then nothing will happen as a result of this event. A wait event simulates the currently running process performing some I/O operation. If a wait occurs, the currently running process should become blocked and put on the blocked queue. You also need an entry in the PCB so you know what event the process is waiting for. The wait event is followed by an integer number, which is an indication of the type of event the process has requested. Likewise the event directive simulates the nishing of some I/O operation. When an event occurs, you should scan your blocked processes and make any process ready that was waiting on that event. The integer value following an event indicates the type of event that just occurred. You have been given some example event sequences (simulation-01.sim, simulation-02.sim, etc.) along with the expected output for those sequence 3 of events (simulation-01.res, simulation-02.res, etc.). The output of your program should be sent to standard output. The correct output for the simulation-01.sim simulation is: Time: 1 CPU (currently running): pid=1, state=RUNNING, start=1, slice=1, Ready Queue: EMPTY Blocked Queue: EMPTY Time: 2 CPU (currently running): pid=1, state=RUNNING, start=1, slice=2, Ready Queue: EMPTY Blocked Queue: EMPTY Time: 3 CPU (currently running): pid=1, state=RUNNING, start=1, slice=3, Ready Queue: EMPTY Blocked Queue: EMPTY Time: 4 CPU (currently running): pid=1, state=RUNNING, start=1, slice=4, Ready Queue: pid=2, state=READY, start=4, slice=0, Blocked Queue: EMPTY Time: 5 CPU (currently running): pid=1, state=RUNNING, start=1, slice=5, Ready Queue: 4 pid=2, state=READY, start=4, slice=0, Blocked Queue: EMPTY Time: 6 CPU (currently running): pid=2, state=RUNNING, start=4, slice=1, Ready Queue: pid=1, state=READY, start=1, slice=5, Blocked Queue: EMPTY Time: 7 CPU (currently running): pid=2, state=RUNNING, start=4, slice=2, Ready Queue: pid=1, state=READY, start=1, slice=5, Blocked Queue: EMPTY Time: 8 CPU (currently running): pid=1, state=RUNNING, start=1, slice=1, Ready Queue: EMPTY Blocked Queue: pid=2, state=BLOCKED, start=4, slice=2, event=1 Time: 9 CPU (currently running): pid=1, state=RUNNING, start=1, slice=2, Ready Queue: EMPTY Blocked Queue: pid=2, state=BLOCKED, start=4, slice=2, event=1 Time: 10 CPU (currently running): pid=1, state=RUNNING, start=1, slice=3, Ready Queue: 5 pid=2, state=READY, start=4, slice=2, Blocked Queue: EMPTY Time: 11 CPU (currently running): pid=1, state=RUNNING, start=1, slice=4, Ready Queue: pid=2, state=READY, start=4, slice=2, Blocked Queue: EMPTY Time: 12 CPU (currently running): pid=2, state=RUNNING, start=4, slice=1, Ready Queue: EMPTY Blocked Queue: EMPTY Time: 13 CPU (currently running): pid=2, state=RUNNING, start=4, slice=2, Ready Queue: EMPTY Blocked Queue: EMPTY Time: 14 CPU (currently running): pid=2, state=RUNNING, start=4, slice=3, Ready Queue: EMPTY Blocked Queue: EMPTY Time: 15 CPU (currently running): pid=2, state=RUNNING, start=4, slice=4, Ready Queue: 6 EMPTY Blocked Queue: EMPThis assignment comes with the following starting code. please use it.
#include
#include
#include
#include
using namespace std;
/** The process simulator.
* The main loop for running a simulation. We read simulation
* events from a file
*
* @param simfilename The name of the file (e.g. simulaiton-01.sim) to open
* and read simulated event sequence from.
* @param timeSliceQuantum The value to be used for system time slicing preemption
* for this simulation.
*/
void runSimulation(char* simfilename, int timeSliceQuantum)
{
ifstream simeventsfile(simfilename);
string command;
int eventnum;
if (!simeventsfile.is_open())
{
cout << "Error: could not open simulator events file: " << simfilename << endl;
exit(1);
}
while (!simeventsfile.eof())
{
simeventsfile >> command;
// Handle the next simulated event we just read from the
// simulation event file
if (command == "cpu")
{
cout << " cpu: simulate a cpu cycle here" << endl;
}
else if (command == "new")
{
cout << " new: simulate creation of new process here" << endl;
}
else if (command == "done")
{
cout << " done: simulate termination of currently running process here" << endl;
}
else if (command == "wait")
{
simeventsfile >> eventnum;
cout << " wait: eventnum: " << eventnum <<
" simulate event blocked and waiting" << endl;
}
else if (command == "event")
{
simeventsfile >> eventnum;
cout << " event: eventnum: " << eventnum <<
" simulate event occurring possibly making some processes ready" << endl;
}
else if (command == "exit")
{
// we use an explicit indicator to ensure simulation exits correctly
break;
}
else
{
cout << " ERROR: unknown command: " << command << endl;
exit(0);
}
}
simeventsfile.close();
}
/** Main entry point of simulator
* The main entry point of the process simulator. We simply set up
* and initialize the environment, then call the appropriate function
* to begin the simulation. We expect a single command line argument
* which is the name of the simulation event file to process.
*
* @param argc The argument count
* @param argv The command line argument values. We expect argv[1] to be the
* name of a file in the current directory holding process events
* to simulate.
*/
int main(int argc, char** argv)
{
int timeSliceQuantum = 0;
// validate command line arguments
if (argc != 3)
{
cout << "Error: expecting event file as first command line parameter and time slice quantum as second" << endl;
cout << "Usage: " << argv[0] << " simeventfile.sim time_slice" << endl;
exit(1);
}
// Assume second command line argument is the time slice quantum and parse it
timeSliceQuantum = atoi(argv[2]);
if (timeSliceQuantum <= 0)
{
cout << "Error: invalid time slice quantum received: " << timeSliceQuantum << endl;
exit(1);
}
// Invoke the function to actually run the simulation
runSimulation(argv[1], timeSliceQuantum);
// if don't want to use command line do following.
// need to recompile by hand since file
// name to get simulated events from is hard coded
//runSimulation("simulation-01.sim", 5);
return 0;
}
Step by Step Solution
There are 3 Steps involved in it
Get step-by-step solutions from verified subject matter experts
