-
Notifications
You must be signed in to change notification settings - Fork 0
/
fcfs_aging.py
136 lines (105 loc) · 4.18 KB
/
fcfs_aging.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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
# ============================================================================
# Joe Pringle (661114638), CSCI-4210 OpSys, roundrobin_priority_aging.py
# ============================================================================
import process_priority as pr
from completed_plist import CompletedPlist
"""Configurable time slice defaulted to 100ms"""
TIME_SLICE = 100
# Time for context switch, TCS. Instructions said to include this, but
# this should not be modified, since 7ms removing old process and 10ms
# selecting and resuming new process was not specified to be adjustable.
TCS = 17
def ages(running_process, TIME):
"""
Returns True if a process has waited in the ready_q for
1000ms. Called every time TIME is incremented, for correctness.
"""
return (running_process.time_q > 1000 and
running_process.time_q % 1000 == 0)
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].priority < running_process.priority
except:
return False
def fcfs_aging(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
# Due to aging, using a heap to maintain order isn't as
# effective. We'll just sort by priority each iteration.
for p in ready_q:
if(ages(p, TIME)):
p.ages(TIME)
ready_q.sort()
# 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):
ready_q.append(p)
ready_q.sort()
p.arrives(TIME)
# execute the first process in the ready_q, if one exists
try:
if (running_process is None):
running_process = ready_q.pop(0)
if (running_process.popped is None):
running_process.popped = TIME
# indicate a context switch. 10 ms to select and resume
# the new process
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
ready_q.sort()
if preempts(running_process, ready_q):
prev_process = running_process
pr.switches(running_process, ready_q[0], TIME)
ready_q.append(running_process)
ready_q.sort()
running_process = ready_q.pop(0)
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 = fcfs_aging(plist)
print()
plist_completed.statistics()