-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathscheduler.py
175 lines (137 loc) · 5.84 KB
/
scheduler.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
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
from taskset import TaskSet
NO_MODE = 1
NPP = 2
HLP = 3
class Scheduler(object):
def __init__(self, data):
"""constructor
Args:
data (json): json object of tasks data
"""
self.taskSet = TaskSet(data)
self.queue = []
self.resources = {}
def size(self):
"""return the size of task set
Returns:
int: len of tasks
"""
return len(self.taskSet)
def resourceAvailable(self, key):
"""check if resource is available or not
Args:
key (int): resource key
Returns:
bool: free or not
"""
if key in self.resources:
return self.resources[key] == 0
else:
self.resources[key] = 0
return True
def getHighPriorityJobs(self):
"""get jobs that had resource and still want that
Returns:
list: list of high priority jobs
"""
highPriorityJobs = []
for item in self.queue:
resource = item[0]
job = self.taskSet.getJobById(item[1])
if job.demandResource() == resource:
highPriorityJobs.append(item)
highPriorityJobs.sort(key=lambda x: x[2], reverse=True)
list = [x[1] for x in highPriorityJobs]
return list
def getResource(self, key, value, time):
"""get a resource
Args:
key (int): resource key
value (int): id of that job
"""
self.resources[key] = value
# save the resource get in a queue
self.queue.append((key, value, time))
def freeUnusedResources(self):
"""free unused resources"""
queue = []
for item in self.queue:
resource = item[0]
job = self.taskSet.getJobById(item[1])
time = item[2]
if job.demandResource() != item[0]:
self.resources[resource] = 0
else:
queue.append((resource, job.getId(), time))
self.queue = queue
def run(self, limit, mode):
"""execute scheduler in an amount of time
Args:
limit (int): timeline
Returns:
dict: time and jobs
"""
jobsList = {}
for time in range(limit):
currentJob = None
finalDemand = 0
# get all high priority jobs that use resources
highJobs = self.getHighPriorityJobs()
# free all resources if they are done
self.freeUnusedResources()
jobs = [job for job in self.taskSet.getJobs() if job.isActive(time)] # get all active jobs
jobs.sort(key=lambda x: x.getFP(), reverse=True) # sort jobs by deadline monothonic
if len(jobs) > 0: # schedule when we have jobs
if mode == NO_MODE: # no mode for resource
currentJob = jobs[0]
elif mode == NPP: # Non-Preemptive Protocol
# priority is for jobs that hold a resource
if len(highJobs) > 0:
currentJob = self.taskSet.getJobById(highJobs[0])
else:
# after that use other jobs
for job in jobs:
currentJob = job
# get job demand
jobDemand = currentJob.demandResource()
if jobDemand != 0: # resource wanted
if self.resourceAvailable(jobDemand):
self.getResource(jobDemand, currentJob.getId(), time) # get resource
break
else: # cannot be executed while the resource is in use
continue
else: # no resource wanted
break
elif mode == HLP: # High Lock priority
# priority is for jobs that hold a resource
if len(highJobs) > 0:
currentJob = self.taskSet.getJobById(highJobs[0])
# after that use other jobs
for job in jobs:
if job.getFP() > currentJob.getFP():
currentJobDemand = currentJob.demandResource()
if currentJobDemand != 0 and not job.wantsTheResourceOrNot(currentJobDemand):
currentJob = job
break
else:
# after that use other jobs
for job in jobs:
currentJob = job
# get job demand
jobDemand = currentJob.demandResource()
if jobDemand != 0: # resource wanted
if self.resourceAvailable(jobDemand):
self.getResource(jobDemand, currentJob.getId(), time) # get resource
break
else: # cannot be executed while the resource is in use
continue
else: # no resource wanted
break
if currentJob != None: # do the job
finalDemand = currentJob.demandResource()
currentJob.doJob()
jobsList[time] = {
'job': currentJob,
'resource': finalDemand
}
return jobsList