summaryrefslogtreecommitdiffstats
path: root/naive_trace_reader.py
diff options
context:
space:
mode:
Diffstat (limited to 'naive_trace_reader.py')
-rw-r--r--naive_trace_reader.py165
1 files changed, 165 insertions, 0 deletions
diff --git a/naive_trace_reader.py b/naive_trace_reader.py
new file mode 100644
index 0000000..0f117b8
--- /dev/null
+++ b/naive_trace_reader.py
@@ -0,0 +1,165 @@
1###############################################################################
2# Description
3###############################################################################
4
5# trace_reader(files) returns an iterator which produces records
6# OUT OF ORDER from the files given. (the param is a list of files.)
7#
8# The non-naive trace_reader has a lot of complex logic which attempts to
9# produce records in order (even though they are being pulled from multiple
10# files which themselves are only approximately ordered). This trace_reader
11# attempts to be as simple as possible and is used in the unit tests to
12# make sure the total number of records read by the normal trace_reader is
13# the same as the number of records read by this one.
14
15###############################################################################
16# Imports
17###############################################################################
18
19import struct
20
21
22###############################################################################
23# Public functions
24###############################################################################
25
26# Generator function returning an iterable over records in a trace file.
27def trace_reader(files):
28 for file in files:
29 f = open(file,'rb')
30 while True:
31 data = f.read(RECORD_HEAD_SIZE)
32 try:
33 type_num = struct.unpack_from('b',data)[0]
34 except struct.error:
35 break #We read to the end of the file
36 type = _get_type(type_num)
37 try:
38 values = struct.unpack_from(StHeader.format +
39 type.format,data)
40 record_dict = dict(zip(type.keys,values))
41 except struct.error:
42 f.close()
43 print "Invalid record detected, stopping."
44 exit()
45
46 # Convert the record_dict into an object
47 record = _dict2obj(record_dict)
48
49 # Give it a type name (easier to work with than type number)
50 record.type_name = _get_type_name(type_num)
51
52 # All records should have a 'record type' field.
53 # e.g. these are 'event's as opposed to 'error's
54 record.record_type = "event"
55
56 # If there is no timestamp, set the time to 0
57 if 'when' not in record.__dict__.keys():
58 record.when = 0
59
60 yield record
61
62###############################################################################
63# Private functions
64###############################################################################
65
66# Convert a dict into an object
67def _dict2obj(d):
68 class Obj: pass
69 o = Obj()
70 for key in d.keys():
71 o.__dict__[key] = d[key]
72 return o
73
74###############################################################################
75# Trace record data types and accessor functions
76###############################################################################
77
78# Each class below represents a type of event record. The format attribute
79# specifies how to decode the binary record and the keys attribute
80# specifies how to name the pieces of information decoded. Note that all
81# event records have a common initial 24 bytes, represented by the StHeader
82# class.
83
84RECORD_HEAD_SIZE = 24
85
86class StHeader(object):
87 format = '<bbhi'
88 formatStr = struct.Struct(format)
89 keys = ['type','cpu','pid','job']
90 message = 'The header.'
91
92class StNameData(object):
93 format = '16s'
94 formatStr = struct.Struct(StHeader.format + format)
95 keys = StHeader.keys + ['name']
96 message = 'The name of the executable of this process.'
97
98class StParamData(object):
99 format = 'IIIc'
100 formatStr = struct.Struct(StHeader.format + format)
101 keys = StHeader.keys + ['wcet','period','phase','partition']
102 message = 'Regular parameters.'
103
104class StReleaseData(object):
105 format = 'QQ'
106 formatStr = struct.Struct(StHeader.format + format)
107 keys = StHeader.keys + ['when','deadline']
108 message = 'A job was/is going to be released.'
109
110#Not yet used by Sched Trace
111class StAssignedData(object):
112 format = 'Qc'
113 formatStr = struct.Struct(StHeader.format + format)
114 keys = StHeader.keys + ['when','target']
115 message = 'A job was assigned to a CPU.'
116
117class StSwitchToData(object):
118 format = 'QI'
119 formatStr = struct.Struct(StHeader.format + format)
120 keys = StHeader.keys + ['when','exec_time']
121 message = 'A process was switched to on a given CPU.'
122
123class StSwitchAwayData(object):
124 format = 'QI'
125 formatStr = struct.Struct(StHeader.format + format)
126 keys = StHeader.keys + ['when','exec_time']
127 message = 'A process was switched away on a given CPU.'
128
129class StCompletionData(object):
130 format = 'Q3xcc'
131 formatStr = struct.Struct(StHeader.format + format)
132 keys = StHeader.keys + ['when','forced?','flags']
133 message = 'A job completed.'
134
135class StBlockData(object):
136 format = 'Q'
137 formatStr = struct.Struct(StHeader.format + format)
138 keys = StHeader.keys + ['when']
139 message = 'A task blocks.'
140
141class StResumeData(object):
142 format = 'Q'
143 formatStr = struct.Struct(StHeader.format + format)
144 keys = StHeader.keys + ['when']
145 message = 'A task resumes.'
146
147class StSysReleaseData(object):
148 format = 'QQ'
149 formatStr = struct.Struct(StHeader.format + format)
150 keys = StHeader.keys + ['when','release']
151 message = 'All tasks have checked in, task system released by user'
152
153# Return the binary data type, given the type_num
154def _get_type(type_num):
155 types = [None,StNameData,StParamData,StReleaseData,StAssignedData,
156 StSwitchToData,StSwitchAwayData,StCompletionData,StBlockData,
157 StResumeData,StSysReleaseData]
158 return types[type_num]
159
160# Return the type name, given the type_num (this is simply a convenience to
161# programmers of other modules)
162def _get_type_name(type_num):
163 type_names = [None,"name","params","release","assign","switch_to",
164 "switch_away","completion","block","resume","sys_release"]
165 return type_names[type_num]