diff --git a/simso/core/Job.py b/simso/core/Job.py index 4f7f710..db46734 100644 --- a/simso/core/Job.py +++ b/simso/core/Job.py @@ -28,7 +28,7 @@ class Job(Process): :type etm: AbstractExecutionTimeModel :type sim: Model """ - Process.__init__(self, env=sim, generator=self.activate_job()) # TODO: what to pass as generator? + Process.__init__(self, env=sim,generator=self.activate_job()) self._task = task self._pred = pred self.instr_count = 0 # Updated by the cache model. @@ -50,7 +50,10 @@ class Job(Process): self._on_activate() - self.context_ok = True # The context is ready to be loaded. + self.processor_ok = self._sim.event() + self.context_ok = self._sim.event() + self.context_ok.succeed() + self.context_ready=True def is_active(self): """ @@ -64,7 +67,7 @@ class Job(Process): self._etm.on_activate(self) def _on_execute(self): - self._last_exec = self._sim.now() + self._last_exec = self._sim.now self._etm.on_execute(self) if self._is_preempted: @@ -78,7 +81,7 @@ class Job(Process): def _on_stop_exec(self): if self._last_exec is not None: - self._computation_time += self._sim.now() - self._last_exec + self._computation_time += self._sim.now - self._last_exec self._last_exec = None def _on_preempted(self): @@ -95,7 +98,7 @@ class Job(Process): self._on_stop_exec() self._etm.on_terminated(self) - self._end_date = self._sim.now() + self._end_date = self._sim.now self._monitor.observe(JobEvent(self, JobEvent.TERMINATED)) self._task.end_job(self) self._task.cpu.terminate(self) @@ -104,7 +107,7 @@ class Job(Process): def _on_abort(self): self._on_stop_exec() self._etm.on_abort(self) - self._end_date = self._sim.now() + self._end_date = self._sim.now self._aborted = True self._monitor.observe(JobEvent(self, JobEvent.ABORTED)) self._task.end_job(self) @@ -183,7 +186,7 @@ class Job(Process): Dynamic laxity of the job in ms. """ return (self.absolute_deadline - self.ret - ) * self._sim.cycles_per_ms - self._sim.now() + ) * self._sim.cycles_per_ms - self._sim.now @property def computation_time(self): @@ -201,7 +204,7 @@ class Job(Process): return int(self._computation_time) else: return (int(self._computation_time) + - self._sim.now() - self._last_exec) + self._sim.now - self._last_exec) @property def actual_computation_time(self): @@ -290,7 +293,7 @@ class Job(Process): return self._pred def activate_job(self): - self._start_date = self._sim.now() + self._start_date = self._sim.now # Notify the OS. self._task.cpu.activate(self) @@ -298,7 +301,8 @@ class Job(Process): while self._end_date is None: # Wait an execute order. try: - yield self._sim.event() + yield self.processor_ok + self.processor_ok = self._sim.event() except Interrupt: pass else: diff --git a/simso/core/Monitor.py b/simso/core/Monitor.py index fe61865..3148371 100644 --- a/simso/core/Monitor.py +++ b/simso/core/Monitor.py @@ -18,7 +18,7 @@ class Monitor(list): def observe(self, y,t = None): """record y and t""" - if t is None: t = self.env.now() + if t is None: t = self.env.now self.append([t, y]) def tally(self, y): @@ -32,7 +32,7 @@ class Monitor(list): def reset(self, t = None): """reset the sums and counts for the monitored variable """ self[:] = [] - if t is None: t = self.env.now() + if t is None: t = self.env.now self.startTime = t def tseries(self): @@ -81,14 +81,14 @@ class Monitor(list): The time-weighted average of the monitored variable. If t is used it is assumed to be the current time, - otherwise t = self.sim.now() + otherwise t = self.sim.now """ N = self.__len__() if N == 0: return None - if t is None: t = self.env.now() + if t is None: t = self.env.now sum = 0.0 tlast = self[0][0] ylast = self[0][1] @@ -107,12 +107,12 @@ class Monitor(list): """ the time - weighted Variance of the monitored variable. If t is used it is assumed to be the current time, - otherwise t = self.sim.now() + otherwise t = self.sim.now """ N = self.__len__() if N == 0: return None - if t is None: t = self.env.now() + if t is None: t = self.env.now sm = 0.0 ssq = 0.0 tlast = self[0][0] diff --git a/simso/core/Processor.py b/simso/core/Processor.py index 8cd4dd0..22aee77 100644 --- a/simso/core/Processor.py +++ b/simso/core/Processor.py @@ -54,11 +54,12 @@ class Processor(Process): cls._identifier = 0 def __init__(self, model, proc_info): - Process.__init__(self, env=model, generator=self.run()) # TODO: what to pass as generator? + Process.__init__(self, model, self.run()) self._model = model self._internal_id = Processor._identifier Processor._identifier += 1 self.identifier = proc_info.identifier + self.name = proc_info.name self._running = None self.was_running = None self._evts = deque([]) @@ -70,7 +71,8 @@ class Processor(Process): self._cl_overhead = proc_info.cl_overhead self._migration_overhead = proc_info.migration_overhead self.set_caches(proc_info.caches) - self.timer_monitor = Monitor(env=model, name="Monitor Timer" + proc_info.name) + self.timer_monitor = Monitor( + env=model, name="Monitor Timer" + proc_info.name) self._speed = proc_info.speed def resched(self): @@ -143,34 +145,37 @@ class Processor(Process): """ return self._running - def waituntil(self, cond_func, delay=1): - while not cond_func(): - yield self.env.timeout(delay) - def run(self): while True: if not self._evts: job = self._running if job: - yield self.waituntil(lambda: job.context_ok) + # yield job.context_ok + while not job.context_ready: + yield self._model.timeout(1) self.monitor.observe(ProcCxtLoadEvent()) - yield self._model.timeout(self.cl_overhead) # overhead load context + # overhead load context + yield self._model.timeout(self.cl_overhead) self.monitor.observe(ProcCxtLoadEvent(terminated=True)) - job.interruptReset() - self.env.reactivate(job) + # job.interruptReset() # TODO: does this interrupt need handling? + job.processor_ok.succeed() + job.processor_ok = self._model.event() self.monitor.observe(ProcRunEvent(job)) - job.context_ok = False + job.context_ready = False else: self.monitor.observe(ProcIdleEvent()) # Wait event. - yield self.waituntil(lambda: self._evts) + while not self._evts: + yield self._model.timeout(1) if job: - self.interrupt(job) + self._model.interrupt(job) self.monitor.observe(ProcCxtSaveEvent()) - yield self._model.timeout(self.cs_overhead) # overhead save context + # overhead save context + yield self._model.timeout(self.cs_overhead) self.monitor.observe(ProcCxtSaveEvent(terminated=True)) - job.context_ok = True + # job.context_ok = self._model.event() + job.context_ready = True evt = self._evts.popleft() if evt[0] == RESCHED: @@ -193,7 +198,7 @@ class Processor(Process): elif evt[0] == TIMER: self.timer_monitor.observe(None) if evt[1].overhead > 0: - print(self.env.now(), "hold", evt[1].overhead) + print(self._model.now, "hold", evt[1].overhead) yield self._model.timeout(evt[1].overhead) evt[1].call_handler() elif evt[0] == SPEED: @@ -201,9 +206,11 @@ class Processor(Process): elif evt[0] == RESCHED: self.monitor.observe(ProcOverheadEvent("Scheduling")) self.sched.monitor_begin_schedule(self) - yield self.waituntil(self.sched.get_lock) + while not self.sched.get_lock: + yield self._model.timeout(1) decisions = self.sched.schedule(self) - yield self._model.timeout(self.sched.overhead) # overhead scheduling + # overhead scheduling + yield self._model.timeout(self.sched.overhead) if type(decisions) is not list: decisions = [decisions] decisions = [d for d in decisions if d is not None] diff --git a/simso/core/Scheduler.py b/simso/core/Scheduler.py index ad751c6..faa638e 100644 --- a/simso/core/Scheduler.py +++ b/simso/core/Scheduler.py @@ -130,7 +130,7 @@ class Scheduler(object): - **sim**: :class:`Model ` instance. \ Useful to get current time with ``sim.now_ms()`` (in ms) or \ - ``sim.now()`` (in cycles). + ``sim.now`` (in cycles). - **processors**: List of :class:`processors \ ` handled by this scheduler. - **task_list**: List of :class:`tasks ` \ diff --git a/simso/core/Task.py b/simso/core/Task.py index b769e5d..24863c9 100644 --- a/simso/core/Task.py +++ b/simso/core/Task.py @@ -266,7 +266,7 @@ class GenericTask(Process): self._activations_fifo.popleft() if len(self._activations_fifo) > 0: self.job = self._activations_fifo[0] - self.env.activate(self.job, self.job.activate_job()) + self._sim.process(self.job.activate_job()) def _job_killer(self, job): if job.end_date is None and job.computation_time < job.wcet: @@ -281,15 +281,15 @@ class GenericTask(Process): """ self._job_count += 1 job = Job(self, "{}_{}".format(self.name, self._job_count), pred, - monitor=self._monitor, etm=self._etm, sim=self.env) + monitor=self._monitor, etm=self._etm, sim=self._sim) if len(self._activations_fifo) == 0: self.job = job - self.env.process(job.activate_job()) + self._sim.process(job.activate_job()) self._activations_fifo.append(job) self._jobs.append(job) - timer_deadline = Timer(self.env, GenericTask._job_killer, + timer_deadline = Timer(self._sim, GenericTask._job_killer, (self, job), self.deadline) timer_deadline.start() @@ -307,7 +307,7 @@ class ATask(GenericTask): def execute(self): self._init() - yield self.env.event() + yield self._sim.event() class PTask(GenericTask): @@ -320,13 +320,13 @@ class PTask(GenericTask): def execute(self): self._init() # wait the activation date. - yield self.env.timeout(int(self._task_info.activation_date * + yield self._sim.timeout(int(self._task_info.activation_date * self._sim.cycles_per_ms)) while True: - # print self.sim.now(), "activate", self.name + # print self.sim.now, "activate", self.name self.create_job() - yield self.env.timeout(int(self.period * self._sim.cycles_per_ms)) + yield self._sim.timeout(int(self.period * self._sim.cycles_per_ms)) class SporadicTask(GenericTask): @@ -340,8 +340,8 @@ class SporadicTask(GenericTask): self._init() for ndate in self.list_activation_dates: - yield self.env.timeout(int(ndate * self._sim.cycles_per_ms) \ - - self._sim.now()) + yield self._sim.timeout(int(ndate * self._sim.cycles_per_ms) \ + - self._sim.now) self.create_job() @property @@ -360,8 +360,8 @@ class ProbabilisticTask(GenericTask): self._init() for ndate in self.list_activation_dates: - yield self.env.timeout(int(ndate * self._sim.cycles_per_ms) \ - - self._sim.now()) + yield self._sim.timeout(int(ndate * self._sim.cycles_per_ms) \ + - self._sim.now) self.create_job() @property diff --git a/simso/core/Timer.py b/simso/core/Timer.py index 3e4adc5..29a469d 100644 --- a/simso/core/Timer.py +++ b/simso/core/Timer.py @@ -8,7 +8,8 @@ from simpy import Environment, Process, Interrupt class InstanceTimer(Process): def __init__(self, timer): - Process.__init__(self, env=timer.env, generator=self.run()) + Process.__init__(self, env=timer._sim, generator=self.run()) + self._sim = timer._sim self.function = timer.function self.args = timer.args self.delay = timer.delay @@ -25,12 +26,12 @@ class InstanceTimer(Process): self.running = True while self.running: try: - yield self.env.timeout(self.delay) + yield self._sim.timeout(self.delay) except Interrupt: break else: if not self.running: - break; + break if self.cpu: self.cpu.timer(self) else: @@ -72,7 +73,7 @@ class Timer(object): Methods: """ - self.env = sim + self._sim = sim self.function = function self.args = args if in_ms: @@ -94,7 +95,7 @@ class Timer(object): Start the timer. """ self.instance = InstanceTimer(self) - self.env.process(self.instance.run()) # TODO: , self.prior what's with this? + self._sim.process(self.instance.run()) # TODO: , self.prior what's with this? def stop(self): """ diff --git a/simso/core/results.py b/simso/core/results.py index cb1f0b6..60340b3 100644 --- a/simso/core/results.py +++ b/simso/core/results.py @@ -335,7 +335,7 @@ class Results(object): Get the observation window. """ if self._observation_window is None: - self._observation_window = (0, self.model.now()) + self._observation_window = (0, self.model.now) return self._observation_window def set_observation_window(self, window): diff --git a/simso/schedulers/SCHED_DEADLINE.py b/simso/schedulers/SCHED_DEADLINE.py index f133bb6..c8ed101 100644 --- a/simso/schedulers/SCHED_DEADLINE.py +++ b/simso/schedulers/SCHED_DEADLINE.py @@ -83,7 +83,7 @@ class SCHED_DEADLINE(Scheduler): if (cpu_min.running is None or self.cbs_servers[cpu_min.running.task].current_deadline > self.cbs_servers[ job.task].current_deadline): - print(self.sim.now(), job.name, cpu_min.name) + print(self.sim.now, job.name, cpu_min.name) # start runtime timer of the new server selected self.cbs_servers[job.task].timer_runtime = Timer(self.sim, SCHED_DEADLINE.runtime_call,