-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathprocessor.py
More file actions
213 lines (124 loc) · 5.88 KB
/
Copy pathprocessor.py
File metadata and controls
213 lines (124 loc) · 5.88 KB
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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
"""
processor.py - Processor/core class file. Represents a CPU/Processor/Core that executes processes.
The processor is what deecrements the cycles or does the execution of a process.
"""
from process import Process
class Processor:
def __init__(self, processor_ID: str, speed: int = 1, memory_capacity: int = 2048):
"""
Initialize proccessor core/CPU.
@Param processor_ID str - Identifier of core (i.e., P_A or P_B)
@Param speed int - Cycles executed within one time unit, default should be 1 for now.
@Param memeory_capacity int - Maximum memory this processor can handle. Processor should not handle a task that demands more memory than the processor can handle.
"""
self.processor_ID = processor_ID
# current work and availability
self.current_process = None # Initially should be none
self.is_available = True # Initally True
# Specs, needed for parts 2 and 3
self.speed = speed
self.memory_capacity = memory_capacity
self.quantum_used = 0
pass
def assign_process(self, process: Process):
"""
Assigns a process for the core/processor to execute.
@Param process - Process being assigned
@Return boolean - For confirmation. True if success. False otherwise.
"""
# busy
if self.is_available == False:
return False
# Check memeory constraints
if self.can_accept(process) == False:
return False
# Assign process
self.current_process = process
self.is_available = False
# Record start time if this is the first time executing
if process.has_started() == False:
process.start_time = None # seen and checked in execute cycles
return True
pass
def execute_cycles(self, current_time):
"""
Executes one time units worth of work on current process.
Deecrements remaining_cycles by speed. Function should be not responsible for main execution loop.
The simulator holds that responsibility, along with deciding when to check for preemptions.
scheduler is responsible for time quantum usage and preemption decisions.
@param current_time - time used time related calculations
@return Process - If process has finished
@return None - If still running or there is no process
"""
# If there is no process assigned or the process is already complete
if self.current_process == None:
return None
if self.current_process.is_complete():
self.release_current_process()
return None
# Set start time to current time on first execution
if self.current_process.has_started() == False:
self.current_process.start_time = current_time
# Now we can execute one unit time of work
self.current_process.remaining_cycles -= self.speed
self.current_process.service_ticks += 1
self.quantum_used += 1 # increase time quantum used
# check if process completed from time unit of work
if self.current_process.is_complete():
# Record completion time
self.current_process.finished_time = current_time
# Clean up
completed = self.current_process
self.reset()
return completed
# If we are here this mean the process still has work remaing
return None
def is_idle(self) -> bool:
"""
Checks if processor is free/idle.
@return boolean - True if no assigned process. False otherwise.
"""
return self.current_process == None
pass
def can_accept(self, process) -> bool:
"""
Checks if a processor can even accept a process based on memory requirements.
@param process - The process we are checking
@return boolean - True if process memory <= memory_capacity. False otherwise.
"""
if process == None:
return False
return process.memory_bytes <= self.memory_capacity
pass
def reset(self):
"""
Reset process to idle state.
Clears current process and make processor available
"""
self.current_process = None
self.is_available = True
self.quantum_used = 0
pass
def release_current_process(self):
"""
Mainly for round robin.
Releases the current process, needed for preemption.
Returns the process that it can be put back into ready queue.
@return process - The released process
@return None - if there was no process
"""
if self.current_process == None:
return None
released = self.current_process
self.reset()
return released
pass
if __name__ == "__main__":
print("Processor Class file tests:\n")
print("Test 1: Create process and print information")
PA = Processor("P_A", 1, 2048)
print(f"Created processor {PA.processor_ID}. Has a speed of {PA.speed} and a memeory capacity of {PA.memory_capacity}")
print(f"Is this process idle? {PA.is_idle()}, should be true.")
print(f"Is this processor available? {PA.is_available} should also be true \n")
print()
pass