def test_nested_preemption(env, log): def process(id, env, res, delay, prio, preempt, log): yield env.timeout(delay) with res.request(priority=prio, preempt=preempt) as req: try: yield req yield env.timeout(5) log.append((env.now, id)) except simpy.Interrupt as ir: log.append((env.now, id, (ir.cause.by, ir.cause.usage_since))) def process2(id, env, res0, res1, delay, prio, preempt, log): yield env.timeout(delay) with res0.request(priority=prio, preempt=preempt) as req0: try: yield req0 with res1.request(priority=prio, preempt=preempt) as req1: try: yield req1 yield env.timeout(5) log.append((env.now, id)) except simpy.Interrupt as ir: log.append( (env.now, id, (ir.cause.by, ir.cause.usage_since, ir.cause.resource))) except simpy.Interrupt as ir: log.append((env.now, id, (ir.cause.by, ir.cause.usage_since, ir.cause.resource))) res0 = simpy.PreemptiveResource(env, 1) res1 = simpy.PreemptiveResource(env, 1) env.process(process2(0, env, res0, res1, 0, -1, True, log)) p1 = env.process(process(1, env, res1, 1, -2, True, log)) env.process(process2(2, env, res0, res1, 20, -1, True, log)) p3 = env.process(process(3, env, res0, 21, -2, True, log)) env.process(process2(4, env, res0, res1, 21, -1, True, log)) env.run() assert log == [ (1, 0, (p1, 0, res1)), (6, 1), (21, 2, (p3, 20, res0)), (26, 3), (31, 4), ]
def __init__(self, id, env, location, Number_of_parkings): self.env = env self.capacity = simpy.PreemptiveResource(self.env, capacity=Number_of_parkings) self.id = id self.location = location self.queue = []
def test_mixed_preemption(env, log): def process(id, env, res, delay, prio, preempt, log): yield env.timeout(delay) with res.request(priority=prio, preempt=preempt) as req: try: yield req yield env.timeout(5) log.append((env.now, id)) except simpy.Interrupt as ir: log.append((env.now, id, tuple(ir.cause))) res = simpy.PreemptiveResource(env, 2) p0 = env.start(process(0, env, res, 0, 1, True, log)) p1 = env.start(process(1, env, res, 0, 1, True, log)) p2 = env.start(process(2, env, res, 1, 0, False, log)) p3 = env.start(process(3, env, res, 1, 0, True, log)) p4 = env.start(process(4, env, res, 2, 2, True, log)) simpy.simulate(env) assert log == [ (1, 1, (p3, 0)), (5, 0), (6, 3), (10, 2), (11, 4), ]
def run_factory_simulation(m, r, pt_mean, pt_sigma, mttf, repair_time, simulation_weeks, job_duration): # Setup and start the simulation print('Machine shop') # Create an environment and start the setup process env = simpy.Environment() repairman = simpy.PreemptiveResource(env, capacity=r) machines = [ Machine(env=env, name='Machine %d' % i, repairman=repairman, pt_mean=pt_mean, pt_sigma=pt_sigma, mttf=mttf, repair_time=repair_time) for i in range(m) ] env.process(other_jobs(env, repairman, job_duration)) # Execute! sim_time = simulation_weeks * 7 * 24 * 60 env.run(until=sim_time) # Analyis/results print('Machine shop results after %s weeks' % simulation_weeks) for machine in machines: print('%s made %d parts.' % (machine.name, machine.parts_made)) return machines
def run(self): downloads = [] yield self.env.timeout(self.refresh_delay * self.rs.uniform()) while True: # print("ReFRESH %d"%self.env.now) for download in downloads: if download.is_alive: download.interrupt("refresh %s" % self.env.now) del downloads[:] download_queue = simpy.PreemptiveResource( self.env, capacity=self.concurent_download) for _, content in list( zip(range(self.storage.size()), self.contentHistory.getPopulars())): if content not in self.storage: downloads.append( self.env.process( download_process(self.env, download_queue, self.download_delay, self.storage, content))) else: # push up in self.storage[content] = True yield self.env.timeout(self.rs.poisson(self.refresh_delay, 1)[0])
def test_mixed_preemption(env, log): def p(id, env, res, delay, prio, preempt, log): yield env.timeout(delay) with res.request(priority=prio, preempt=preempt) as req: try: yield req yield env.timeout(2) log.append((env.now, id)) except simpy.Interrupt as ir: log.append((env.now, id, (ir.cause.by, ir.cause.usage_since))) res = simpy.PreemptiveResource(env, 1) # p0: First user: env.process(p(0, env, res, delay=0, prio=2, preempt=True, log=log)) # p1: Waits (cannot preempt): env.process(p(1, env, res, delay=0, prio=2, preempt=True, log=log)) # p2: Waits later, but has a higher prio: env.process(p(2, env, res, delay=1, prio=1, preempt=False, log=log)) # p3: Preempt the above proc: p3 = env.process(p(3, env, res, delay=3, prio=0, preempt=True, log=log)) # p4: Wait again: env.process(p(4, env, res, delay=4, prio=3, preempt=True, log=log)) env.run() assert log == [ (2, 0), # p0 done (3, 2, (p3, 2)), # p2 got it next, but got interrupted by p3 (5, 3), # p3 done (7, 1), # p1 done (finally got the resource) (9, 4), # p4 done ]
def run_simulation( number_of_stations: int, seed: int, simulation_time: int, skip_results: bool, config: Config, backoffs: Dict[int, Dict[int, int]], results: Dict[str, List[str]], ): random.seed(seed) environment = simpy.Environment() channel = Channel( simpy.PreemptiveResource(environment, capacity=1), simpy.Resource(environment, capacity=1), number_of_stations, backoffs, ) for i in range(1, number_of_stations + 1): Station(environment, "Station {}".format(i), channel, config) environment.run(until=simulation_time * 1000000) p_coll = "{:.4f}".format( channel.failed_transmissions / (channel.failed_transmissions + channel.succeeded_transmissions) ) print( f"SEED = {seed} N={number_of_stations} CW_MIN = {config.cw_min} CW_MAX = {config.cw_max} PCOLL: {p_coll} THR:" f" {(channel.bytes_sent*8)/(simulation_time * 1000000)} " f"FAILED_TRANSMISSIONS: {channel.failed_transmissions}" f" SUCCEEDED_TRANSMISSION {channel.succeeded_transmissions}" ) if not skip_results: add_to_results( p_coll, channel, number_of_stations, results, seed, simulation_time, config )
def __init__(self, id, env, location, power, Number_of_chargers): self.env = env self.plugs = simpy.PreemptiveResource(self.env, capacity=Number_of_chargers) self.id = id self.location = location self.power = power # kwh/min self.queue = []
def send_frame(self): self.channel.tx_list.append(self) # add station to currently transmitting list res = self.channel.tx_queue.request( # create request basing on this station frame length priority=(big_num - self.frame_to_send.frame_time) ) try: result = yield res | self.env.timeout( 0 ) # try to hold transmitting lock(station with the longest frame will get this) if ( res not in result ): # check if this station got lock, if not just wait you frame time raise simpy.Interrupt("There is a longer frame...") with self.channel.tx_lock.request() as lock: # this station has the longest frame so hold the lock yield lock log(self, self.channel.back_off_list) for ( station ) in ( self.channel.back_off_list ): # stop all station which are waiting backoff as channel is not idle station.process.interrupt() log(self, self.frame_to_send.frame_time) yield self.env.timeout( self.frame_to_send.frame_time ) # wait this station frame time self.channel.back_off_list.clear() # channel idle, clear backoff waiting list was_sent = self.check_collision() # check if collision occurred if was_sent: # transmission successful yield self.env.timeout( self.times.get_ack_frame_time() ) # wait ack self.channel.tx_list.clear() # clear transmitting list self.channel.tx_queue.release(res) # leave the transmitting queue return True # there was collision self.channel.tx_list.clear() # clear transmitting list self.channel.tx_queue.release(res) # leave the transmitting queue self.channel.tx_queue = simpy.PreemptiveResource( self.env, capacity=1 ) # create new empty transmitting queue yield self.env.timeout( self.times.ack_timeout ) # simulate ack timeout after failed transmission return False except simpy.Interrupt: # this station does not have the longest frame, waiting frame time yield self.env.timeout(self.frame_to_send.frame_time) was_sent = self.check_collision() if was_sent: # check if collision occurred yield self.env.timeout( self.times.get_ack_frame_time() ) # wait ack else: log(self, "waiting wck timeout slave") yield self.env.timeout( Times.ack_timeout ) # simulate ack timeout after failed transmission return was_sent
def test_preemptive_resource_timeout_0(env): def proc_a(env, resource, prio): with resource.request(priority=prio) as req: try: yield req yield env.timeout(1) pytest.fail('Should have received an interrupt/preemption.') except simpy.Interrupt: pass yield env.event() def proc_b(env, resource, prio): with resource.request(priority=prio) as req: yield req resource = simpy.PreemptiveResource(env, 1) env.process(proc_a(env, resource, 1)) env.process(proc_b(env, resource, 0)) env.run()
def test_preemptive_resource(env, log): def process(id, env, res, delay, prio, log): yield env.timeout(delay) with res.request(priority=prio) as req: try: yield req yield env.timeout(5) log.append((env.now, id)) except simpy.Interrupt as ir: log.append((env.now, id, (ir.cause.by, ir.cause.usage_since))) res = simpy.PreemptiveResource(env, capacity=2) env.process(process(0, env, res, 0, 1, log)) env.process(process(1, env, res, 0, 1, log)) p2 = env.process(process(2, env, res, 1, 0, log)) env.process(process(3, env, res, 2, 2, log)) env.run() assert log == [(1, 1, (p2, 0)), (5, 0), (6, 2), (10, 3)]
def __init__(self, env: simpy.Environment, sheet: xlrd.sheet, machine: Machine, conditions: RoadConditionsState, user_memory: UserMemory, persona: str, max_mental: int, max_perc: int): self.visual = simpy.PreemptiveResource(env, capacity=1) self.visual_peripheral = simpy.PreemptiveResource(env, capacity=1) self.sound_vocal = simpy.PreemptiveResource(env, capacity=1) self.sound_non_vocal = simpy.PreemptiveResource(env, capacity=1) self.haptic_hands = simpy.PreemptiveResource(env, capacity=1) self.haptic_seat = simpy.PreemptiveResource(env, capacity=1) self.psychomotor = simpy.PreemptiveResource(env, capacity=1) self.cognitive_workload = simpy.Container(env, capacity=max_mental) self.perceptional_workload = simpy.Container(env, capacity=max_perc) self.machine = machine self.road_conditions = conditions self.user_memory = user_memory # cognitive resources of human self.tasks = [ Task(env=env, row=sheet.row_values(i), resources=[ self.visual, self.visual_peripheral, self.sound_vocal, self.sound_non_vocal, self.haptic_hands, self.haptic_seat, self.psychomotor, self.cognitive_workload, self.perceptional_workload ], machine=machine, user_memory=user_memory, road_conditions=conditions) for i in np.arange(1, sheet.nrows) ] self.tasks = [ task for task in self.tasks if task.persona == persona or task.persona == '' ] self.control_tasks = [ task for task in self.tasks if 'user_switch_regime' in task.trigger ] self.env = env self.tasks_to_execute: List[Task] = [] self.interrupted_tasks = [] self.finished_tasks = [] self.env.process(self.interrupted_tasks_monitor())
def test_preemptive_resource(env): """Processes with a higher priority may preempt requests of lower priority processes. Note that higher priorities are indicated by a lower number value.""" def proc_a(env, resource, prio): try: with resource.request(priority=prio) as req: yield req pytest.fail('Should have received an interrupt/preemption.') except simpy.Interrupt: pass def proc_b(env, resource, prio): with resource.request(priority=prio) as req: yield req resource = simpy.PreemptiveResource(env, 1) env.process(proc_a(env, resource, 1)) env.process(proc_b(env, resource, 0)) env.run()
def run_factory_simulation(m, r, pt_mean, pt_sigma, mttf, repair_time, simulation_weeks, job_duration): # Create an environment and start the setup process env = simpy.Environment() repairman = simpy.PreemptiveResource(env, capacity=r) machines = [ Machine(env=env, name='Machine %d' % i, repairman=repairman, pt_mean=pt_mean, pt_sigma=pt_sigma, mttf=mttf, repair_time=repair_time) for i in range(m) ] env.process(other_jobs(env, repairman, job_duration)) # Execute! sim_time = simulation_weeks * 7 * 24 * 60 env.run(until=sim_time) return machines
def test_mixed_preemption(env, log): def process(id, env, res, delay, prio, preempt, log): yield env.timeout(delay) with res.request(priority=prio, preempt=preempt) as req: try: yield req yield env.timeout(5) log.append((env.now, id)) except simpy.Interrupt as ir: log.append((env.now, id, (ir.cause.by, ir.cause.usage_since))) res = simpy.PreemptiveResource(env, 2) env.process(process(0, env, res, 0, 1, True, log)) env.process(process(1, env, res, 0, 1, True, log)) env.process(process(2, env, res, 1, 0, False, log)) p3 = env.process(process(3, env, res, 1, 0, True, log)) env.process(process(4, env, res, 2, 2, True, log)) env.run() assert log == [(1, 1, (p3, 0)), (5, 0), (6, 3), (10, 2), (11, 4)]
repairman_at = [m.id for m in machines if m.process in repairman_processes] + ( ["unimportant_work"] if unimportant_work.process in repairman_processes else [] ) return f"Repairman at {repairman_at}; broken {broken_machines}; unimportant_work state {unimportant_work.state}, made {unimportant_work.works_made}" # Setup and start the simulation print("Machine shop") # This helps reproducing the results rng1.seed(RANDOM_SEED) rng2.seed(RANDOM_SEED) # Create an environment and start the setup process env = simpy.Environment() repairman = simpy.PreemptiveResource(env, capacity=1) machines = [ Machine(env, id=i, name=process_name(i, of=NUM_MACHINES), repairman=repairman) for i in range(NUM_MACHINES) ] unimportant_work = UnimportantWork(env, repairman=repairman) # Execute! env.run(until=SIM_TIME) # Analyis/results print("Machine shop results after %s weeks" % WEEKS) for machine in machines: print("%s made %d parts." % (machine.name, machine.parts_made)) print(snapshot(env, repairman, unimportant_work, machines))
def __init__(self, network_type, capacity): super(Network, self).__init__() self.network_type = network_type # sat|ter self.resource = simpy.PreemptiveResource(env, capacity=capacity) # resource object with given capacity
def preemtive_resource(self, *args, **kwargs): kwargs = set_env(self, args, kwargs) return simpy.PreemptiveResource(*args, **kwargs)
# random.seed(3) deadline_met = True task_arrivals = {} task_start = {} task_early_release = {} task_end = {} task_complete = {} lo_task_names = [] hi_tasks_active = [] hi_tasks_names = [] task_er_points = {} env = simpy.Environment() processor = simpy.PreemptiveResource(env, capacity=1) lo_tasks_ER = TasksetGenerator.change_ER_points(lo_tasks_ref, num_er=num_er) lo_tasks_list = [] for i, (start, period, wcet) in enumerate(lo_tasks_ER): task_name = 'Task LO ' + str(i) lo_task_names.append(task_name) task_arrivals[task_name] = [] task_start[task_name] = [] task_early_release[task_name] = [] task_end[task_name] = [] task_complete[task_name] = []
self.CTVs = CTVs self.failure_list = pd.DataFrame([]) def request_resource(self, turbine): """ A wind turbine has requested a vessel to fix a failure. This will either allocate a vessel to the turbine or let it know to wait for a period before it will try to allocate a vessel again. """ return self.CTVs[0] print('Wind Site') #random.seed(RANDOM_SEED) env = simpy.Environment() CTVs = [simpy.PreemptiveResource(env, capacity=1000)] resource_manager = resource_manager(env, "rm1", CTVs) turbines = [ turbine(env, 'Turbine %d' % i, resource_manager) for i in range(NUM_TURBINES) ] env.run(until=SIM_TIME) turbine_data = pd.DataFrame([]) turbine_data["Uptime"] = [(turbines[i].power / SIM_TIME) * 100 for i in range(NUM_TURBINES)] turbine_data["Failures"] = [ turbines[i].num_failures for i in range(NUM_TURBINES) ] fig1 = px.histogram(turbine_data, x="Uptime", nbins=100) fig1.show()
if (not message_process.triggered): message_process.interrupt("timeout") def error_generator(env, server): while True: # Wait a random amount of time to introduce the error yield env.timeout(uniform(*errorwait)) print(f"LOG_ERROR_Start error at time {env.now}") # Make an equal amount of requests to the capacity of the server # Make a list of requests request_list = [ server.request(priority=0) for i in range(server.capacity) ] for request in request_list: yield request # Send priority request to PreemptiveResource # Wait for the error to be resolved yield env.timeout(uniform(*error_duration)) # Release spots in server when the error is resolved for request in request_list: yield server.release(request) print(f"LOG_ERROR_End error at time {env.now}") if __name__ == "__main__": env = simpy.Environment() serv = simpy.PreemptiveResource(env, capacity=5) env.process(error_generator(env, serv)) env.process(message_generator(env, serv)) env.run(until=runtime)
# Setup and start the simulation # This helps reproducing the results random.seed(RANDOM_SEED) # Create an environment and start the setup process env = simpy.Environment() # Create the machine resources machines = simpy.Resource(env, capacity = NUM_MACHINES) # Create the repairmen resources repairman = simpy.PreemptiveResource(env, capacity=NUM_REPAIRMEN) # Start the machines in the factory env.process(machine(env, machines)) # Start the observation cycle simultaneously env.process(observe(env, machines)) # Start other less important processes which repairmen look after env.process(other_jobs(env, repairman)) # Execute! env.run(SIM_TIME) # The wait time per wafer
def main(user_input=False): #Environment env = simpy.Environment() #Operators main_ops = Operator(env, G.MAIN_OPERATORS) sup_ops = Operator(env, G.SUPPORT_OPERATORS) #Containers formed_sheet_stock = simpy.Container(env, G.FORMED_SHEET_STOCK_SIZE, init=0) split_formed_stock = simpy.Container(env, G.SPLIT_FORMED_STOCK_SIZE, init=0) routed_part_stock = simpy.Container(env, G.ROUTED_PART_STOCK_SIZE, init=0) trimmed_part_stock = simpy.Container(env, G.TRIMMED_PART_STOCK_SIZE, init=0) raw_sheet_stock = simpy.Container(env, G.RAW_SHEET_STOCK_SIZE, init=0) finished_part_stock = simpy.Container(env, G.FINISHED_PART_STOCK_SIZE, init=0) box = simpy.Container(env, G.BOX_SIZE, init=0) #Thermoformers station = simpy.PreemptiveResource(env, capacity=1) load_station_one = Load_Station('Load Station 1', env, main_ops, station, raw_sheet_stock, formed_sheet_stock, user_input=G.USER_INPUT) thermoformer_one = Thermoformer('Thermoformer 1', env, station, load_station_one, user_input=G.USER_INPUT) #Formed sheet splitting operation splitting_one = Splitter('Splitter 1', env, main_ops, formed_sheet_stock, split_formed_stock, user_input=G.USER_INPUT) #Automatic Sheeters sheeter_one = Sheeter('Sheeter 1', env, main_ops, raw_sheet_stock, user_input=G.USER_INPUT) #Robotic Routers router_one = Router('Router 1', env, main_ops, split_formed_stock, routed_part_stock, user_input=G.USER_INPUT) router_two = Router('Router 2', env, sup_ops, split_formed_stock, routed_part_stock, user_input=G.USER_INPUT) router_three = Router('Router 3', env, sup_ops, split_formed_stock, routed_part_stock, user_input=G.USER_INPUT) #Hotwire Trimmer trimmer_one = Hotwire_Trimmer('Hotwire trimmer 1', env, sup_ops, routed_part_stock, trimmed_part_stock, user_input=G.USER_INPUT) #Driller driller_one = Driller('Driller 1', env, sup_ops, trimmed_part_stock, finished_part_stock, user_input=G.USER_INPUT) #Boxer boxer_one = Boxer('Boxer 1', env, sup_ops, finished_part_stock, box, user_input=G.USER_INPUT) #Run the simulation environment env.run(until=G.SIMULATION_TIME) wip = formed_sheet_stock.level * 2 + split_formed_stock.level + routed_part_stock.level + trimmed_part_stock.level + finished_part_stock.level #Generic summary report if G.USER_INPUT == True: print('\n\nResults:') print('{0} produced {1} sheets'.format(sheeter_one.name, sheeter_one.sheets)) print('{0} produced {1} parts'.format(router_one.name, router_one. parts)) print('{0} produced {1} parts'.format(router_two.name, router_two. parts)) print('{0} produced {1} parts'.format(router_three.name, router_three. parts)) print('{0} produced {1} parts'.format(trimmer_one.name, trimmer_one.parts)) print('{0} produced {1} parts'.format(driller_one.name, driller_one.parts)) print('{0} produced {1} boxes'.format(boxer_one.name, boxer_one.boxes)) print('{0} missed {1} of {2} total cycles'.format(thermoformer_one.name, thermoformer_one.failures, thermoformer_one.cycles)) print('{0} parts as WIP still in cell'.format(wip)) print('Effecitve cycle: {0: .1f}s, Average production rate: {1: .1f} parts/hr'.format(G.SIMULATION_TIME / max(1, (driller_one.parts / 2)), driller_one.parts / (G.SIMULATION_TIME / 3600))) return driller_one.parts, thermoformer_one.failures, wip
import simpy # https://simpy.readthedocs.io/en/latest/topical_guides/resources.html def resource_user(name, env, resource, wait, prio): yield env.timeout(wait) with resource.request(priority=prio) as req: print(f'{name} requesting at {env.now} with priority={prio}') yield req print(f'{name} got resource at {env.now}') try: yield env.timeout(3) except simpy.Interrupt as interrupt: by = interrupt.cause.by usage = env.now - interrupt.cause.usage_since print(f'{name} got preempted by {by} at {env.now}' f' after {usage}') env = simpy.Environment() res = simpy.PreemptiveResource(env, capacity=1) p1 = env.process(resource_user(1, env, res, wait=0, prio=0)) p2 = env.process(resource_user(2, env, res, wait=1, prio=0)) p3 = env.process(resource_user(3, env, res, wait=2, prio=-1)) env.run()
'Dude-bro', 'Bill', 'Tina', ] random.shuffle(customer_names) # generate random name for arbitrary number: import names # Setup and start the simulation print('Bartender Simulation') random.seed(RANDOM_SEED) # env = simpy.Environment() env = simpy.rt.RealtimeEnvironment(factor=2) bartender = simpy.PreemptiveResource(env, capacity=1) # create initial customers customers = [ Customer(env, names.get_first_name(), bartender) for i in range(INITIAL_CUSTOMERS) ] env.process(other_tasks(env, bartender)) shots = 0 # Bartender is offered a shot at random intervals def take_shot(env): global shots global POUR_TIME
""" Machine shop Series System Scenario: A workshop has *n* identical machines. Each machine runs continuously and it breaks down periodically. The machines go back to work after repairs are carried out by one repairman. Broken machines enter the queue of the repairman. """ import random import simpy RANDOM_SEED = 42 MTTF = 3000.0 # Mean time to failure in minutes REPAIR_TIME = 300.0 # Time it takes to repair a machine in minutes NUM_MACHINES = 1 # Number of machines in the machine shop WEEKS = 4 # Simulation time in weeks SIM_TIME = WEEKS * 7 * 24 * 60 # Simulation time in minutes def time_to_repair(): """return time interval until the repair is done, and machine is ready to run again. """ return REPAIR_TIME def time_to_failure(): """Return time until next failure for a machine.""" return random.expovariate(1.0/MTTF) class SystemLog(object): def __init__(self, name): self.event_time = [] self.event_sn = [] self.event_type = [] self.down_count = 0 class Machine(object):