|
@@ -4,15 +4,6 @@ AtomicDEVSBlock ResourceHandler {
|
|
|
parameters = 1
|
|
parameters = 1
|
|
|
initialState = "self.state, self.elapsed = {'resources': parameters[0], 'queue': []}, 0.0"
|
|
initialState = "self.state, self.elapsed = {'resources': parameters[0], 'queue': []}, 0.0"
|
|
|
|
|
|
|
|
- constructor = """
|
|
|
|
|
- def __init__(self, resources):
|
|
|
|
|
- AtomicDEVS.__init__(self, "__resource_handler")
|
|
|
|
|
- self.state = {'resources': resources, 'queue': []}
|
|
|
|
|
- self.elapsed = 0.0
|
|
|
|
|
- self.resource_in = self.addInPort("resource_in")
|
|
|
|
|
- self.resource_out = self.addOutPort("resource_out")
|
|
|
|
|
- """
|
|
|
|
|
-
|
|
|
|
|
timeAdvance = """
|
|
timeAdvance = """
|
|
|
if self.state['queue'] and self.state['resources']:
|
|
if self.state['queue'] and self.state['resources']:
|
|
|
# Can grant a resource
|
|
# Can grant a resource
|
|
@@ -20,30 +11,30 @@ AtomicDEVSBlock ResourceHandler {
|
|
|
else:
|
|
else:
|
|
|
# No request queued, or no available resources to handle the request
|
|
# No request queued, or no available resources to handle the request
|
|
|
return float('inf')
|
|
return float('inf')
|
|
|
- """
|
|
|
|
|
|
|
+ """
|
|
|
|
|
|
|
|
outputFnc = """
|
|
outputFnc = """
|
|
|
return {self.resource_out: {'id': self.state['queue'][0]}}
|
|
return {self.resource_out: {'id': self.state['queue'][0]}}
|
|
|
- """
|
|
|
|
|
|
|
+ """
|
|
|
|
|
|
|
|
intTransition = """
|
|
intTransition = """
|
|
|
# Processed a request that could be processed
|
|
# Processed a request that could be processed
|
|
|
self.state['resources'] -= 1
|
|
self.state['resources'] -= 1
|
|
|
del self.state['queue'][0]
|
|
del self.state['queue'][0]
|
|
|
return self.state
|
|
return self.state
|
|
|
- """
|
|
|
|
|
|
|
+ """
|
|
|
|
|
|
|
|
extTransition = """
|
|
extTransition = """
|
|
|
for inp in inputs[self.resource_in]:
|
|
for inp in inputs[self.resource_in]:
|
|
|
- if inp['type'] == "request":
|
|
|
|
|
|
|
+ if inp['type'] == 'request':
|
|
|
# Queue the request
|
|
# Queue the request
|
|
|
self.state['queue'].append(inp['id'])
|
|
self.state['queue'].append(inp['id'])
|
|
|
- elif inp['type'] == "release":
|
|
|
|
|
|
|
+ elif inp['type'] == 'release':
|
|
|
# Increment the number of available resources
|
|
# Increment the number of available resources
|
|
|
self.state['resources'] += 1
|
|
self.state['resources'] += 1
|
|
|
|
|
|
|
|
return self.state
|
|
return self.state
|
|
|
- """
|
|
|
|
|
|
|
+ """
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
InputPort rh_ri {
|
|
InputPort rh_ri {
|
|
@@ -64,7 +55,7 @@ AtomicDEVSBlock Activity {
|
|
|
class ActivityState(object):
|
|
class ActivityState(object):
|
|
|
def __init__(self, name, distribution):
|
|
def __init__(self, name, distribution):
|
|
|
self.timer = float('inf')
|
|
self.timer = float('inf')
|
|
|
- self.mode = "inactive"
|
|
|
|
|
|
|
+ self.mode = 'inactive'
|
|
|
self.counter = 0
|
|
self.counter = 0
|
|
|
self.name = name
|
|
self.name = name
|
|
|
self.distribution = distribution
|
|
self.distribution = distribution
|
|
@@ -83,25 +74,25 @@ AtomicDEVSBlock Activity {
|
|
|
"""
|
|
"""
|
|
|
|
|
|
|
|
outputFnc = """
|
|
outputFnc = """
|
|
|
- if self.state.mode == "active":
|
|
|
|
|
|
|
+ if self.state.mode == 'active':
|
|
|
# Output the control token to the next model in line, and release the resources
|
|
# Output the control token to the next model in line, and release the resources
|
|
|
- return {self.control_out: {}, self.resource_out: [{'type': "release"}]}
|
|
|
|
|
- elif self.state.mode == "request_resource":
|
|
|
|
|
|
|
+ return {self.control_out: {}, self.resource_out: [{'type': 'release'}]}
|
|
|
|
|
+ elif self.state.mode == 'request_resource':
|
|
|
# Output a request for resources with a specified ID (used to find out whether this was our request)
|
|
# Output a request for resources with a specified ID (used to find out whether this was our request)
|
|
|
- return {self.resource_out: [{'type': "request", 'id': "%s-%s" % (self.state.name, self.state.counter)}]}
|
|
|
|
|
|
|
+ return {self.resource_out: [{'type': 'request', 'id': '%s-%s' % (self.state.name, self.state.counter)}]}
|
|
|
else:
|
|
else:
|
|
|
return {}
|
|
return {}
|
|
|
"""
|
|
"""
|
|
|
|
|
|
|
|
intTransition = """
|
|
intTransition = """
|
|
|
self.state.timer -= self.timeAdvance()
|
|
self.state.timer -= self.timeAdvance()
|
|
|
- if self.state.mode == "request_resource":
|
|
|
|
|
|
|
+ if self.state.mode == 'request_resource':
|
|
|
# Go and request the required resource
|
|
# Go and request the required resource
|
|
|
- self.state.mode = "wait_resource"
|
|
|
|
|
|
|
+ self.state.mode = 'wait_resource'
|
|
|
self.state.timer = float('inf')
|
|
self.state.timer = float('inf')
|
|
|
- elif self.state.mode == "active":
|
|
|
|
|
|
|
+ elif self.state.mode == 'active':
|
|
|
# Finished execution, so release resources
|
|
# Finished execution, so release resources
|
|
|
- self.state.mode = "inactive"
|
|
|
|
|
|
|
+ self.state.mode = 'inactive'
|
|
|
self.state.timer = 0.0
|
|
self.state.timer = 0.0
|
|
|
self.state.timer = float('inf')
|
|
self.state.timer = float('inf')
|
|
|
self.state.counter += 1
|
|
self.state.counter += 1
|
|
@@ -110,15 +101,15 @@ AtomicDEVSBlock Activity {
|
|
|
|
|
|
|
|
extTransition = """
|
|
extTransition = """
|
|
|
self.state.timer -= self.elapsed
|
|
self.state.timer -= self.elapsed
|
|
|
- if self.state.mode == "inactive" and self.control_in in inputs:
|
|
|
|
|
|
|
+ if self.state.mode == 'inactive' and self.control_in in inputs:
|
|
|
# Got control token, so ask for the required resources
|
|
# Got control token, so ask for the required resources
|
|
|
- self.state.mode = "request_resource"
|
|
|
|
|
|
|
+ self.state.mode = 'request_resource'
|
|
|
self.state.timer = 0.0
|
|
self.state.timer = 0.0
|
|
|
# NOTE this violates DEVS, though is easy to debug
|
|
# NOTE this violates DEVS, though is easy to debug
|
|
|
- #print("Activate " + str(self.state.name) + " at time " + str(self.time_last[0] + self.elapsed))
|
|
|
|
|
- elif self.state.mode == "wait_resource" and self.resource_in in inputs and inputs[self.resource_in]['id'] == "%s-%s" % (self.state.name, self.state.counter):
|
|
|
|
|
|
|
+ #print('Activate ' + str(self.state.name) + ' at time ' + str(self.time_last[0] + self.elapsed))
|
|
|
|
|
+ elif self.state.mode == 'wait_resource' and self.resource_in in inputs and inputs[self.resource_in]['id'] == '%s-%s' % (self.state.name, self.state.counter):
|
|
|
# Got required resources, so start execution
|
|
# Got required resources, so start execution
|
|
|
- self.state.mode = "active"
|
|
|
|
|
|
|
+ self.state.mode = 'active'
|
|
|
self.state.timer = self.state.random_sample()
|
|
self.state.timer = self.state.random_sample()
|
|
|
return self.state
|
|
return self.state
|
|
|
"""
|
|
"""
|
|
@@ -208,8 +199,8 @@ OutputPort syn_co {
|
|
|
name = "control_out"
|
|
name = "control_out"
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-DEVSBlockToPort (Synchronization, syn_ri) {}
|
|
|
|
|
-DEVSBlockToPort (Synchronization, syn_ro) {}
|
|
|
|
|
|
|
+DEVSBlockToPort (Synchronization, syn_ci) {}
|
|
|
|
|
+DEVSBlockToPort (Synchronization, syn_co) {}
|
|
|
|
|
|
|
|
AtomicDEVSBlock ExclusiveChoice {
|
|
AtomicDEVSBlock ExclusiveChoice {
|
|
|
name = "ExclusiveChoice"
|
|
name = "ExclusiveChoice"
|
|
@@ -321,7 +312,7 @@ AtomicDEVSBlock MultiInstance {
|
|
|
self.spawned = num
|
|
self.spawned = num
|
|
|
self.collected = 0
|
|
self.collected = 0
|
|
|
self.counter = 0
|
|
self.counter = 0
|
|
|
- self.mode = "inactive"
|
|
|
|
|
|
|
+ self.mode = 'inactive'
|
|
|
self.running_tasks = []
|
|
self.running_tasks = []
|
|
|
self.requested = []
|
|
self.requested = []
|
|
|
self.name = name
|
|
self.name = name
|
|
@@ -337,24 +328,24 @@ AtomicDEVSBlock MultiInstance {
|
|
|
"""
|
|
"""
|
|
|
|
|
|
|
|
timeAdvance = """
|
|
timeAdvance = """
|
|
|
- if self.state.mode == "finish":
|
|
|
|
|
|
|
+ if self.state.mode == 'finish':
|
|
|
return 0.0
|
|
return 0.0
|
|
|
elif self.state.running_tasks:
|
|
elif self.state.running_tasks:
|
|
|
return self.state.running_tasks[0][0]
|
|
return self.state.running_tasks[0][0]
|
|
|
- elif self.state.mode == "request_resources":
|
|
|
|
|
|
|
+ elif self.state.mode == 'request_resources':
|
|
|
return 0.0
|
|
return 0.0
|
|
|
else:
|
|
else:
|
|
|
return float('inf')
|
|
return float('inf')
|
|
|
"""
|
|
"""
|
|
|
|
|
|
|
|
outputFnc = """
|
|
outputFnc = """
|
|
|
- if self.state.mode == "request_resources":
|
|
|
|
|
|
|
+ if self.state.mode == 'request_resources':
|
|
|
# Request all resources in one go
|
|
# Request all resources in one go
|
|
|
return {self.resource_out: [{'type': 'request', 'id': i} for i in self.state.requested]}
|
|
return {self.resource_out: [{'type': 'request', 'id': i} for i in self.state.requested]}
|
|
|
- elif self.state.mode == "active":
|
|
|
|
|
|
|
+ elif self.state.mode == 'active':
|
|
|
# Finished an instance, so release it
|
|
# Finished an instance, so release it
|
|
|
return {self.resource_out: [{'type': 'release'}]}
|
|
return {self.resource_out: [{'type': 'release'}]}
|
|
|
- elif self.state.mode == "finish":
|
|
|
|
|
|
|
+ elif self.state.mode == 'finish':
|
|
|
# Finished execution of all, so pass on token
|
|
# Finished execution of all, so pass on token
|
|
|
return {self.control_out: {}}
|
|
return {self.control_out: {}}
|
|
|
else:
|
|
else:
|
|
@@ -366,17 +357,17 @@ AtomicDEVSBlock MultiInstance {
|
|
|
for t in self.state.running_tasks:
|
|
for t in self.state.running_tasks:
|
|
|
t[0] -= ta
|
|
t[0] -= ta
|
|
|
|
|
|
|
|
- if self.state.mode == "active":
|
|
|
|
|
|
|
+ if self.state.mode == 'active':
|
|
|
# Finished an instance, so pop it
|
|
# Finished an instance, so pop it
|
|
|
del self.state.running_tasks[0]
|
|
del self.state.running_tasks[0]
|
|
|
self.state.collected += 1
|
|
self.state.collected += 1
|
|
|
if self.state.collected == self.state.spawned:
|
|
if self.state.collected == self.state.spawned:
|
|
|
- self.state.mode = "finish"
|
|
|
|
|
- elif self.state.mode == "request_resources":
|
|
|
|
|
|
|
+ self.state.mode = 'finish'
|
|
|
|
|
+ elif self.state.mode == 'request_resources':
|
|
|
# Requested resources, so be ready for a response
|
|
# Requested resources, so be ready for a response
|
|
|
- self.state.mode = "active"
|
|
|
|
|
- elif self.state.mode == "finish":
|
|
|
|
|
- self.state.mode = "inactive"
|
|
|
|
|
|
|
+ self.state.mode = 'active'
|
|
|
|
|
+ elif self.state.mode == 'finish':
|
|
|
|
|
+ self.state.mode = 'inactive'
|
|
|
self.state.collected = 0
|
|
self.state.collected = 0
|
|
|
self.state.counter += 1
|
|
self.state.counter += 1
|
|
|
self.state.running_tasks = []
|
|
self.state.running_tasks = []
|
|
@@ -388,15 +379,15 @@ AtomicDEVSBlock MultiInstance {
|
|
|
for t in self.state.running_tasks:
|
|
for t in self.state.running_tasks:
|
|
|
t[0] -= self.elapsed
|
|
t[0] -= self.elapsed
|
|
|
|
|
|
|
|
- if self.state.mode == "inactive" and self.control_in in inputs:
|
|
|
|
|
- self.state.mode = "request_resources"
|
|
|
|
|
- self.state.requested = ["%s-%s-%s" % (self.state.name, self.state.counter, i) for i in range(self.state.spawned)]
|
|
|
|
|
|
|
+ if self.state.mode == 'inactive' and self.control_in in inputs:
|
|
|
|
|
+ self.state.mode = 'request_resources'
|
|
|
|
|
+ self.state.requested = ['%s-%s-%s' % (self.state.name, self.state.counter, i) for i in range(self.state.spawned)]
|
|
|
|
|
|
|
|
- if self.state.mode in ["active", "release_resource"] and self.resource_in in inputs:
|
|
|
|
|
|
|
+ if self.state.mode in ['active', 'release_resource'] and self.resource_in in inputs:
|
|
|
# Got a resource, so allocate it to an activity
|
|
# Got a resource, so allocate it to an activity
|
|
|
self.state.running_tasks.append([self.state.task_time(), self.state.requested.pop(0)])
|
|
self.state.running_tasks.append([self.state.task_time(), self.state.requested.pop(0)])
|
|
|
# NOTE this violates DEVS, though is easy to debug
|
|
# NOTE this violates DEVS, though is easy to debug
|
|
|
- #print("Spawn " + str(self.state.running_tasks[-1][1]) + " at time " + str(self.time_last[0] + self.elapsed))
|
|
|
|
|
|
|
+ #print('Spawn ' + str(self.state.running_tasks[-1][1]) + ' at time ' + str(self.time_last[0] + self.elapsed))
|
|
|
self.state.running_tasks.sort()
|
|
self.state.running_tasks.sort()
|
|
|
return self.state
|
|
return self.state
|
|
|
"""
|
|
"""
|
|
@@ -406,7 +397,7 @@ InputPort mi_ci {
|
|
|
name = "control_in"
|
|
name = "control_in"
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-OutputPort mu_co {
|
|
|
|
|
|
|
+OutputPort mi_co {
|
|
|
name = "control_out"
|
|
name = "control_out"
|
|
|
}
|
|
}
|
|
|
|
|
|