diff --git a/schedulers/BF.py b/schedulers/BF.py index 17ef504..666dbcc 100644 --- a/schedulers/BF.py +++ b/schedulers/BF.py @@ -1,16 +1,20 @@ """ Implementation of the BF algorithm. + +Authors: Maxime Chéramy and Stefan Junker """ from simso.core import Scheduler, Timer +from fractions import Fraction class BF(Scheduler): def init(self): self.t_f = 0 self.waiting_schedule = False - self.mirroring = False self.allocations = [] self.timers = {} + self.rw = {t.identifier: 0 for t in self.task_list} + self.pw = {} def reschedule(self, cpu=None): """ @@ -54,7 +58,7 @@ class BF(Scheduler): return -1 elif ai < aj: return 1 - elif ai == 0: + elif ai == 0 == aj: return -1 elif ai == -1: if self.uf_plus_one(job_i) > self.uf_plus_one(job_j): @@ -77,33 +81,60 @@ class BF(Scheduler): * self.sim.cycles_per_ms) # Duration that can be allocated for each processor. w = int(self.t_f - self.sim.now()) + available = w * len(self.processors) + p = 0 # Processor id. mand = {} - available = w * len(self.processors) eligible = [] + print("{:#^60}".format( + " Scheduling Interval [{},{}) ".format( + self.sim.now() / self.sim.cycles_per_ms, + self.t_f / self.sim.cycles_per_ms))) for task in self.task_list: - job = task.job - if not job.is_active(): + if not task.job.is_active(): + self.rw[task.identifier] = 0 + self.pw[task.identifier] = 0 continue - fluid = (self.sim.now() - job.activation_date * - self.sim.cycles_per_ms) * job.wcet / job.period - lag = fluid - job.computation_time_cycles - mand[task.identifier] = max(0, - int(lag + w * job.wcet / job.period)) + rw = self.rw[task.identifier] + m_pure = ((Fraction(rw) + Fraction(w * task.job.wcet) + / Fraction(task.job.period)) + / Fraction(self.sim.cycles_per_ms)) + m = int(m_pure) + self.pw[task.identifier] = m_pure - m + mand[task.identifier] = max(0, m * self.sim.cycles_per_ms) + +# print("rw: {:>4}".format(rw)) +# print("{}:, w: {}, m_pure: {:>4}, m: {:>2}, pw: {:>4}, mand: {}".format( +# task.name, w/self.sim.cycles_per_ms, m_pure, m, +# self.pw[task.identifier], mand[task.identifier])) + available -= mand[task.identifier] - if mand[task.identifier] < w: + if mand[task.identifier] < w and self.pw[task.identifier] > 0: eligible.append(task) - while available > 0 and eligible: - job_m = None - for task in eligible: - if job_m is None or self.compare(task.job, job_m) == -1: - job_m = task.job - mand[job_m.task.identifier] += 1 - eligible.remove(job_m.task) - available -= 1 + self.rw[task.identifier] = \ + self.pw[task.identifier] * self.sim.cycles_per_ms + + print("{:#^60}".format(" Done ")) + + while available >= self.sim.cycles_per_ms and eligible: + task_m = eligible[0] + for task_e in eligible[1:]: + result = self.compare(task_m.job, task_e.job) + + if result == -1: + pass + elif result == 1: + task_m = task_e + else: + print("Warning: Couldn't find task for optional unit!") + + mand[task_m.identifier] += self.sim.cycles_per_ms + available -= self.sim.cycles_per_ms + self.rw[task_m.identifier] -= self.sim.cycles_per_ms + eligible.remove(task_m) for task in self.task_list: # The "fair" duration for this job on that interval. Rounded to the @@ -132,8 +163,8 @@ class BF(Scheduler): # Because every durations are rounded to the upper value, # the last job may have not enough space left. # This could probably be improved. - print("Warning: didn't allowed enough time to last task.", - duration - duration1) + print("Warning: didn't allowed enough time to %s (%d)." % + (task.name, duration - duration1)) break p += 1 @@ -142,13 +173,6 @@ class BF(Scheduler): if allocation[0] < w: allocation[1].append((None, w - allocation[0])) - if self.mirroring: - for allocation in self.allocations: - # Rerverse the order of the jobs. - # Note: swapping the first and last items should be enough. - allocation[1].reverse() - self.mirroring = not self.mirroring - def end_event(self, z, job): """ Called when a job's budget has expired.