////////////////////////////////////////////////////////////
//Author: Christin Rodgers
//Date: Monday, February 10, 2010
//Overview:
//
//References:
//
///////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////
#include <iostream>
#include <queue>
#include <fstream>
#include <string>
#include "task.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
using namespace std;
/*
//Stores the process ID, arrival time, and burst time of each process.
struct Task
{
//Process ID
int pid;
//Arrival Time
int aTime;
//Burst Time
int runTime;
};
*/
//Function Header: FCFS
//FCFS is a function to schedule tasks in a first come first server manner.
int FCFS(queue<Task>);
//Function Header: RR
//RR is a function to schedule tasks in a round robin manner.
int RR(queue<Task>, int);
//Function Header: SJF
//SJF is a function to schedule tasks in the order of shortest job first.
int SJF(queue<Task>);
int main(int argc, char* argv[])
{
//Variable Declarations
//File pointer to open and read in the file
ifstream inFile;
//Temporary Task variable to store the task read in from the file
Task temp;
//FIFO queue for the input from the file.
queue<Task> input;
//Stores the input file name
string fileName;
//Stores the scheduling algorithm to implement
string whichAlg;
//Time quantum for when round robin scheduling is chosen
int timeQuantum;
//Parse the input from the command line.
fileName = argv[0];
whichAlg = argv[1];
if(whichAlg == "RR")
{
timeQuantum = atoi(argv[2]);
}
//Open input file
// inFile.open(fileName.c_str());
inFile.open("input.txt");
//Check that file opened correctly
if(!inFile)
{
cout << "Could not open the input file." << endl;
return 1;
}
inFile >> temp.pid >> temp.aTime >> temp.runTime;
input.push(temp);
while(inFile)
{
inFile >> temp.pid >> temp.aTime >> temp.runTime;
input.push(temp);
}
//Close input file
inFile.close();
//Choose scheduling algorithm to execute.
//If first come first serve was requested:
if(strcmp(argv[2], "FCFS")==0)
{
//Output general information to user.
cout << "Scheduling Algorithm: FCFS" << endl;
cout << "Total " << input.size() << " tasks are read from '" << fileName
<< "'. Press 'enter' to start." << endl;
//Call first come first server function
FCFS(input);
}
//If round robin was requested:
if(strcmp(argv[2], "RR")==0)
{
//Output general information to user.
cout << "Scheduling Algorithm: RR" << endl;
cout << "Total " << input.size() << " tasks are read from '" << fileName
<< "'. Press 'enter' to start." << endl;
//Call round robin function
RR(input, timeQuantum);
}
//If shortest job first was requested:
if(strcmp(argv[2], "SJF")==0)
{
//Output general information to user.
cout << "Scheduling Algorithm: SJF" << endl;
cout << "Total " << input.size() << " tasks are read from '" << fileName
<< "'. Press 'enter' to start." << endl;
//Call shortest job first function
SJF(input);
}
return 0;
}
int FCFS(queue<Task> input)
{
//Variable Declarations
//Stores the current task.
Task current;
//For-loop counter
int i, j;
//Keeps a count of the total run time.
int total = 0;
cout << "Size of input queue: " << input.size() << endl;
//Loops through the each process in the input queue.
for(i=0; i<input.size(); i++)
{
//Get the first process from the queue.
current = input.front();
//Checks to see if there are any ready tasks.
while(total < current.aTime)
{
//If not, outputs an idle message.
cout << "<system time "<< total << "> The CPU is idle." << endl;
//Increments the total run time.
total++;
}
//Schedules the first process for its run time.
for(j=0; j<current.runTime; j++)
{
cout << "<system time "<< total << "> process " << current.pid
<< " is running" << endl;
//Increments the total run time.
total++;
}
}
return 0;
}
int RR(queue<Task> input, int timeQuantum)
{
//Variable Declarations
//Stores the running task.
Task current;
//Keeps a count of the total run time.
int total = 0;
//Stores the ready and/or running tasks.
queue<Task> ready;
//For-loop counter
int i;
//Grab the first task from the input queue.
current = input.front();
input.pop();
//Check if the arrival time is equal to the total time.
//If not, output an idle message until it is.
while(total < current.aTime)
{
//If not, outputs an idle message.
cout << "<system time "<< total << "> The CPU is idle." << endl;
//Increments the total run time.
total++;
}
//If the there are still tasks coming:
//
//Insert any tasks that will arrive BEFORE the current task is finished
//executing its allocated amount of time.
// [i.e. tasks with an arrival time <= total + timeQuantum-1]
//This will implement the round robin scheduling in a first come first
//server manner.
if(!input.empty())
{
while(input.front().aTime <= total+timeQuantum-1)
{
ready.push(input.front());
input.pop();
}
}
//Enter the main loop of the round robin scheduling algorithm:
//
//Run the first task in the ready queue for 'timeQuantum' milliseconds.
while(!input.empty())
{
//If the ready queue is empty but there are still tasks that have
//yet to arrived, the CPU is idle.
if(ready.empty())
{
//If not, outputs an idle message.
cout << "<system time "<< total << "> The CPU is idle." << endl;
//Increments the total run time.
total++;
}
//Run the next task for 'timeQuantum' -OR- until the task has finished
//running.
if(!ready.empty())
{
current = ready.front();
ready.pop();
while(i<timeQuantum && current.runTime > 0)
{
cout << "<system time "<< total << "> process "
<< current.pid << " is running." << endl;
i++;
current.runTime = current.runTime-1;
total++;
}
}
if(!input.empty())
{
while(input.front().aTime <= total+timeQuantum-1)
{
ready.push(input.front());
input.pop();
}
}
}
//If all the tasks have arrived and the ready queue is not empty,
//execute the remaining tasks in a round robin fashion.
while(!ready.empty())
{
current = ready.front();
ready.pop();
while(i<timeQuantum && current.runTime > 0)
{
cout << "<system time "<< total << "> process " << current.pid
<< " is running" << endl;
i++;
current.runTime = current.runTime-1;
total++;
}
}
/*
--------------------------------------------------------------------
//Grab the first task from the input queue.
current = input.front();
input.pop();
//Check if the arrival time is equal to the total time.
//If not, output an idle message until it is.
while(total < current.aTime)
{
//If not, outputs an idle message.
cout << "<system time "<< total << "> The CPU is idle." << endl;
//Increments the total run time.
total++;
}
//Inserts the ready task to 'ready'
ready.push(current);
//Insert to the ready queue any of the tasks that have the
//same arrival time as the front of the next task.
while(current.aTime == input.front().aTime)
{
ready.push(input.front());
input.pop();
}
//Executes the first ready task for 'timeQuantum'.
while(current.runTime < timeQuantum && current.runTime > 0)
{
//Run current task.
//Increment tqCounter
tqCounter++;
}
//Checks the next task in input queue to see if it is "ready".
//If so, task is popped of 'input' and placed onto 'ready.
if(input.front().aTime <= total)
{
ready.push(input.front());
input.pop();
}
//Checks to see if 'tqCounter' is equal to 'timeQuantum'
//If not, is either idle for 1ms or begins next task in ready queue.
//If the ready queue is empty but there are still more tasks coming:
if(ready.empty() && !input.empty())
{
//Accounting for idle time until the next task has arrived.
while(total < input.front().aTime)
{
//Output idle message.
}
//Puts the next task in the ready queue.
ready.push(input.front());
input.pop();
}
*/
return 0;
}
int SJF(queue<Task> input)
{
//Variable Declarations
//Stores the running task.
Task current;
//For-loop counter
int i;
return 0;
}