import Process import Events class SRTF: running = -1 ReadyQ = [] IOWaitTime = 10 preemptTime = -1 def tick(self): if SRTF.running >= 0: pr = Process.PT.pt[SRTF.running] if pr.time == 0: newEv = Events.EventCreate(Events.currentTime,'exit',pr.num,0,0,0) Events.AddEvent(newEv) elif pr.timetoio == 0: newEv = Events.EventCreate(Events.currentTime,'iowait',pr.num,0,0,0) Events.AddEvent(newEv) def HandleEvent(self,ev): if ev.type == 'create': pr = Process.ProcessCreate(ev.p1,ev.p2,ev.p3,ev.p4) pr.statechange(ev.time,'created') if pr.iotime > 0: pr.timetoio = pr.iotime else: pr.timetoio = pr.time + 1 LogEvent(pr,"created") elif ev.type == 'admit': pr = Process.PT.pt[ev.p1] pr.statechange(ev.time,'ready') self.AddReady(ev.p1) LogEvent(pr,"admitted") if SRTF.preemptTime != Events.currentTime and SRTF.running > 0: curpr = Process.PT.pt[SRTF.running] timeToRun = curpr.time if timeToRun > 0 and curpr.timetoio > 0: if pr.time < timeToRun: newEv = Events.EventCreate(Events.currentTime,'interrupt',SRTF.running,0,0,0) Events.AddEvent(newEv) msg = "preemption forced" SRTF.preemptTime = Events.currentTime else: msg = "no preemption" print " check preemption: " + \ "new (%d): %d, current (%d): %d/%d, %s" % \ (pr.num,pr.time,SRTF.running,timeToRun,curpr.timetoio,msg) elif ev.type == 'dispatch': pr = Process.PT.pt[ev.p1] pr.statechange(ev.time,'running') SRTF.running = pr.num LogEvent(pr,"dispatched") elif ev.type == 'interrupt': pr = Process.PT.pt[ev.p1] pr.statechange(ev.time,'ready') if SRTF.running == pr.num: SRTF.running = -1 self.AddReady(pr.num) LogEvent(pr,"interrupted") elif ev.type == 'iowait': pr = Process.PT.pt[ev.p1] pr.statechange(ev.time,'waiting') SRTF.running = -1 waitfor = SRTF.IOWaitTime etime = Events.currentTime + waitfor newEv = Events.EventCreate(etime,'iocomplete',ev.p1,0,0,0) Events.AddEvent(newEv) LogEvent(pr,"io waits",waitfor) elif ev.type == 'iocomplete': pr = Process.PT.pt[ev.p1] pr.statechange(ev.time,'ready') if pr.iotime > 0: pr.timetoio = pr.iotime else: pr.timetoio = pr.time + 1 self.AddReady(ev.p1) LogEvent(pr,"completes io") if SRTF.preemptTime != Events.currentTime and SRTF.running > 0: curpr = Process.PT.pt[SRTF.running] timeToRun = curpr.time if timeToRun > 0 and curpr.timetoio > 0: if pr.time < timeToRun: newEv = Events.EventCreate(Events.currentTime,'interrupt',SRTF.running,0,0,0) Events.AddEvent(newEv) msg = "preemption forced" SRTF.preemptTime = Events.currentTime else: msg = "no preemption" print " check preemption: " + \ "new (%d): %d, current (%d): %d/%d, %s" % \ (pr.num,pr.time,SRTF.running,timeToRun,curpr.timetoio,msg) elif ev.type == 'exit': # terminate pr = Process.PT.pt[ev.p1] pr.statechange(Events.currentTime,'terminated') SRTF.running = -1 LogEvent(pr,"terminates") if SRTF.running < 0: if len(SRTF.ReadyQ) > 0: runP = SRTF.ReadyQ[0] SRTF.running = runP del SRTF.ReadyQ[0] newEv = Events.EventCreate(Events.currentTime,'dispatch',runP,0,0,0) Events.AddEvent(newEv) def AddReady(self,pnum): addp = Process.PT.pt[pnum] for i in range(len(self.ReadyQ)): pn = self.ReadyQ[i] process = Process.PT.pt[pn] if (addp.time < process.time): self.ReadyQ.insert(i,pnum) break else: self.ReadyQ.append(pnum) print " added process %d to ready queue with time %d, ReadyQ=%s" \ % (pnum,addp.time,self.ReadyQ) def LogEvent(pr,evname,waitfor=0): if waitfor>0: msg = ", io wait for %d" % waitfor else: msg = "" print "time:%3d => process %d %s, run time %d, time to io %d%s" % \ (Events.currentTime,pr.num,evname,pr.time,pr.timetoio,msg)