-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathprio.py
101 lines (71 loc) · 3.92 KB
/
prio.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
from taskgen import Tasks
from time import sleep
def prio(tasks: Tasks, preemp: bool) -> True:
# task queue
tasks_waiting: list[dict[str:int]] = []
# flags
has_task: bool = True
new_arrived: bool = True
last_task = -1
highest_prio = 0
time = 1
while has_task:
sleep(.1) # delay for debugging
# tasks_waiting becomes a queue of tasks where a task only enters when the time
# reaches its arrival time and only gets out when its timeleft reaches zero
for task in tasks:
if task.get('arrival') <= time and task not in tasks_waiting and task.get('timeleft') != 0:
tasks_waiting.append(task)
# gets the highest priority task index of the waiting tasks if it's preemptive
if preemp:
highest_prio = 0
for task_index in range(len(tasks_waiting)):
if tasks_waiting[task_index].get('prio') > tasks_waiting[highest_prio].get('prio'):
highest_prio = task_index
# if it's not preemptive, sort by task arrival time
# and run the first of the queue
else:
for i in range(len(tasks_waiting)):
for task_num in range(len(tasks_waiting) - i - 1):
if tasks_waiting[task_num].get('arrival') > tasks_waiting[task_num+1].get('arrival'):
temp = tasks_waiting[task_num]
tasks_waiting[task_num] = tasks_waiting[task_num+1]
tasks_waiting[task_num+1] = temp
# switches places of tasks with same arrival time but less priority
for n in range(len(tasks_waiting)):
for i in range(len(tasks_waiting) - n - 1):
if tasks_waiting[i].get('arrival') == tasks_waiting[i+1].get('arrival') and tasks_waiting[i].get('prio') < tasks_waiting[i+1].get('prio'):
temp = tasks_waiting[i]
tasks_waiting[i] = tasks_waiting[i+1]
tasks_waiting[i+1] = temp
# only if there is at least one task in the queue
if len(tasks_waiting) > 0:
if new_arrived or last_task != tasks_waiting[highest_prio].get("num"):
# if the flag of a new task arrival is raised show that the task has arrived,
# downs the flag and registers the time it has waited
print('-------------------------')
print(f'Task {tasks_waiting[highest_prio].get("num")} arrived: ')
tasks_waiting[highest_prio]['waiting'] = time - tasks_waiting[highest_prio]['arrival'] - (tasks_waiting[highest_prio].get('runtime') - tasks_waiting[highest_prio].get('timeleft'))
new_arrived = False
if tasks_waiting[highest_prio].get('timeleft') != 0:
print(f" Time [ {time} ] - Timeleft: {tasks_waiting[highest_prio].get('timeleft')}")
tasks_waiting[highest_prio]['timeleft'] -= 1
last_task = tasks_waiting[highest_prio].get('num')
if tasks_waiting[highest_prio].get('timeleft') == 0:
# if the task's timeleft reaches 0 after the time tick, then erase it (only the pointer)
# from the queue and raises a flag that another task is required
new_arrived = True
del tasks_waiting[highest_prio]
else:
print(f" Time [ {time} ] - no task ")
time += 1
has_task = False
for task in tasks:
if task.get('timeleft') > 0:
has_task = True
# if any task is above 0 timeleft, raises the flag
# that there is a task yet to run, else breaks the loop
tasks.show_waiting_time()
return True
if __name__ == "__main__":
prio(Tasks(), preemp = True)