diff options
author | Mac Mollison <mollison@cs.unc.edu> | 2009-01-28 23:41:25 -0500 |
---|---|---|
committer | Mac Mollison <mollison@cs.unc.edu> | 2009-01-28 23:41:25 -0500 |
commit | 90aff3291a0d95b8597bb057433963251ff0ae96 (patch) | |
tree | 41044f624f529150362e82d279af32ab24a6298d |
Initial commit - messy state, probably working.
-rwxr-xr-x | sta.py | 202 |
1 files changed, 202 insertions, 0 deletions
@@ -0,0 +1,202 @@ | |||
1 | #Note to self: I stopped while working on implementing an iterator so I could | ||
2 | # do a filter() operation to get only events of a certain job so I could compare | ||
3 | # to Bjoern's pdf | ||
4 | # Note: Just got StDump iterator working. Remember list() in iterator. | ||
5 | # Note: Just got a generator working :) Awesome, need to pretty up. | ||
6 | # Note: Likely next steps: | ||
7 | # - Define convenience comparisons for ordering by earliest time for sort, | ||
8 | # - and lambdas for filtering by job or PID or CPU or whatever | ||
9 | # - and change read_trace to possibly take multiple traces. | ||
10 | # - and /maybe/ allow for saving /loading previously saved traces. | ||
11 | |||
12 | |||
13 | #!/usr/bin/python3 | ||
14 | |||
15 | # Imports. | ||
16 | import struct | ||
17 | import sys | ||
18 | |||
19 | |||
20 | #################################### | ||
21 | # Types for binary data conversion # | ||
22 | #################################### | ||
23 | |||
24 | st_record_size = 192 | ||
25 | |||
26 | |||
27 | class StHeader: | ||
28 | format = '<bbhi' | ||
29 | formatStr = struct.Struct(format) | ||
30 | keys = ['type','cpu','pid','job'] | ||
31 | message = 'The header.' | ||
32 | |||
33 | |||
34 | class StNameData: | ||
35 | format = '16s' | ||
36 | formatStr = struct.Struct(StHeader.format + format) | ||
37 | keys = StHeader.keys + ['name'] | ||
38 | message = 'The name of the executable of this process.' | ||
39 | |||
40 | # Untested because this never appears in my sample files | ||
41 | # ACTUALLY: None in 0, none in 1, a bunch in 2, and none in 3 | ||
42 | class StParamData: | ||
43 | format = 'III8?' | ||
44 | formatStr = struct.Struct(StHeader.format + format) | ||
45 | keys = StHeader.keys + ['wcet','period','phase','partition'] | ||
46 | message = 'Regular parameters.' | ||
47 | |||
48 | |||
49 | class StReleaseData: | ||
50 | format = 'LL' | ||
51 | formatStr = struct.Struct(StHeader.format + format) | ||
52 | keys = StHeader.keys + ['release_time','deadline'] | ||
53 | message = 'A job was/is going to be released.' | ||
54 | |||
55 | |||
56 | class AssignedData: | ||
57 | format = 'Lh' | ||
58 | formatStr = struct.Struct(StHeader.format + format) | ||
59 | keys = StHeader.keys + ['when','target'] | ||
60 | message = 'A job was assigned to a CPU.' | ||
61 | |||
62 | class StSwitchToData: | ||
63 | format = 'LI' | ||
64 | formatStr = struct.Struct(StHeader.format + format) | ||
65 | keys = StHeader.keys + ['when','exec_time'] | ||
66 | message = 'A process was switched to on a given CPU.' | ||
67 | |||
68 | |||
69 | class StSwitchAwayData: | ||
70 | format = 'LI' | ||
71 | formatStr = struct.Struct(StHeader.format + format) | ||
72 | keys = StHeader.keys + ['when','exec_time'] | ||
73 | |||
74 | class StCompletionData: | ||
75 | format = 'L7x?c' | ||
76 | formatStr = struct.Struct(StHeader.format + format) | ||
77 | keys = StHeader.keys + ['when','forced?','flags'] | ||
78 | message = 'A job completed.' | ||
79 | |||
80 | |||
81 | class StBlockData: | ||
82 | format = 'L' | ||
83 | formatStr = struct.Struct(StHeader.format + format) | ||
84 | keys = StHeader.keys + ['when'] | ||
85 | message = 'A task blocks.' | ||
86 | |||
87 | |||
88 | class StResumeData: | ||
89 | format = 'L' | ||
90 | formatStr = struct.Struct(StHeader.format + format) | ||
91 | keys = StHeader.keys + ['when'] | ||
92 | message = 'A task resumes.' | ||
93 | |||
94 | |||
95 | class StSysReleaseData: | ||
96 | format = 'LL' | ||
97 | formatStr = struct.Struct(StHeader.format + format) | ||
98 | keys = StHeader.keys + ['when','release'] | ||
99 | message = 'StSysReleaseData (no details).' | ||
100 | |||
101 | |||
102 | |||
103 | ################## | ||
104 | # Business logic # | ||
105 | ################## | ||
106 | |||
107 | |||
108 | def get_type(type_num): | ||
109 | """Return the class needed to read a record, given its numerical type""" | ||
110 | type = None | ||
111 | if type_num == 1: | ||
112 | return StNameData | ||
113 | elif type_num == 2: | ||
114 | return StParamData | ||
115 | elif type_num == 3: | ||
116 | return StReleaseData | ||
117 | elif type_num == 4: | ||
118 | return StAssignedData | ||
119 | elif type_num == 5: | ||
120 | return StSwitchToData | ||
121 | elif type_num == 6: | ||
122 | return StSwitchAwayData | ||
123 | elif type_num == 7: | ||
124 | return StCompletionData | ||
125 | elif type_num == 8: | ||
126 | return StBlockData | ||
127 | elif type_num == 9: | ||
128 | return StResumeData | ||
129 | elif type_num == 10: | ||
130 | return StSysReleaseData | ||
131 | return type | ||
132 | |||
133 | |||
134 | def print_record(record): | ||
135 | """Prints a record, given the record as a dict.""" | ||
136 | print(record) | ||
137 | |||
138 | |||
139 | def print_record_verbose(record): | ||
140 | """Prints a record verbosely, given the record as a dict.""" | ||
141 | print(50*'=') | ||
142 | print(get_type(record['type']).message) | ||
143 | for k,v in record.items(): | ||
144 | print(k +":", v) | ||
145 | |||
146 | |||
147 | def trace_iter(*files): | ||
148 | """Returns an iterator for iterating over trace(s) and producing records.""" | ||
149 | for file in files: | ||
150 | f = open(file,'rb') | ||
151 | while True: | ||
152 | try: | ||
153 | data = f.read(st_record_size) | ||
154 | typenum = struct.unpack_from('<b',data)[0] | ||
155 | type = get_type(typenum) | ||
156 | values = struct.unpack_from(StHeader.format + type.format,data) | ||
157 | record = dict(zip(type.keys,values)) | ||
158 | yield record | ||
159 | except struct.error: | ||
160 | f.close() | ||
161 | break | ||
162 | |||
163 | |||
164 | def trace(*files): | ||
165 | obj = "hi" | ||
166 | iter = trace_iter(*files) | ||
167 | def filter(): | ||
168 | print("Hi!") | ||
169 | obj.filter = filter | ||
170 | obj.iter = iter | ||
171 | return obj | ||
172 | |||
173 | |||
174 | ######## | ||
175 | # Main # | ||
176 | ######## | ||
177 | |||
178 | |||
179 | def main(args): | ||
180 | """Main function, called if the program is executed.""" | ||
181 | if args[1] == '-v': | ||
182 | printfunc = print_record_verbose | ||
183 | files = sys.argv[2:] | ||
184 | else: | ||
185 | printfunc = print_record | ||
186 | files = args[1:] | ||
187 | for file in files: | ||
188 | data = open(file,'rb').read() | ||
189 | offset = 0 | ||
190 | try: | ||
191 | while True: | ||
192 | record = get_record(data,offset) | ||
193 | printfunc(record) | ||
194 | offset += st_record_size | ||
195 | #input("Press Enter") | ||
196 | except struct.error: # We've reached the EOF. | ||
197 | continue | ||
198 | |||
199 | |||
200 | # Call main() if the program is executed directly. | ||
201 | if __name__ == "__main__": | ||
202 | main(sys.argv) | ||