#ifndef SCHEDULER_HPP
#define SCHEDULER_HPP
#include "process.h"
#include "event.h"
enum Mode {FCFS, SJF, RR, PRIORITY};
class scheduler {
private:
Process* readyq; //container
unsigned int vacant;//last vacant spot of ready queue array.
void enqueue(Process&);//Add element to ready queue.
Process dequeue(); //Removes element from ready queue.
int order;//Incremented & assigned to process on add.
int mode; //scheduling method- run-time changes is possible.
public:
/*PARAM: (capacity for container, mode for scheduler)
NOTE: Uses new.*/
scheduler(const unsigned int&, const int&);
//Deletes array created by new.
~scheduler();
/*PARAM: (process to add to container)*/
void add(Process&);
/*PARAM: (CPU status, event queue, time quantum)
NOTE: tq, time quantum, only applicable for RR.*/
void run(bool&, Event*, unsigned int&, const int&, const unsigned int& tq = 0);
};
#include "objcmp.hpp"
#include "heap_sort.hpp"
#ifdef DEBUG
#include <cstdio>
#endif
scheduler::scheduler(const unsigned int& amount, const int& _mode) {
readyq = new Process[amount];
for (int i = 0; i < amount; i++) {
//Uninitialized junk may interfere & cause seg. faults.
readyq[i].state = TERMINATED;
}
vacant = 0;
order = 0;
mode = _mode;
}
scheduler::~scheduler() {
delete [] readyq;
}
Process scheduler::dequeue() {
static struct cmp<Process, int, std::less_equal> lec
(&Process::CPU_duration_remaining);
static struct cmp<Process, int, std::less_equal> lep
(&Process::priority);
static struct cmp<Process, int, std::less_equal> leo
(&Process::order);
Process output = readyq[0];
switch(mode) {
case SJF:
reheapify<Process, int, std::less_equal>
(readyq, vacant, lec);
break;
case PRIORITY:
reheapify<Process, int, std::less_equal>
(readyq, vacant, lep);
break;
default:
reheapify<Process, int, std::less_equal>
(readyq, vacant, leo);
break;
}
return output;
}
void scheduler::enqueue(Process& add_me) {
static struct cmp<Process, int, std::less>
oless(&Process::order);
static struct cmp<Process, int, std::less>
cless(&Process::CPU_duration_remaining);
static struct cmp<Process, int, std::less>
pless(&Process::priority);
switch(mode) {
case RR:
case FCFS:
insert<Process, int, std::less>
(readyq, vacant, add_me, oless);
break;
case SJF:
insert<Process, int, std::less>
(readyq, vacant, add_me, cless);
break;
case PRIORITY:
insert<Process, int, std::less>
(readyq, vacant, add_me, pless);
break;
default:
printf("Error: Hit default case on scheduler::add.\n");
exit(EXIT_FAILURE);
break;
}
}
void scheduler::add(Process& add_me) {
order++;
add_me.order = order;
#ifdef DEBUG
printf("Process#%d at the front of ready queue\nNeed to add process id#%d\n", readyq[0].id, add_me.id);
#endif
for (int i = 0; i < vacant; i++) {
if (add_me.id == readyq[i].id) {
//Already exists - don't add clones to the ready queue.
readyq[i] = add_me;
Process temp[i + 1];
for (int j = 0; j < i + 1; j++) {
temp[j] = dequeue();
}//end for
for (int j = 0; j < i + 1; j++) {
enqueue(temp[j]);
}
#ifdef DEBUG
goto display;
#else
return;
#endif
}//end if
}//end for
enqueue(add_me);
#ifdef DEBUG
display:
for (unsigned int j = 0; j < vacant; j++) {
printf("Process Id#%d with order %d.\n", readyq[j].id, readyq[j].order);
}
#endif
//vacant is incremented by insert().
}
void scheduler::run
(bool& cpu_idle, Event* event_queue, unsigned int& ev,
const int& ctime, const unsigned int& tq) {
static struct cmp<Event, int, std::less> lt
(&Event::occur_time);
if (vacant <= 0) {
printf("Scheduler has no processes in ready queue.\n");
return;
}
if (cpu_idle && mode != RR) {
#ifdef DEBUG
printf("CPU is idle - and non-pre-emptive scheduling.\n");
#endif
//Run process
cpu_idle ^= 1; //Set to busy.
Process running = dequeue();
Event e;
e.pid = running.id;
e.happened = CPU_BURST_COMPLETION;
e.occur_time = ctime + running.CPU_burst_length_next;
insert<Event, int, std::less>(event_queue, ev, e, lt);
} else if (!cpu_idle && mode == RR && tq != 0) {
#ifdef DEBUG
printf("CPU is busy and pre-emptive scheduling.\n");
#endif
//Set aside process. Send IO_Burst Completion Event.
//Get new process. Send CPU Completion Event.
} else if (!cpu_idle && mode == RR) {
#ifdef DEBUG
printf("Error: Time quantum is 0.\n");
#endif
exit(EXIT_FAILURE);
}
/*CPU is not idle and mode is not RR
or CPU is idle and the mode is RR*/
}
#endif
One file of a homework assignment. This thread could get quite long.