-
Notifications
You must be signed in to change notification settings - Fork 0
/
sjf_preemption.py
111 lines (86 loc) · 3.44 KB
/
sjf_preemption.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# ============================================================================
# Joe Pringle (661114638), CSCI-4210 OpSys, sjf_preemption.py
# ============================================================================
import process as pr
from completed_plist import CompletedPlist
import heapq
# ============================================================================
def preempts(running_process, ready_q):
"""
Peek at the top of the ready_q. If a process in the ready_q
has less time remaining than the current process, return
TRUE. Else, return FALSE.
"""
try:
return ready_q[0] < running_process
except:
return False
def sjf_preemption(plist):
"""
Shortest Job First (sjf). As processes arrive, execute them in
increasing order of burst time.
"""
TIME, completed, num_processes = -1, 0, len(plist)
ready_q = []
running_process, prev_process = None, None
TIMECS_REMAINING = 0
p_completed = CompletedPlist()
while (completed < num_processes):
TIME += 1
# handle total wait time for each process
for p in ready_q:
p.time_q += 1
# populate ready_q
for p in plist:
if (p.arrived == TIME):
heapq.heappush(ready_q, p)
p.arrives(TIME)
# execute the first process in the ready_q, if one exists
try:
if (running_process is None):
running_process = heapq.heappop(ready_q)
if(running_process.popped is None):
running_process.popped = TIME
# indicate a context switch. 10 ms to select and resume
# the new process
# fix this
pr.switches(prev_process, running_process, TIME)
TIMECS_REMAINING += 10
# if ready_q empty, can't execute any processes
except IndexError:
if (TIMECS_REMAINING == 0):
prev_process = None
continue
# if a context switch is occurring, wait until it finishes
if (TIMECS_REMAINING > 0):
TIMECS_REMAINING -= 1
continue
# If a preemption occurs, print a message indicating a context switch.
# Then, switch the current process with the one on top of the heap
if preempts(running_process, ready_q):
prev_process = running_process
pr.switches(running_process, ready_q[0], TIME)
heapq.heappush(ready_q, running_process)
running_process = heapq.heappop(ready_q)
if (running_process.popped is None):
running_process.popped = TIME
if (running_process.is_complete()):
running_process.completes(TIME)
p_completed.push(running_process)
completed += 1
# we will not check for a context switch until the
# next iteration, decrement time. this way, a context switch will
# begin immediately as a process completes
TIME -= 1
# 7 ms in context switch to clear old process
prev_process = running_process
TIMECS_REMAINING += 7
running_process = None
else:
running_process.time -= 1
return p_completed
if __name__ == "__main__":
plist = pr.create_plist() # takes optional argument for num processes
plist_completed = sjf_preemption(plist)
print()
plist_completed.statistics()