WC_RUN.py 2.22 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
"""
Work-Conserving version of U-EDF.
"""

from RUN import RUN


class WC_RUN(RUN):
    def init(self):
        RUN.init(self)
        self.state = {}

    def on_terminated(self, job):
        RUN.on_terminated(self, job)
        if job in self.state:
            del self.state[job]

    def on_abort(self, job):
        RUN.on_abort(self, job)
        if job in self.state:
            del self.state[job]

    def schedule(self, cpu):
        decisions = RUN.schedule(self, cpu)

#        print(".")
#        print([(id(job), job.name if job else None, proc.name)
#               for job, proc in self.state.items()])
#
#        print("decisions :")
#        print([(job.name if job else None, proc.name)
#               for job, proc in decisions])

        rstate = {proc: job for job, proc in self.state.items()}
        for djob, dproc in decisions:
            if dproc in rstate:
                del self.state[rstate[dproc]]
            if djob is not None:
                self.state[djob] = dproc
                rstate[dproc] = djob

#        print([(id(job), job.name if job else None, proc.name)
#               for job, proc in self.state.items()])

        running_jobs = list(self.state.keys())

        # Get active jobs.
        jobs = sorted(
            (task.job for task in self.task_list if task.job.is_active()),
            key=lambda j: j.absolute_deadline)

        # Bind jobs to processors:
        available_procs = list(self.processors)
        was_not_running = []
        for job in jobs:
            if job in running_jobs:
                available_procs.remove(self.state[job])
            else:
                was_not_running.append(job)

        remaining_jobs = []
        for job in was_not_running:
            if job.cpu in available_procs:
                decisions.append((job, job.cpu))
                available_procs.remove(job.cpu)
                self.state[job] = job.cpu
            else:
                remaining_jobs.append(job)

        for p, proc in enumerate(available_procs):
            if p < len(remaining_jobs):
                job = remaining_jobs[p]
                self.state[job] = proc
            else:
                job = None
            decisions.append((job, proc))

        return decisions