Scheduler
taskScheduler.cpp
Go to the documentation of this file.
1 
10 #include "taskScheduler.h"
11 
12 #include <cassert>
13 #include <fstream>
14 #include <iostream>
15 #include <string>
16 #include <utility>
17 
18 #include <utils/log.h>
19 #include "events/coreEvents.h"
20 #include "events/eventList.h"
21 #include "events/eventType.h"
22 #include "process.h"
23 #include "queue.h"
24 #include "schedulerConfiguration.h"
26 #include "system.h"
27 #include "time.h"
28 
29 #include "specialMailbox.h"
30 
31 #define PRINT 1
32 
33 using namespace Scheduler;
34 
35 TaskScheduler::TaskScheduler(std::shared_ptr<SchedulerConfiguration> c) : deadlinesHistory(Utils::Record(c, "deadlineMisses")), conf(c)
36 {
37  setDiscipline(conf->getDisciplineFromFile());
38 }
39 
40 
42 {
43 }
44 
46 {
47  //printStatus();
48  Utils::Log log;
49  static Queue *readyQueue = Queue::getReadyQueue();
50  static Processor *proc = System::getInstance()->getProc();
51 
53 
54 
55  if (trigger == TriggeringEvent::terminate)
56  {
57  }
58  else
59  {
61  }
62 
63 
64  if (trigger == TriggeringEvent::newprocess)
65  {
67  }
68 
69  if (!discipline->preempts(trigger) && proc->isBusy())
70  {
71  /*The event that triggered the scheduler invocation does not preempt
72  this particular discipline used*/
73  return;
74  }
75 
76  std::shared_ptr<Process> nextTask = discipline->selectNextTask(readyQueue,
78 
79  if (proc->isRunning(nextTask))
80  {
81  return;
82  }
83 
84  if (discipline->preempts(trigger))
85  {
87  }
88  if (!proc->powered()) /*Just to be sure. Can happen if proc is turned on at the exact same time when task gets ready*/
89  {
90  return;
91  }
92 
93  proc->setRunning(nextTask);
94 
95  if (nextTask != nullptr)
96  {
97  readyQueue->remove(nextTask);
98  scheduleEndOfBurst(nextTask);
99  }
100 
101  printRunningProcess(nextTask);
102  return;
103 }
104 
105 void TaskScheduler::dealWithMissedDeadlines(std::shared_ptr<Process> p)
106 {
107 #if 0
108  deadlineMisses++;
109 #else
110  deadlineMisses += (p->getPriority()+1);//TODO decide according to some configuration option
111 #endif
112  static Processor *proc = System::getInstance()->getProc();
113  std::shared_ptr<Process> running = proc->getRunningTask();
114  deadlinesHistory.add(Time::getTime(), p->getPid());
115  if (running == p)
116  {
117  std::shared_ptr<Event> ev = getBurstEnd();
119  proc->setRunning(nullptr);
120  return;
121  }
122  if (Queue::getReadyQueue()->remove(p) != nullptr)
123  {
124  }
125 }
126 
127 
128 void TaskScheduler::clearRunningTask(std::shared_ptr<Process> p)
129 {
130  static Processor *proc = System::getInstance()->getProc();
131  assert(p == proc->getRunningTask());
132  proc->setRunning(nullptr);
133  printRunningProcess(nullptr);
134 }
135 
136 void TaskScheduler::scheduleEndOfBurst(std::shared_ptr<Process> runningTask)
137 {
138  static Processor *proc = System::getInstance()->getProc();
139  static EventList *eventList = EventList::getInstance();
140  if (!proc->isBusy())
141  return;
142 
143  double newTime = Time::getTime() + runningTask->getCurrentCpuAow()/proc->getFreq();
144  bool wait = runningTask->advanceBurst();
145  std::shared_ptr<Event> e;
146  if (wait)
147  {
148  e = std::make_shared<Waiting>(newTime);
149  }
150  else
151  {
152  e = std::make_shared<Terminates>(newTime);
153  }
154  e->setTask(runningTask);
155 
156  setBurstEnd(eventList->insert(e));
157 }
158 
160 {
161  static Processor *proc = System::getInstance()->getProc();
162  static EventList *eventList = EventList::getInstance();
163  static Queue *readyQueue = Queue::getReadyQueue();
164  if (!proc->isBusy())
165  return;
166  std::shared_ptr<Event> ev = getBurstEnd();
167  if (ev != nullptr)
168  {
169  double newAow = (ev->getTime() - Time::getTime())*proc->getFreq();
170  runningTask->updateCurrentAow(newAow);
171  eventList->remove(ev);
172  readyQueue->add(runningTask);
173  }
174 }
175 
176 
177 void TaskScheduler::setBurstEnd(std::shared_ptr<Event> e)
178 {
179  burstEnd = e;
180 }
181 
182 std::shared_ptr<Event> TaskScheduler::getBurstEnd()
183 {
184  return burstEnd;
185 }
186 
187 
188 
189 
191 {
192 #ifdef PRINT
193  Utils::Log log;
194  log << Utils::Log::Color::lightBlue;
195  log << " Scheduler invoked. Ready queue contains ";
196  log << Queue::getReadyQueue()->getDisplay() << Utils::Log::Color::normal <<"\n";
197 #endif
198 }
199 
200 void TaskScheduler::printRunningProcess(std::shared_ptr<Process> runningTask)
201 {
202  Utils::Log log;
203  if (runningTask != nullptr)
204  {
205  log << Utils::Log::Color::blue;
206  log <<" Currently running process number "<<runningTask->getPid();
207 
208  if (runningTask->isRealTime())
209  log << ":"<< runningTask->getJobNumber();
210 
211  log << Utils::Log::Color::normal << "\n";
212  }
213  else
214  {
215  log << Utils::Log::Color::blue;
216  log << " Processor sleeping" << Utils::Log::Color::normal << "\n";
217  }
218 }
219 
220 
221 
222 
223 
224 void TaskScheduler::setDiscipline(std::unique_ptr<SchedulingDiscipline> disc)
225 {
226  discipline = std::move(disc);
227  assert(discipline != nullptr);
228 #ifdef PRINT
229  Utils::Log log;
230  log << Utils::Log::Color::green << "Using scheduling discipline ";
231  log << discipline->getName() << Utils::Log::Color::normal << "\n";
232 #endif
233 }
234 
235 
236 
237 
238 
239 void TaskScheduler::printReports(std::string folder)
240 {
242 }
243 
244 
246 {
248 }
249 
250 
251 
253 {
257 }
258 
259 
260 void TaskScheduler::end(std::string folder)
261 {
262  discipline->end();
263  printReports(folder);
264 }
265 
266 
void printReports(std::string folder)
TriggeringEvent
Definition: eventType.h:16
double getFreq() const
get the current frequency of the processor
Definition: processor.cpp:130
TaskScheduler(std::shared_ptr< SchedulerConfiguration > conf)
static double getTime()
Definition: time.cpp:16
void putRunningTaskBackToReadyQueue(std::shared_ptr< Process > task)
This class implements the ready queue and the wait queue. Those queues contain processes ready to run...
Definition: queue.h:28
void print() const
print a summary of the queue&#39;s content
Definition: queue.cpp:86
void end(std::string reportsFolder)
cleanup and print reports
void printToFile(std::string folder) const
Definition: record.cpp:23
std::shared_ptr< Event > burstEnd
Definition: taskScheduler.h:75
void printRunningProcess(std::shared_ptr< Process > runningTask)
void setBurstEnd(std::shared_ptr< Event > e)
void remove(std::shared_ptr< Event > e)
remove an element from the list.
Definition: eventList.cpp:83
static System * getInstance()
Definition: system.cpp:28
void setDiscipline(std::unique_ptr< SchedulingDiscipline > discipline)
void setRunning(std::shared_ptr< Process > p)
Definition: processor.cpp:84
unsigned int deadlineMisses
Definition: taskScheduler.h:78
std::string getDisplay() const
get the queue&#39;s content as a string, for command-line output
Definition: queue.cpp:95
static Queue * getReadyQueue()
get a pointer to the system&#39;s ready queue
Definition: queue.cpp:30
static Queue * getWaitQueue()
get a pointer to the system&#39;s wait queue
Definition: queue.cpp:37
void scheduleTask(TriggeringEvent trigger)
This function is the scheduler. When called, it schedule the task to be executed on the processor ama...
void add(double time, double element)
Definition: record.cpp:41
std::shared_ptr< Process > runningTask
Definition: taskScheduler.h:74
std::shared_ptr< SchedulerConfiguration > conf
Definition: taskScheduler.h:82
bool isBusy() const
return true if the processor is running any task
Definition: processor.cpp:72
std::shared_ptr< Process > remove(std::shared_ptr< Process > p)
removes the process from the queue. Note: this does not delete the process. Just remove it from queue...
Definition: queue.cpp:48
void clearRunningTask(std::shared_ptr< Process > p)
void scheduleEndOfBurst(std::shared_ptr< Process > runningTask)
std::shared_ptr< Event > insert(std::shared_ptr< Event > e)
Definition: eventList.cpp:56
void incrementJobsArrivalCount()
increments the number of jobs issued since the beginning of simulation
Definition: system.cpp:144
void dealWithMissedDeadlines(std::shared_ptr< Process > p)
to be called when a deadline mis event happends. This function will terminate the task and update the...
Definition: log.h:18
std::shared_ptr< Event > getBurstEnd()
bool powered() const
return true if the processor is powered on
Definition: processor.cpp:179
Processor * getProc()
return the processor
Definition: system.cpp:76
static SpecialMailbox * getInstance()
Utils::Record deadlinesHistory
Definition: taskScheduler.h:79
void add(std::shared_ptr< Process > p)
add a process to the queue
Definition: queue.cpp:23
std::unique_ptr< SchedulingDiscipline > discipline
Definition: taskScheduler.h:72
Definition: context.h:16
std::shared_ptr< Process > getRunningTask()
Definition: processor.cpp:92
static EventList * getInstance()
Singleton pattern.
Definition: eventList.cpp:22
bool isRunning(std::shared_ptr< Process > p) const
returns true if the processor is running the task provided as argument
Definition: processor.cpp:78
void printDeadlineMissesReport(std::string folder)