Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- """
- CPU Scheduling
- CSCI 4210 OPSYS
- Summer 2019
- """
- import sys
- from classes.config import Config
- from classes.process import Process
- from classes.state import State
- from classes.random_class import Rand48
- from copy import deepcopy
- import math
- def initialize_processes():
- rand48_obj = Rand48(Config.instance._seed)
- rand48_obj.srand(Config.instance._seed)
- processes = list()
- alpha = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
- n_processes = Config.instance._nProcesses
- for i in range(n_processes):
- process = Process(alpha[i], rand48_obj)
- processes.append(process)
- return processes
- def accept_new_process(alg, time, time_str, state, process, output):
- state.place_ready(process)
- if state.running == '':
- process.context_switch = Config.instance._contextSwitchDuration//2 - 1
- output += time_str
- if time == 9:
- x = 0
- if alg == "SRT" or alg == "SJF":
- state.ready.sort(key=lambda x: (x.tau[min(x.burst_index, len(x.tau)- 1)] - x.burst_elapsed, x._id))
- runningProcess = state.get_process(state.running)
- if alg == "SRT" and runningProcess != None and max(process.tau[process.burst_index] - process.burst_elapsed, -2) <= \
- max(runningProcess.tau[runningProcess.burst_index - 1] - runningProcess.burst_elapsed, -2):
- output += "(tau " + str(process.tau[process.burst_index]) + "ms) arrived; preempting {:s} {:s}\n" \
- .format(str(runningProcess), state.getReadyQ())
- #output += time_str + "now preempting\n"
- state.preemption(process, False)
- state.ready[0].context_switch = Config.instance._contextSwitchDuration - 1
- runningProcess.context_switch = Config.instance._contextSwitchDuration // 2 - 1
- runningProcess.time_remaining = runningProcess.burst_time
- runningProcess.resetBurstCounters(rsElapsed=False)
- if runningProcess.burst_elapsed == -1:
- runningProcess.burst_elapsed = 0
- elif alg == "SRT" or alg == "SJF":
- output += "(tau " + str(process.tau[process.burst_index]) + "ms) arrived; added to ready queue {:s}\n" \
- .format(state.getReadyQ())
- else:
- output += "arrived; added to ready queue {:s}\n".format(state.getReadyQ())
- # TODO add contextswitch
- return output
- def handle_context_switch(alg, time, time_str, state, process, output):
- if process.context_switch == 0:
- process.resetContextSwitch()
- if process.status == "ready":
- state.switches += 1
- process.CPU_time += 1
- #output += time_str + "In ready within handle_context_switch for {:s}\n".format(str(process))
- process.burst_time = process.bursts[min(process.burst_index, len(process.tau)- 1)].actual_burst_time
- if process.burst_elapsed == -1:
- if alg == "SRT":
- process.burst_index += 1
- if process.burst_index == process.n_bursts:
- return (output, False)
- if alg != "SRT":
- process.burst_index += 1
- if (alg == "RR" or alg == "SRT") and process.time_remaining != -1:
- process.burst_time = process.time_remaining
- process.time_remaining = -1
- #process.burst_index -= 1
- if (alg == "SRT" or alg == "SJF") and process.burst_index < len(process.tau):
- state.ready.sort(key=lambda x: (x.tau[min(x.burst_index, len(x.tau)- 1)] - x.burst_elapsed, x._id))
- process.start_burst = time # a marker indicating the current time (to determine total allocated time for burst)
- #output += time_str + "now preempting\n"
- #print(str(time) + " " + str(state.getReadyQ()) + str(process))
- state.preemption(process, True)
- output += time_str
- if (alg == "SRT" or alg == "SJF") and process.burst_index <= process.n_bursts:
- output += "(tau " + str(process.tau[process.burst_index - 1]) + "ms) "
- output += "started using the CPU "
- if (alg == "SRT") and process.burst_index <= process.n_bursts:
- output += "with {:d}ms burst remaining {:s}\n".format(process.burst_time, state.getReadyQ())
- else:
- output += "for {:d}ms burst {:s}\n".format(process.burst_time, state.getReadyQ())
- if len(state.ready) > 0:
- first_proc = state.ready[0]
- first_proc_index = first_proc.burst_index if first_proc.burst_elapsed == -1 else first_proc.burst_index - 1
- #first_proc_index = first_proc.burst_index
- #print("{:s}: {:d}".format(str(first_proc), max(first_proc.tau[first_proc_index] - first_proc.burst_elapsed, -2)))
- #print("{:s}: {:d}\n".format(str(process), max(process.tau[process.burst_index] - process.burst_elapsed, -2)))
- if alg == "SRT" and max(first_proc.tau[first_proc_index] - first_proc.burst_elapsed, -2) <= \
- max(process.tau[process.burst_index] - process.burst_elapsed, -2) and \
- first_proc.burst_index < first_proc.n_bursts:
- output += "time {:d}ms: Process {:s} (tau {:d}ms) will preempt {:s} {:s}\n"\
- .format(time, str(first_proc), first_proc.tau[first_proc_index], str(process), state.getReadyQ())
- output += "{:s}: tau: {:d} elapsed: {:d} actual: {:d}\n{:s}: tau: {:d} elapsed: {:d} actual: {:d}\n".format(str(first_proc), first_proc.tau[first_proc_index ], first_proc.burst_elapsed, \
- first_proc.bursts[first_proc_index ].actual_burst_time, str(process), process.tau[process.burst_index], process.burst_elapsed, process.bursts[process.burst_index].actual_burst_time)
- first_proc.context_switch = Config.instance._contextSwitchDuration - 1
- process.context_switch = Config.instance._contextSwitchDuration//2 - 1
- process.time_remaining = process.burst_time
- process.resetBurstCounters(rsElapsed=False)
- if process.burst_elapsed == -1:
- process.burst_elapsed = 0
- elif process.status == "running":
- if (alg == "RR" or alg == "SRT") and process.time_remaining != -1:
- state.preemption(None, False)
- else:
- state.place_blocked(state.get_process(state.running))
- elif process.context_switch > 0:
- process.context_switch -= 1
- return (None, True)
- return (output, False)
- def print_list(l):
- output = "["
- for i in range(len(l)):
- output += str(l[i]) + ", "
- output += "]"
- return output
- def do_burst(alg, time, time_str, time_slice, state, process, output, terminated_processes):
- process.CPU_time += 1
- if time == 42:
- x = 12
- if process.burst_time == 0 or (time - process.start_burst) == time_slice:
- if alg == "RR":
- if time - process.start_burst == time_slice and len(state.ready) == 0:
- output += "time {:d}ms: Time slice expired; no preemption because ready queue is empty {:s}\n"\
- .format(time, state.getReadyQ())
- process.burst_time -= 1
- return (output, True)
- elif time - process.start_burst == time_slice and process.burst_time != 0:
- time_remaining = process.bursts[process.burst_index - 1].actual_burst_time - time_slice
- output += time_str + "Time slice expired; process {:s} preempted with {:d}ms to go {:s}\n"\
- .format(str(process), time_remaining, state.getReadyQ())
- process.time_remaining = time_remaining
- process.context_switch = Config.instance._contextSwitchDuration//2 - 1
- if state.ready[0] in state.processes_run:
- state.ready[0].context_switch = Config.instance._contextSwitchDuration - 1
- else:
- state.ready[0].context_switch = Config.instance._contextSwitchDuration - 1
- process.resetBurstCounters(rsElapsed=True)
- process.burst_index -= 1
- return (output, True)
- remaining_bursts = len(process.bursts) - process.burst_index
- if process.burst_index == len(process.bursts):
- terminated_processes.append(process)
- output += time_str + "terminated {:s}\n".format(state.getReadyQ())
- state.running = ''
- if len(state.ready) > 0:
- state.ready[0].context_switch = Config.instance._contextSwitchDuration-1
- '''state.turnaround += float(process.CPU_time/process.n_bursts)
- state.wait_time += float((process.CPU_time-process.totalBurstTime())/process.n_bursts)'''
- return (output, True)
- process.start_io = time
- process.io_time = process.bursts[process.burst_index - 1].io_burst_time
- process.resetBurstCounters(rsElapsed=True)
- if len(state.ready) > 0:
- #output += "processes_run == " + print_list(state.processes_run) + "\n"
- state.ready[0].context_switch = Config.instance._contextSwitchDuration - 1
- process.context_switch = Config.instance._contextSwitchDuration // 2
- #output += ("set the context switch of {:s} to {:d}\n".format(str(state.ready[0]), state.ready[0].context_switch))
- else:
- process.context_switch = Config.instance._contextSwitchDuration//2
- burstWord = "bursts" if remaining_bursts > 1 else "burst"
- output += time_str
- if alg == "SRT" or alg == "SJF":
- output += "(tau " + str(process.tau[process.burst_index - 1]) + "ms) "
- output += "completed a CPU burst; {:d} {:s} to go {:s}\n"\
- .format(remaining_bursts, burstWord, state.getReadyQ())
- if alg == "SRT" or alg == "SJF":
- output += "time {:d}ms: Recalculated tau = {:d}ms for process {:s} {:s}\n" \
- .format(time, process.tau[process.burst_index], str(process), state.getReadyQ())
- output += time_str + "switching out of CPU; will block on I/O until time {:d}ms {:s}\n"\
- .format(process.io_time + time + process.context_switch, state.getReadyQ())
- runningProcess = state.get_process(state.running)
- # if runningProcess:
- # state.place_blocked(state.get_process(state.running))
- process.time_remaining = -1
- elif alg == "RR":
- if process.burst_time > 0 and (time - process.start_burst) != time_slice:
- process.burst_time -= 1
- return (None, True)
- elif process.burst_time > 0:
- process.burst_time -= 1
- process.burst_elapsed += 1
- return (None, True)
- return (output, False)
- def do_IO_burst(alg, time, time_str, state, process, output):
- if process.io_time == 0:
- state.place_ready(process)
- process.resetIOCounters()
- if time == 92:
- print("here")
- runningProcess = state.get_process(state.running)
- if runningProcess:
- output += "{:d}\n".format(max(process.tau[process.burst_index] - process.burst_elapsed, -2));
- output += "{:d}\n".format(max(runningProcess.tau[runningProcess.burst_index-1] - runningProcess.burst_elapsed, -2));
- if time == 1159:
- x = 2
- if alg == "SRT" and runningProcess != None and max(process.tau[process.burst_index] - process.burst_elapsed, -2) <= \
- max(runningProcess.tau[runningProcess.burst_index-1] - runningProcess.burst_elapsed, -2):
- output += time_str + "(tau " + str(process.tau[process.burst_index]) + "ms) completed I/O; preempting {:s} {:s}\n" \
- .format(str(runningProcess), state.getReadyQ())
- output += "{:s}: tau: {:d} elapsed: {:d} actual: {:d}\n{:s}: tau: {:d} elapsed: {:d} actual: {:d}\n".format(str(process), process.tau[process.burst_index], process.burst_elapsed, \
- process.bursts[process.burst_index].actual_burst_time, str(runningProcess), runningProcess.tau[runningProcess.burst_index-1], runningProcess.burst_elapsed, runningProcess.bursts[runningProcess.burst_index-1].actual_burst_time)
- state.ready[0].context_switch = Config.instance._contextSwitchDuration - 1
- runningProcess.context_switch = Config.instance._contextSwitchDuration//2 - 1
- runningProcess.time_remaining = runningProcess.burst_time + 1
- runningProcess.resetBurstCounters(rsElapsed=False)
- if runningProcess.burst_elapsed == -1:
- runningProcess.burst_elapsed = 0
- else:
- if alg == "SRT" or alg == "SJF":
- output += time_str + "(tau " + str(process.tau[process.burst_index]) + "ms) completed I/O; added to ready queue {:s}\n" \
- .format(state.getReadyQ())
- if (runningProcess != None):
- x = 0
- #output += "{:s}: tau: {:d} elapsed: {:d} actual: {:d}\n{:s}: tau: {:d} elapsed: {:d} actual: {:d}\n".format(str(process), process.tau[process.burst_index], process.burst_elapsed, \
- #process.bursts[process.burst_index].actual_burst_time, str(runningProcess), runningProcess.tau[runningProcess.burst_index - 1], runningProcess.burst_elapsed, runningProcess.bursts[runningProcess.burst_index-1].actual_burst_time)
- else:
- output += time_str + "completed I/O; added to ready queue {:s}\n".format(state.getReadyQ())
- if state.running == '' and state.ready[0] == process:
- state.ready[0].context_switch = Config.instance._contextSwitchDuration//2 - 1
- else:
- process.io_time -= 1
- return (output, True)
- def run_algorithm(alg, state, time, time_slice):
- terminated_processes = list()
- output = ""
- state.processes.sort()
- sorted_processes = state.processes
- #print(sorted_processes)
- for process in sorted_processes:
- if(process.status == "ready"):
- process.CPU_time += 1
- for process in sorted_processes:
- state.processes_run.append(process)
- time_str = "time {:d}ms: Process {:s} ".format(time, str(process))
- # Preemption for RR
- if process.context_switch != -1:
- returnTuple = handle_context_switch(alg, time, time_str, state, process, output)
- # If there's anything to append to output, do so
- if returnTuple[0] != None:
- output += returnTuple[0]
- # If context switch ongoing, then continue
- if returnTuple[1]:
- continue
- state.processes_run.clear()
- for process in sorted_processes:
- state.processes_run.append(process)
- if process.context_switch <= 0:
- time_str = "time {:d}ms: Process {:s} ".format(time, str(process))
- # Do a CPU Burst/Set up IO Burst
- if process.burst_time != -1:
- if(time > 678 and time < 685):
- print("burst", process.burst_time)
- returnTuple = do_burst(alg, time, time_str, time_slice, state, process, output, terminated_processes)
- if returnTuple[0] != None:
- output += returnTuple[0]
- if returnTuple[1]:
- continue
- state.processes_run.clear()
- for process in sorted_processes:
- state.processes_run.append(process)
- if process.context_switch <= 0:
- time_str = "time {:d}ms: Process {:s} ".format(time, str(process))
- # Do an IO Burst
- if process.io_time != -1:
- output = do_IO_burst(alg, time, time_str, state, process, output)[0]
- continue
- state.processes_run.clear()
- for process in sorted_processes:
- state.processes_run.append(process)
- time_str = "time {:d}ms: Process {:s} ".format(time, str(process))
- # Process arrival
- if process.arrival_time == time:
- output += accept_new_process(alg, time, time_str, state, process, output)
- state.processes_run.clear()
- for process in terminated_processes:
- state.remove_process(process)
- return output
- def RR(state, time, time_slice):
- return run_algorithm("RR", state, time, time_slice)
- def FCFS(state, time):
- return run_algorithm("FCFS", state, time, 1000000)
- def SJF(state, time):
- return run_algorithm("SJF", state, time, -999999)
- def SRT(state, time):
- return run_algorithm("SRT", state, time, -999999)
- def wrapperAlgo(processes, header, tHeader):
- FCFS_state = State(deepcopy(processes))
- SJF_state = State(deepcopy(processes))
- SRT_state = State(deepcopy(processes))
- RR_state = State(deepcopy(processes))
- time = 0
- FCFS_output = header + "time {:d}ms: Simulator started for FCFS {:s}\n".format(time,FCFS_state.getReadyQ())
- SJF_output = tHeader + "time {:d}ms: Simulator started for SJF {:s}\n".format(time,SJF_state.getReadyQ())
- SRT_output = tHeader + "time {:d}ms: Simulator started for SRT {:s}\n".format(time,SRT_state.getReadyQ())
- RR_output = header + "time {:d}ms: Simulator started for RR {:s}\n".format(time,RR_state.getReadyQ())
- #while len(FCFS_state) > 0 and len(SJF_state) > 0 and len(SRT_state) > 0 and len(RR_state) > 0:
- while len(FCFS_state) > 0 and len(RR_state) > 0 and time != 50000:
- if time == 7425:
- x = "yes"
- FCFS_output += FCFS(FCFS_state, time)
- #SJF_output += SJF(SJF_state, time)
- #SRT_output += SRT(SRT_state, time)
- #RR_output += RR(RR_state, time, Config.instance._timeSliceRR)
- time += 1
- time+=1
- RR_output += "time {:d}ms: Simulator ended for RR {:s}\n".format(time,RR_state.getReadyQ())
- FCFS_output += "time {:d}ms: Simulator ended for FCFS {:s}\n".format(time,FCFS_state.getReadyQ())
- SRT_output += "time {:d}ms: Simulator ended for SRT {:s}\n".format(time,SRT_state.getReadyQ())
- SJF_output += "time {:d}ms: Simulator ended for SJF {:s}\n".format(time,SJF_state.getReadyQ())
- print(FCFS_output)
- print(SJF_output)
- print(SRT_output)
- print(RR_output)
- if __name__ == "__main__":
- # Instantiate a singleton Config with unpacked sys.argv, and
- # prevent python/python3 from being considered an argument
- if sys.argv[0] in ["python", "python3"]:
- Config(*sys.argv[2:])
- else:
- Config(*sys.argv[1:])
- # Debug print config
- # print(Config.instance)
- processes = initialize_processes()
- header = ""
- tHeader = ""
- for p in processes:
- header += "Process {:s} [NEW] (arrival time {:d} ms) {:d} CPU bursts\n".format(str(p),p.arrival_time,p.n_bursts)
- tHeader += "Process {:s} [NEW] (arrival time {:d} ms) {:d} CPU bursts (tau {:.0f}ms)\n".format(str(p),p.arrival_time,p.n_bursts,1/Config.instance._lambdaValue)
- wrapperAlgo(processes, header, tHeader)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement