// // Program to simulate CPU scheduling. // // Input to this class's main method is a file (name given as a command-line // argument) containing one or more lines, each representing one job to // schedule, and containing: // Job ID (string) // Arrival time (integer) // Running time (integer) // Priority (integer, where higher numbers indicate higher priority) // These lines are assumed to be in order by arrival time. // // (Optional second command-line argument "--verbose" gives more-verbose // output. You do not have to use this in your code, but it may be // useful for debugging.) // // Output is, for each scheduling algorithm implemented, the following // information for each job, plus average turnaround: // Job ID and other input info // Start time // End time // Turnaround time // #include // C++ headers for C-style I/O #include // C++ headers for stdlib #include // C++ headers for C-style strings #include // C++ file I/O classes (streams) #include // C++ string class #include // C++ vector class (expandable array) using std::ifstream; using std::string; using std::vector; // ---- Class for representing each job ---- class jobInfo { public: // Constructor // parameters are jobID, etc., from program input jobInfo(string _jobID, int _arrival, int _runtime, int _prty) : jobID(_jobID), arrival(_arrival), runtime(_runtime), prty(_prty), start(0), end(0), turnaround(0), timeLeft(0) { } // Variables // input string jobID; int arrival; int runtime; int prty; // to be filled in by scheduler function(s) int start; int end; int turnaround; // to be used as work by scheduler function(s) int timeLeft; }; // shorthand for type (vsize_type) to represent size of vector and indices typedef vector::size_type vsize_type; // ---- Function to print contents of vector of jobInfo objects ---- void print(const char *headerMsg, vector &jobs) { printf("\n%s\n\n", headerMsg); printf("%10s %10s %10s %10s %10s %10s %10s\n\n", "job", "arrival", "runtime", "priority", "start", "end", "turnaround"); int totalTurnaround = 0; for (vsize_type i = 0; i < jobs.size(); ++i) { printf("%10s %10d %10d %10d %10d %10d %10d\n", jobs[i].jobID.c_str(), jobs[i].arrival, jobs[i].runtime, jobs[i].prty, jobs[i].start, jobs[i].end, jobs[i].turnaround); totalTurnaround += jobs[i].turnaround; } printf("\nAverage turnaround time = %12.2f\n", (double) totalTurnaround / (double) jobs.size()); } // ---- Scheduler functions (declarations) ---- void scheduleFCFS(vector &jobs); // FIXME uncomment as appropriate // void scheduleSJF(vector &jobs); // void schedulePriority(vector &jobs); // void scheduleRR(vector &jobs, const int quantum); // ---- Global variable indicating whether verbose output is wanted ---- static bool verbose = false; // ---- Main program ---- int main(int argc, char* argv[]) { // process cmdline argument(s) if (argc < 2) { fprintf(stderr, "usage: %s inputfile [--verbose]\n", argv[0]); return EXIT_FAILURE; } verbose = (argc > 2) && (strcmp(argv[2], "--verbose") == 0); vector jobs; // get input (using C++ stream I/O so we can read C++ strings directly) ifstream infile; infile.open(argv[1]); if (!infile.is_open()) { fprintf(stderr, "cannot open input file %s\n", argv[1]); return EXIT_FAILURE; } string jobID; int arrival, runtime, prty; // loop until end of file or error while (infile >> jobID >> arrival >> runtime >> prty) { jobs.push_back(jobInfo(jobID, arrival, runtime, prty)); } if (!infile.eof()) { fprintf(stderr, "invalid input\n"); return EXIT_FAILURE; } infile.close(); // schedule jobs scheduleFCFS(jobs); print("First come, first served", jobs); // FIXME uncomment as appropriate // scheduleSJF(jobs); // print("Shortest job first", jobs); // schedulePriority(jobs); // print("Priority", jobs); // scheduleRR(jobs, 1); // print("Round robin, quantum = 1", jobs); // scheduleRR(jobs, 2); // print("Round robin, quantum = 2", jobs); return EXIT_SUCCESS; } // ---- Scheduler functions (definitions) ---- // // These functions should fill in the start, end, and turnaround fields // of each element of the vector of jobInfo objects. // First come, first served. void scheduleFCFS(vector &jobs) { int time = 0; // simulated time vector readyQueue; // queue of ready jobs (indices into jobs) vsize_type nextInput = 0; // index of first job not in readyQueue if (verbose) { printf("\nStarting FCFS scheduling\n"); } // schedule jobs until no more input and ready queue is empty while ((nextInput < jobs.size()) || (readyQueue.size() > 0)) { // add jobs with arrival times <= current time to ready queue while ((nextInput < jobs.size()) && (jobs[nextInput].arrival <= time)) { readyQueue.push_back(nextInput++); } // if there's anything ready, schedule it if (readyQueue.size() > 0) { vsize_type job = readyQueue[0]; readyQueue.erase(readyQueue.begin()); if (verbose) { printf("At time %d, starting job %s\n", time, jobs[job].jobID.c_str()); } jobs[job].start = time; time += jobs[job].runtime; jobs[job].end = time; jobs[job].turnaround = jobs[job].end - jobs[job].arrival; } // otherwise increment time and try again else { time = jobs[nextInput].arrival; } } } // FIXME add function definitions as needed