-
Notifications
You must be signed in to change notification settings - Fork 1
/
SimpleSMTScheduler.py
154 lines (141 loc) · 6.92 KB
/
SimpleSMTScheduler.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
#!/usr/bin/python
import getopt
import sys
import os
from statistics import stdev
from simplesmtscheduler.schedulers import *
from simplesmtscheduler.utilities import *
taskSet = []
tasksFileName = ""
plotFileName = ""
schedulePlotPeriods = 1
plot = True
verbose = True
interactive = False
optimize = False
split = False
if __name__ == "__main__":
print("Welcome to this simple SMT scheduler (SSMTS)...\n")
if len(sys.argv) > 1:
try:
opts, args = getopt.getopt(sys.argv[1:], "hi:w:p:n:ovcs",
["help", "itasks=", "wcet=", "plot=", "nperiods=", "optimize", "verbose",
"code", "split"])
except getopt.GetoptError:
print('Try : SimpleSMTScheduler.py -i <inputtasks> -w 35713 -p <outputplot> -n <plotperiods> -v -c')
print("Or : SimpleSMTScheduler.py --help")
sys.exit(2)
plot = False
verbose = False
code = False
schedulePlotPeriods = 1
wcet_offset = 0
jitter = 0
for opt, arg in opts:
if opt in ("-h", "--help"):
print('SimpleSMTScheduler.py -i <inputtasks> -w 35713 -p <outputplot> -n <plotperiods> -o -v -c -s')
print("-h\t--help")
print("-i\t--itasks")
print("-w\t--wcet")
print("-p\t--plot")
print("-n\t--nperiods")
print("-o\t--optimize")
print("-v\t--verbose")
print("-c\t--code")
print("-s\t--split")
sys.exit()
elif opt in ("-i", "--itasks"):
tasksFileName = arg
elif opt in ("-w", "--wcet"):
wcet_offset = float(arg)
elif opt in ("-p", "--plot"):
plotFileName = arg
plot = True
elif opt in ("-n", "--nperiods"):
schedulePlotPeriods = int(arg)
elif opt in ("-o", "--optimize"):
optimize = True
elif opt in ("-v", "--verbose"):
verbose = True
elif opt in ("-c", "--code"):
code = True
elif opt in ("-s", "--split"):
split = True
else:
code = False
interactive = True
split = False
wcet_offset = 0
jitter = 0
if interactive:
tasksFileName = input("Enter the csv file for the tasks to be scheduled: ")
wcet_offset = int(input("Enter the WCET allocation gap between activations: "))
schedulePlotPeriods = int(input("Enter the number of hyper periods to be plotted: "))
code = input("Enable code output (Yes/No)? ").lower() == "Yes".lower()
optimize = input("Enable optimization (Yes/No)? ").lower() == "Yes".lower()
verbose = input("Enable verbose mode (Yes/No)? ").lower() == "Yes".lower()
print("Importing task set from file source...\n")
parse_csv_taskset(tasksFileName, taskSet)
baseFileName = os.path.basename(tasksFileName)
if [t for t in taskSet if t.execution > t.deadline]:
sys.exit("\nTask set is not valid.\nExecution time violate period and deadline constraints for tasks: " + str(
[t.name for t in taskSet if t.execution > t.deadline]))
elif [t for t in taskSet if t.deadline > t.period]:
sys.exit("\nTask set is not valid.\nDeadline times violate period constraints")
elif [t for t in taskSet if t.offset > t.period]:
sys.exit("\nTask set is not valid.\nOffset times violate period constraints")
else:
nr_cores = [t.coreid for t in taskSet]
for core_id in range(min(nr_cores), max(nr_cores) + 1):
core_tasks = [t for t in taskSet if t.coreid == core_id]
hyper_period = find_lcm([t.period for t in core_tasks])
utilization = sum(t.execution / t.period for t in core_tasks) * 100
print(f"\nScheduling CPU ID {str(core_id)} started...")
print("\t- Utilization = %s %%" % str(utilization))
print("\t- Schedule hyper period = %s" % str(hyper_period))
print("\t- Using optimization is", str(optimize))
print("\t- Allocated WCET RTS =", str(wcet_offset))
schedule, utilization, hyperPeriod, elapsedTime = gen_cyclic_schedule_model(core_tasks, wcet_offset,
optimize,
verbose)
print("\n\t- Solver completed in %s ms" % (elapsedTime * SEC_TO_MS))
if schedule is not None:
gen_schedule_activations(schedule, core_tasks)
print("\n\t- Activation Instances:")
for i in range(len(core_tasks)):
print("\t\tschedtime_t %s_sched_insts[%s] = %s;" % (
core_tasks[i].name, len(core_tasks[i].getStartPIT()),
str(core_tasks[i].getStartPIT()).replace("[", "{").replace(
"]", "}")))
print("\n\t- Estimated release jitter per task:")
tasks_jitter = calc_jitter_pertask(core_tasks)
for t in core_tasks:
print(f"\t\t{t.name}", end='')
if len(tasks_jitter[t.name]) > 1:
print(f"(std.dev = {round(stdev(tasks_jitter[t.name]), 2)}, "
f"max = {max(tasks_jitter[t.name])}, min = {min(tasks_jitter[t.name])}):", end='')
print("\n\t\t\t" + str(tasks_jitter[t.name]))
else:
print(f"\tA schedule for CPU ID {core_id} could not be generated")
if interactive:
schedulePlot = plot_cyclic_schedule(taskSet, hyperPeriod,
schedulePlotPeriods, os.path.splitext(baseFileName)[0])
schedulePlot.show()
elif plot:
if split:
numberOfCores = max(t.coreid for t in taskSet) + 1
for i in range(numberOfCores):
coreIdTasks = ([t for t in taskSet if t.coreid == i])
coreHyperperiod = find_lcm([o.period for o in coreIdTasks])
plot_cyclic_schedule(coreIdTasks, coreHyperperiod,
schedulePlotPeriods, os.path.splitext(baseFileName)[0]).savefig(
plotFileName.replace(".png", "_" + str(i) + ".png"), dpi=MY_DPI)
else:
schedulePlot = plot_cyclic_schedule(taskSet, hyperPeriod,
schedulePlotPeriods, os.path.splitext(baseFileName)[0])
schedulePlot.savefig(plotFileName, dpi=MY_DPI)
if code:
gen_schedule_code(tasksFileName.replace(".csv", "_schedule.h"), tasksFileName, taskSet,
hyperPeriod,
utilization, True)
sys.exit()