-
Notifications
You must be signed in to change notification settings - Fork 14
/
Copy pathst-draw
executable file
·154 lines (121 loc) · 5.19 KB
/
st-draw
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/env python
import argparse
import sys
import os.path
import cairo
from sched_trace import event_name, event_time, SchedTrace
import sched_trace.draw
def s2ns(secs):
return secs * 1E9
def ms2ns(millis):
return millis * 1E6
def ns2s(nanos):
return nanos / 1E9
def parse_args():
parser = argparse.ArgumentParser(
description="Render a LITMUS^RT schedule trace as a PDF.")
parser.add_argument('-o', '--output',
help='name of the generated PDF file')
parser.add_argument('-x', '--xscale', type=float, default=36,
help="how many points (1/72'') per millisecond?")
parser.add_argument('-y', '--yscale', type=float, default=72,
help="how many points (1/72'') per task/core?")
parser.add_argument('--margin', type=float, default=36,
help="how many points (1/72'') of margin around the schedule?")
parser.add_argument('--major-ticks', type=float, default=10,
help="how many milliseconds per major tick? (zero means off)")
parser.add_argument('--minor-ticks', type=float, default=1,
help="how many milliseconds per minor tick? (zero means off)")
parser.add_argument('-j', '--show-job-ids', action='store_true',
help="show job IDs next to releases and completions")
parser.add_argument('-f', '--from', type=float, dest='start',
help='draw schedule starting at time TIME', metavar='TIME')
parser.add_argument('-u', '--until', type=float, dest='end',
help='draw schedule up to time TIME', metavar='TIME')
parser.add_argument('-l', '--length', type=float, default=1000,
help='draw schedule for LENGTH time units')
parser.add_argument('-r', '--relative', action='store_true',
help='interpret -f/-u options relative to system release')
parser.add_argument('-q', '--start-on-multiple', metavar='QUANTUM',
type=float, default=None, dest='quantum',
help='let the schedule start on an integer multiple of QUANTUM')
parser.add_argument('-v', '--verbose', action='store_true', default=False,
help='output some information while drawing')
parser.add_argument('file', nargs='*',
help='the binary trace files collected with st-trace')
return parser.parse_args()
def default_output_name(input_files):
if not input_files:
return 'schedule.pdf'
candidate = input_files[0]
for i in xrange(len(candidate)):
if not all([f[i] == candidate[i] for f in input_files]):
break
candidate = os.path.basename(candidate[:i])
if candidate.endswith('_cpu='):
candidate = candidate.replace('_cpu=', '')
if not candidate:
return 'schedule.pdf'
return candidate + '.pdf'
def main(args=sys.argv[1:]):
opts = parse_args()
if not opts.output:
opts.output = default_output_name(opts.file)
try:
opts.file = [f for f in opts.file if os.stat(f).st_size > 0]
trace = SchedTrace(opts.file)
except IOError, msg:
print 'Could not load trace files (%s)' % msg
sys.exit(1)
if opts.start:
# convert from ms
opts.start = ms2ns(opts.start)
# check if a relative time is given
if opts.relative:
if trace.system_releases:
opts.start += trace.system_releases[0]
else:
opts.start += trace.earliest_event_time
if opts.end:
# convert from ms
opts.end = ms2ns(opts.end)
# check if a relative time is given
if opts.relative:
if trace.system_releases:
opts.end += trace.system_releases[0]
else:
opts.end += trace.earliest_event_time
if not opts.start:
if opts.end and opts.length:
opts.start = opts.end - ms2ns(opts.length)
elif trace.system_releases:
opts.start = trace.system_releases[0]
else:
opts.start = trace.earliest_event_time
if opts.quantum:
q = ms2ns(opts.quantum)
opts.start = (int(opts.start) // int(q)) * q
if not opts.end:
if opts.start and opts.length:
opts.end = opts.start + ms2ns(opts.length)
else:
opts.end = trace.latest_event_time
if opts.verbose:
print '[II] Rendering into file: %s' % opts.output
print '[II] Drawing %.2f seconds from time %.4fs until time %.4fs.' % \
(ns2s(opts.end - opts.start), ns2s(opts.start), ns2s(opts.end))
if len(trace.system_releases) == 1:
print '[II] The trace contains a system release at time %.4fs.' % \
(ns2s(trace.system_releases[0]))
elif len(trace.system_releases) > 1:
print '[!!] The trace contains multiple system releases: %s' % \
(' '.join(['%.4fs' % ns2s(x) for x in trace.system_releases]))
else:
print '[II] The trace does not contain a system release.'
sched_trace.draw.render(opts, trace)
# for pid in trace.task_names:
# print pid, '->', trace.task_names[pid], trace.task_wcets[pid], trace.task_periods[pid]
# for (to, away) in trace.scheduling_intervals_in_range(trace.system_releases[0], trace.system_releases[0] + 1E9):
# print to, away
if __name__ == '__main__':
main()