Commit d7ec2fb6 by Michael Schmid

intermediate commit, not working

parent b7a117cf
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "simso",
"type": "python",
"request": "launch",
"program": "${workspaceFolder}/script.py",
"console": "internalConsole",
"justMyCode": false
}
]
}
\ No newline at end of file
{
"python.pythonPath": "/usr/bin/python",
"editor.tokenColorCustomizations": {
"textMateRules": [
{
"scope": "googletest.failed",
"settings": {
"foreground": "#f00"
}
},
{
"scope": "googletest.passed",
"settings": {
"foreground": "#0f0"
}
},
{
"scope": "googletest.run",
"settings": {
"foreground": "#0f0"
}
}
]
},
"python.linting.pylintEnabled": true,
"python.linting.enabled": true
}
\ No newline at end of file
# coding=utf-8 # coding=utf-8
from SimPy.Simulation import Process, hold, passivate # from SimPy.Simulation import Process, hold, passivate
from simpy import Process, Interrupt
from simso.core.JobEvent import JobEvent from simso.core.JobEvent import JobEvent
from math import ceil from math import ceil
...@@ -27,7 +28,7 @@ class Job(Process): ...@@ -27,7 +28,7 @@ class Job(Process):
:type etm: AbstractExecutionTimeModel :type etm: AbstractExecutionTimeModel
:type sim: Model :type sim: Model
""" """
Process.__init__(self, name=name, sim=sim) Process.__init__(self, env=sim, generator=self.activate_job()) # TODO: what to pass as generator?
self._task = task self._task = task
self._pred = pred self._pred = pred
self.instr_count = 0 # Updated by the cache model. self.instr_count = 0 # Updated by the cache model.
...@@ -37,14 +38,15 @@ class Job(Process): ...@@ -37,14 +38,15 @@ class Job(Process):
self._start_date = None self._start_date = None
self._end_date = None self._end_date = None
self._is_preempted = False self._is_preempted = False
self._activation_date = self.sim.now_ms()
self._absolute_deadline = self.sim.now_ms() + task.deadline
self._aborted = False self._aborted = False
self._sim = sim self._sim = sim
self._activation_date = self._sim.now_ms()
self._absolute_deadline = self._sim.now_ms() + task.deadline
self._monitor = monitor self._monitor = monitor
self._etm = etm self._etm = etm
self._was_running_on = task.cpu self._was_running_on = task.cpu
self._wcet = task.wcet self._wcet = task.wcet
self.name = name
self._on_activate() self._on_activate()
...@@ -62,7 +64,7 @@ class Job(Process): ...@@ -62,7 +64,7 @@ class Job(Process):
self._etm.on_activate(self) self._etm.on_activate(self)
def _on_execute(self): def _on_execute(self):
self._last_exec = self.sim.now() self._last_exec = self._sim.now()
self._etm.on_execute(self) self._etm.on_execute(self)
if self._is_preempted: if self._is_preempted:
...@@ -76,7 +78,7 @@ class Job(Process): ...@@ -76,7 +78,7 @@ class Job(Process):
def _on_stop_exec(self): def _on_stop_exec(self):
if self._last_exec is not None: 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 self._last_exec = None
def _on_preempted(self): def _on_preempted(self):
...@@ -87,13 +89,13 @@ class Job(Process): ...@@ -87,13 +89,13 @@ class Job(Process):
self._monitor.observe(JobEvent(self, JobEvent.PREEMPTED)) self._monitor.observe(JobEvent(self, JobEvent.PREEMPTED))
self._sim.logger.log(self.name + " Preempted! ret: " + self._sim.logger.log(self.name + " Preempted! ret: " +
str(self.interruptLeft), kernel=True) str("Don't know what to pass else?"), kernel=True) # TODO: what to pass as interrupted?
def _on_terminated(self): def _on_terminated(self):
self._on_stop_exec() self._on_stop_exec()
self._etm.on_terminated(self) 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._monitor.observe(JobEvent(self, JobEvent.TERMINATED))
self._task.end_job(self) self._task.end_job(self)
self._task.cpu.terminate(self) self._task.cpu.terminate(self)
...@@ -102,7 +104,7 @@ class Job(Process): ...@@ -102,7 +104,7 @@ class Job(Process):
def _on_abort(self): def _on_abort(self):
self._on_stop_exec() self._on_stop_exec()
self._etm.on_abort(self) self._etm.on_abort(self)
self._end_date = self.sim.now() self._end_date = self._sim.now()
self._aborted = True self._aborted = True
self._monitor.observe(JobEvent(self, JobEvent.ABORTED)) self._monitor.observe(JobEvent(self, JobEvent.ABORTED))
self._task.end_job(self) self._task.end_job(self)
...@@ -181,7 +183,7 @@ class Job(Process): ...@@ -181,7 +183,7 @@ class Job(Process):
Dynamic laxity of the job in ms. Dynamic laxity of the job in ms.
""" """
return (self.absolute_deadline - self.ret return (self.absolute_deadline - self.ret
) * self.sim.cycles_per_ms - self.sim.now() ) * self._sim.cycles_per_ms - self._sim.now()
@property @property
def computation_time(self): def computation_time(self):
...@@ -199,7 +201,7 @@ class Job(Process): ...@@ -199,7 +201,7 @@ class Job(Process):
return int(self._computation_time) return int(self._computation_time)
else: else:
return (int(self._computation_time) + return (int(self._computation_time) +
self.sim.now() - self._last_exec) self._sim.now() - self._last_exec)
@property @property
def actual_computation_time(self): def actual_computation_time(self):
...@@ -288,39 +290,35 @@ class Job(Process): ...@@ -288,39 +290,35 @@ class Job(Process):
return self._pred return self._pred
def activate_job(self): def activate_job(self):
self._start_date = self.sim.now() self._start_date = self._sim.now()
# Notify the OS. # Notify the OS.
self._task.cpu.activate(self) self._task.cpu.activate(self)
# While the job's execution is not finished. # While the job's execution is not finished.
while self._end_date is None: while self._end_date is None:
# Wait an execute order. # Wait an execute order.
yield passivate, self try:
yield self._sim.event()
# Execute the job. except Interrupt:
if not self.interrupted(): pass
else:
self._on_execute() self._on_execute()
# ret is a duration lower than the remaining execution time. # ret is a duration lower than the remaining execution time.
ret = self._etm.get_ret(self) ret = self._etm.get_ret(self)
while ret > 0: while ret > 0:
yield hold, self, int(ceil(ret)) try:
yield self._sim.timeout(int(ceil(ret)))
if not self.interrupted(): except Interrupt:
# If executed without interruption for ret cycles.
ret = self._etm.get_ret(self)
else:
self._on_preempted() self._on_preempted()
self.interruptReset()
break break
else:
ret = self._etm.get_ret(self)
if ret <= 0: if ret <= 0:
# End of job. # End of job.
self._on_terminated() self._on_terminated()
else:
self.interruptReset()
class SequentialJob(Job): class SequentialJob(Job):
pass pass
......
# coding=utf-8 # coding=utf-8
from SimPy.Simulation import Monitor from simso.core.Monitor import Monitor
class Logger(object): class Logger(object):
""" """
...@@ -13,7 +12,7 @@ class Logger(object): ...@@ -13,7 +12,7 @@ class Logger(object):
- `sim`: The :class:`model <simso.core.Model.Model>` object. - `sim`: The :class:`model <simso.core.Model.Model>` object.
""" """
self.sim = sim self.sim = sim
self._logs = Monitor(name="Logs", sim=sim) self._logs = Monitor(name="Logs", env=sim)
def log(self, msg, kernel=False): def log(self, msg, kernel=False):
""" """
......
# coding=utf-8 # coding=utf-8
from SimPy.Simulation import Simulation # from simpy.Simulation import Simulation
from simpy import Environment
from simso.core.Processor import Processor from simso.core.Processor import Processor
from simso.core.Task import Task from simso.core.Task import Task
from simso.core.Timer import Timer from simso.core.Timer import Timer
from simso.core.etm import execution_time_models from simso.core.etm import execution_time_models
from simso.core.Logger import Logger from simso.core.Logger import Logger
from simso.core.results import Results from simso.core.results import Results
import SimPy as SPPc
class Model(Simulation): class Model(Environment):
""" """
Main class for the simulation. It instantiate the various components Main class for the simulation. It instantiate the various components
required by the simulation and run it. required by the simulation and run it.
...@@ -27,8 +27,7 @@ class Model(Simulation): ...@@ -27,8 +27,7 @@ class Model(Simulation):
Methods: Methods:
""" """
print(SPPc.__version__) Environment.__init__(self)
Simulation.__init__(self)
self._logger = Logger(self) self._logger = Logger(self)
task_info_list = configuration.task_info_list task_info_list = configuration.task_info_list
proc_info_list = configuration.proc_info_list proc_info_list = configuration.proc_info_list
...@@ -76,7 +75,7 @@ class Model(Simulation): ...@@ -76,7 +75,7 @@ class Model(Simulation):
self.results = None self.results = None
def now_ms(self): def now_ms(self):
return float(self.now()) / self._cycles_per_ms return float(self.now) / self._cycles_per_ms
@property @property
def logs(self): def logs(self):
...@@ -127,25 +126,25 @@ class Model(Simulation): ...@@ -127,25 +126,25 @@ class Model(Simulation):
def _on_tick(self): def _on_tick(self):
if self._callback: if self._callback:
self._callback(self.now()) self._callback(self.now)
def run_model(self): def run_model(self):
""" Execute the simulation.""" """ Execute the simulation."""
self.initialize() # self.initialize()
self.scheduler.init() self.scheduler.init()
self.progress.start() self.progress.start()
for cpu in self._processors: for cpu in self._processors:
self.activate(cpu, cpu.run()) self.process(cpu.run())
for task in self._task_list: for task in self._task_list:
self.activate(task, task.execute()) self.process(task.execute())
try: try:
self.simulate(until=self._duration) self.run(until=self._duration)
finally: finally:
self._etm.update() self._etm.update()
if self.now() > 0: if self.now > 0:
self.results = Results(self) self.results = Results(self)
self.results.end() self.results.end()
class Monitor(list):
""" Monitored variables
A Class for monitored variables, that is, variables that allow one
to gather simple statistics. A Monitor is a subclass of list and
list operations can be performed on it. An object is established
using m = Monitor(name = '..'). It can be given a
unique name for use in debugging and in tracing and ylab and tlab
strings for labelling graphs.
"""
def __init__(self, env , name = 'a_Monitor', ylab = 'y', tlab = 't'):
list.__init__(self)
self.env = env
self.startTime = 0.0
self.name = name
self.ylab = ylab
self.tlab = tlab
def observe(self, y,t = None):
"""record y and t"""
if t is None: t = self.env.now()
self.append([t, y])
def tally(self, y):
""" deprecated: tally for backward compatibility"""
self.observe(y, 0)
def accum(self, y,t = None):
""" deprecated: accum for backward compatibility"""
self.observe(y, t)
def reset(self, t = None):
"""reset the sums and counts for the monitored variable """
self[:] = []
if t is None: t = self.env.now()
self.startTime = t
def tseries(self):
""" the series of measured times"""
return list(zip(*self))[0]
def yseries(self):
""" the series of measured values"""
return list(zip(*self))[1]
def count(self):
""" deprecated: the number of observations made """
return self.__len__()
def total(self):
""" the sum of the y"""
if self.__len__() == 0: return 0
else:
sum = 0.0
for i in range(self.__len__()):
sum += self[i][1]
return sum # replace by sum() later
def mean(self):
""" the simple average of the monitored variable"""
try:
return 1.0 * self.total() / self.__len__()
except ZeroDivisionError:
raise ZeroDivisionError('SimPy: No observations for mean')
def var(self):
""" the sample variance of the monitored variable """
n = len(self)
tot = self.total()
ssq = 0.0
for i in range(self.__len__()):
ssq += self[i][1] ** 2 # replace by sum() eventually
try:
return (ssq - float(tot * tot) / n) / n
except:
raise ZeroDivisionError(
'SimPy: No observations for sample variance')
def timeAverage(self, t = None):
"""
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()
"""
N = self.__len__()
if N == 0:
return None
if t is None: t = self.env.now()
sum = 0.0
tlast = self[0][0]
ylast = self[0][1]
for i in range(N):
ti, yi = self[i]
sum += ylast * (ti - tlast)
tlast = ti
ylast = yi
sum += ylast * (t - tlast)
T = t - self[0][0]
if T == 0:
return None
return sum / float(T)
def timeVariance(self, t = None):
""" 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()
"""
N = self.__len__()
if N == 0:
return None
if t is None: t = self.env.now()
sm = 0.0
ssq = 0.0
tlast = self[0][0]
# print 'DEBUG: 1 twVar ', t, tlast
ylast = self[0][1]
for i in range(N):
ti, yi = self[i]
sm += ylast * (ti - tlast)
ssq += ylast * ylast * (ti - tlast)
tlast = ti
ylast = yi
sm += ylast * (t - tlast)
ssq += ylast * ylast * (t - tlast)
T = t - self[0][0]
if T == 0:
return None
mn = sm / float(T)
return ssq / float(T) - mn * mn
# coding=utf-8 # coding=utf-8
from collections import deque from collections import deque
from SimPy.Simulation import Process, Monitor, hold, waituntil from simpy import Process
# from SimPy.Simulation import Process, Monitor, hold, waituntil
from simso.core.ProcEvent import ProcRunEvent, ProcIdleEvent, \ from simso.core.ProcEvent import ProcRunEvent, ProcIdleEvent, \
ProcOverheadEvent, ProcCxtSaveEvent, ProcCxtLoadEvent ProcOverheadEvent, ProcCxtSaveEvent, ProcCxtLoadEvent
from simso.core.Monitor import Monitor
RESCHED = 1 RESCHED = 1
ACTIVATE = 2 ACTIVATE = 2
...@@ -53,7 +54,7 @@ class Processor(Process): ...@@ -53,7 +54,7 @@ class Processor(Process):
cls._identifier = 0 cls._identifier = 0
def __init__(self, model, proc_info): def __init__(self, model, proc_info):
Process.__init__(self, name=proc_info.name, sim=model) Process.__init__(self, env=model, generator=self.run()) # TODO: what to pass as generator?
self._model = model self._model = model
self._internal_id = Processor._identifier self._internal_id = Processor._identifier
Processor._identifier += 1 Processor._identifier += 1
...@@ -62,15 +63,14 @@ class Processor(Process): ...@@ -62,15 +63,14 @@ class Processor(Process):
self.was_running = None self.was_running = None
self._evts = deque([]) self._evts = deque([])
self.sched = model.scheduler self.sched = model.scheduler
self.monitor = Monitor(name="Monitor" + proc_info.name, sim=model) self.monitor = Monitor(env=model, name="Monitor" + proc_info.name)
self._caches = [] self._caches = []
self._penalty = proc_info.penalty self._penalty = proc_info.penalty
self._cs_overhead = proc_info.cs_overhead self._cs_overhead = proc_info.cs_overhead
self._cl_overhead = proc_info.cl_overhead self._cl_overhead = proc_info.cl_overhead
self._migration_overhead = proc_info.migration_overhead self._migration_overhead = proc_info.migration_overhead
self.set_caches(proc_info.caches) self.set_caches(proc_info.caches)
self.timer_monitor = Monitor(name="Monitor Timer" + proc_info.name, self.timer_monitor = Monitor(env=model, name="Monitor Timer" + proc_info.name)
sim=model)
self._speed = proc_info.speed self._speed = proc_info.speed
def resched(self): def resched(self):
...@@ -143,28 +143,32 @@ class Processor(Process): ...@@ -143,28 +143,32 @@ class Processor(Process):
""" """
return self._running return self._running
def waituntil(self, cond_func, delay=1):
while not cond_func():
yield self.env.timeout(delay)
def run(self): def run(self):
while True: while True:
if not self._evts: if not self._evts:
job = self._running job = self._running
if job: if job:
yield waituntil, self, lambda: job.context_ok yield self.waituntil(lambda: job.context_ok)
self.monitor.observe(ProcCxtLoadEvent()) self.monitor.observe(ProcCxtLoadEvent())
yield hold, self, self.cl_overhead # overhead load context yield self._model.timeout(self.cl_overhead) # overhead load context
self.monitor.observe(ProcCxtLoadEvent(terminated=True)) self.monitor.observe(ProcCxtLoadEvent(terminated=True))
job.interruptReset() job.interruptReset()
self.sim.reactivate(job) self.env.reactivate(job)
self.monitor.observe(ProcRunEvent(job)) self.monitor.observe(ProcRunEvent(job))
job.context_ok = False job.context_ok = False
else: else:
self.monitor.observe(ProcIdleEvent()) self.monitor.observe(ProcIdleEvent())
# Wait event. # Wait event.
yield waituntil, self, lambda: self._evts yield self.waituntil(lambda: self._evts)
if job: if job:
self.interrupt(job) self.interrupt(job)
self.monitor.observe(ProcCxtSaveEvent()) self.monitor.observe(ProcCxtSaveEvent())
yield hold, self, self.cs_overhead # overhead save context yield self._model.timeout(self.cs_overhead) # overhead save context
self.monitor.observe(ProcCxtSaveEvent(terminated=True)) self.monitor.observe(ProcCxtSaveEvent(terminated=True))
job.context_ok = True job.context_ok = True
...@@ -178,28 +182,28 @@ class Processor(Process): ...@@ -178,28 +182,28 @@ class Processor(Process):
self.sched.on_activate(evt[1]) self.sched.on_activate(evt[1])
self.monitor.observe(ProcOverheadEvent("JobActivation")) self.monitor.observe(ProcOverheadEvent("JobActivation"))
self.sched.monitor_begin_activate(self) self.sched.monitor_begin_activate(self)
yield hold, self, self.sched.overhead_activate yield self._model.timeout(self.sched.overhead_activate)
self.sched.monitor_end_activate(self) self.sched.monitor_end_activate(self)
elif evt[0] == TERMINATE: elif evt[0] == TERMINATE:
self.sched.on_terminated(evt[1]) self.sched.on_terminated(evt[1])
self.monitor.observe(ProcOverheadEvent("JobTermination")) self.monitor.observe(ProcOverheadEvent("JobTermination"))
self.sched.monitor_begin_terminate(self) self.sched.monitor_begin_terminate(self)
yield hold, self, self.sched.overhead_terminate yield self._model.timeout(self.sched.overhead_terminate)
self.sched.monitor_end_terminate(self) self.sched.monitor_end_terminate(self)
elif evt[0] == TIMER: elif evt[0] == TIMER:
self.timer_monitor.observe(None) self.timer_monitor.observe(None)
if evt[1].overhead > 0: if evt[1].overhead > 0:
print(self.sim.now(), "hold", evt[1].overhead) print(self.env.now(), "hold", evt[1].overhead)
yield hold, self, evt[1].overhead yield self._model.timeout(evt[1].overhead)
evt[1].call_handler() evt[1].call_handler()
elif evt[0] == SPEED: elif evt[0] == SPEED:
self._speed = evt[1] self._speed = evt[1]
elif evt[0] == RESCHED: elif evt[0] == RESCHED:
self.monitor.observe(ProcOverheadEvent("Scheduling")) self.monitor.observe(ProcOverheadEvent("Scheduling"))
self.sched.monitor_begin_schedule(self) self.sched.monitor_begin_schedule(self)
yield waituntil, self, self.sched.get_lock yield self.waituntil(self.sched.get_lock)
decisions = self.sched.schedule(self) decisions = self.sched.schedule(self)
yield hold, self, self.sched.overhead # overhead scheduling yield self._model.timeout(self.sched.overhead) # overhead scheduling
if type(decisions) is not list: if type(decisions) is not list:
decisions = [decisions] decisions = [decisions]
decisions = [d for d in decisions if d is not None] decisions = [d for d in decisions if d is not None]
......
...@@ -6,11 +6,12 @@ import importlib ...@@ -6,11 +6,12 @@ import importlib
import pkgutil import pkgutil
import inspect import inspect
from simso.core.Monitor import Monitor
from simso.core.SchedulerEvent import SchedulerBeginScheduleEvent, \ from simso.core.SchedulerEvent import SchedulerBeginScheduleEvent, \
SchedulerEndScheduleEvent, SchedulerBeginActivateEvent, \ SchedulerEndScheduleEvent, SchedulerBeginActivateEvent, \
SchedulerEndActivateEvent, SchedulerBeginTerminateEvent, \ SchedulerEndActivateEvent, SchedulerBeginTerminateEvent, \
SchedulerEndTerminateEvent SchedulerEndTerminateEvent
from SimPy.Simulation import Monitor
class SchedulerInfo(object): class SchedulerInfo(object):
...@@ -145,7 +146,7 @@ class Scheduler(object): ...@@ -145,7 +146,7 @@ class Scheduler(object):
self.overhead_activate = scheduler_info.overhead_activate self.overhead_activate = scheduler_info.overhead_activate
self.overhead_terminate = scheduler_info.overhead_terminate self.overhead_terminate = scheduler_info.overhead_terminate
self.data = scheduler_info.data self.data = scheduler_info.data
self.monitor = Monitor(name="MonitorScheduler", sim=sim) self.monitor = Monitor(name="MonitorScheduler", env=sim)
def init(self): def init(self):
""" """
......
# coding=utf-8 # coding=utf-8
import simpy
from simpy import Process
from collections import deque from collections import deque
from SimPy.Simulation import Process, Monitor, hold, passivate # from SimPy.Simulation import Process, Monitor, hold, passivate
from simso.core.Job import Job from simso.core.Job import Job
from simso.core.Timer import Timer from simso.core.Timer import Timer
from simso.core.Monitor import Monitor
from .CSDP import CSDP from .CSDP import CSDP
import os import os
...@@ -129,11 +132,11 @@ class GenericTask(Process): ...@@ -129,11 +132,11 @@ class GenericTask(Process):
:type sim: Model :type sim: Model
:type task_info: TaskInfo :type task_info: TaskInfo
""" """
Process.__init__(self, name=task_info.name, sim=sim) Process.__init__(self, env=sim, generator=self.execute())
self.name = task_info.name self.name = task_info.name
self._task_info = task_info self._task_info = task_info
self._monitor = Monitor(name="Monitor" + self.name + "_states", self._monitor = Monitor(name="Monitor" + self.name + "_states",
sim=sim) env=sim)
self._activations_fifo = deque([]) self._activations_fifo = deque([])
self._sim = sim self._sim = sim
self.cpu = None self.cpu = None
...@@ -144,6 +147,9 @@ class GenericTask(Process): ...@@ -144,6 +147,9 @@ class GenericTask(Process):
self._jobs = [] self._jobs = []
self.job = None self.job = None
def execute(self):
pass
def __lt__(self, other): def __lt__(self, other):
return self.identifier < other.identifier return self.identifier < other.identifier
...@@ -260,12 +266,12 @@ class GenericTask(Process): ...@@ -260,12 +266,12 @@ class GenericTask(Process):
self._activations_fifo.popleft() self._activations_fifo.popleft()
if len(self._activations_fifo) > 0: if len(self._activations_fifo) > 0:
self.job = self._activations_fifo[0] self.job = self._activations_fifo[0]
self.sim.activate(self.job, self.job.activate_job()) self.env.activate(self.job, self.job.activate_job())
def _job_killer(self, job): def _job_killer(self, job):
if job.end_date is None and job.computation_time < job.wcet: if job.end_date is None and job.computation_time < job.wcet:
if self._task_info.abort_on_miss: if self._task_info.abort_on_miss:
self.cancel(job) # self.cancel(job) TODO: How to cancel Job?
job.abort() job.abort()
def create_job(self, pred=None): def create_job(self, pred=None):
...@@ -275,15 +281,15 @@ class GenericTask(Process): ...@@ -275,15 +281,15 @@ class GenericTask(Process):
""" """
self._job_count += 1 self._job_count += 1
job = Job(self, "{}_{}".format(self.name, self._job_count), pred, job = Job(self, "{}_{}".format(self.name, self._job_count), pred,
monitor=self._monitor, etm=self._etm, sim=self.sim) monitor=self._monitor, etm=self._etm, sim=self.env)
if len(self._activations_fifo) == 0: if len(self._activations_fifo) == 0:
self.job = job self.job = job
self.sim.activate(job, job.activate_job()) self.env.process(job.activate_job())
self._activations_fifo.append(job) self._activations_fifo.append(job)
self._jobs.append(job) self._jobs.append(job)
timer_deadline = Timer(self.sim, GenericTask._job_killer, timer_deadline = Timer(self.env, GenericTask._job_killer,
(self, job), self.deadline) (self, job), self.deadline)
timer_deadline.start() timer_deadline.start()
...@@ -301,7 +307,7 @@ class ATask(GenericTask): ...@@ -301,7 +307,7 @@ class ATask(GenericTask):
def execute(self): def execute(self):
self._init() self._init()
yield passivate, self yield self.env.event()
class PTask(GenericTask): class PTask(GenericTask):
...@@ -314,13 +320,13 @@ class PTask(GenericTask): ...@@ -314,13 +320,13 @@ class PTask(GenericTask):
def execute(self): def execute(self):
self._init() self._init()
# wait the activation date. # wait the activation date.
yield hold, self, int(self._task_info.activation_date * yield self.env.timeout(int(self._task_info.activation_date *
self._sim.cycles_per_ms) self._sim.cycles_per_ms))
while True: while True:
# print self.sim.now(), "activate", self.name # print self.sim.now(), "activate", self.name
self.create_job() self.create_job()
yield hold, self, int(self.period * self._sim.cycles_per_ms) yield self.env.timeout(int(self.period * self._sim.cycles_per_ms))
class SporadicTask(GenericTask): class SporadicTask(GenericTask):
...@@ -334,8 +340,8 @@ class SporadicTask(GenericTask): ...@@ -334,8 +340,8 @@ class SporadicTask(GenericTask):
self._init() self._init()
for ndate in self.list_activation_dates: for ndate in self.list_activation_dates:
yield hold, self, int(ndate * self._sim.cycles_per_ms) \ yield self.env.timeout(int(ndate * self._sim.cycles_per_ms) \
- self._sim.now() - self._sim.now())
self.create_job() self.create_job()
@property @property
...@@ -354,8 +360,8 @@ class ProbabilisticTask(GenericTask): ...@@ -354,8 +360,8 @@ class ProbabilisticTask(GenericTask):
self._init() self._init()
for ndate in self.list_activation_dates: for ndate in self.list_activation_dates:
yield hold, self, int(ndate * self._sim.cycles_per_ms) \ yield self.env.timeout(int(ndate * self._sim.cycles_per_ms) \
- self._sim.now() - self._sim.now())
self.create_job() self.create_job()
@property @property
......
# coding=utf-8 # coding=utf-8
from SimPy.Simulation import Process, hold # from SimPy.Simulation import Process, hold
from simpy import Environment, Process, Interrupt
# TODO: allow the user to specify an overhead. # TODO: allow the user to specify an overhead.
class InstanceTimer(Process): class InstanceTimer(Process):
def __init__(self, timer): def __init__(self, timer):
Process.__init__(self, name="Timer", sim=timer.sim) Process.__init__(self, env=timer.env, generator=self.run())
self.function = timer.function self.function = timer.function
self.args = timer.args self.args = timer.args
self.delay = timer.delay self.delay = timer.delay
...@@ -23,9 +24,13 @@ class InstanceTimer(Process): ...@@ -23,9 +24,13 @@ class InstanceTimer(Process):
def run(self): def run(self):
self.running = True self.running = True
while self.running: while self.running:
yield hold, self, self.delay try:
if self.interrupted() or not self.running: yield self.env.timeout(self.delay)
except Interrupt:
break break
else:
if not self.running:
break;
if self.cpu: if self.cpu:
self.cpu.timer(self) self.cpu.timer(self)
else: else:
...@@ -67,7 +72,7 @@ class Timer(object): ...@@ -67,7 +72,7 @@ class Timer(object):
Methods: Methods:
""" """
self.sim = sim self.env = sim
self.function = function self.function = function
self.args = args self.args = args
if in_ms: if in_ms:
...@@ -89,7 +94,7 @@ class Timer(object): ...@@ -89,7 +94,7 @@ class Timer(object):
Start the timer. Start the timer.
""" """
self.instance = InstanceTimer(self) self.instance = InstanceTimer(self)
self.sim.activate(self.instance, self.instance.run(), self.prior) self.env.process(self.instance.run()) # TODO: , self.prior what's with this?
def stop(self): def stop(self):
""" """
......
...@@ -9,3 +9,4 @@ from simso.core.Processor import Processor ...@@ -9,3 +9,4 @@ from simso.core.Processor import Processor
from simso.core.Scheduler import Scheduler from simso.core.Scheduler import Scheduler
from simso.core.Timer import Timer from simso.core.Timer import Timer
from simso.core.results import Results from simso.core.results import Results
from simso.core.Monitor import Monitor
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment