diff options
| author | Mac Mollison <mollison@cs.unc.edu> | 2010-02-09 00:26:01 -0500 |
|---|---|---|
| committer | Mac Mollison <mollison@cs.unc.edu> | 2010-02-09 00:41:51 -0500 |
| commit | 398c0e00341ce6cd747dec36eb63e138c813a12c (patch) | |
| tree | b9a4468c6b081bbe2cfe97c51efd79c8984985c8 | |
| parent | d260162e66d5f15d6f133bc50c2dd47107e228de (diff) | |
Minor cleanup; added error printing functionality to stdout_printer.
| -rwxr-xr-x | run.py | 4 | ||||
| -rwxr-xr-x | runtests.py | 2 | ||||
| -rw-r--r-- | stdout_printer.py | 9 | ||||
| -rw-r--r-- | trace_reader.py | 42 |
4 files changed, 45 insertions, 12 deletions
| @@ -30,5 +30,5 @@ g4 = [ | |||
| 30 | # Pipeline | 30 | # Pipeline |
| 31 | ############################################################################### | 31 | ############################################################################### |
| 32 | 32 | ||
| 33 | stream = trace_reader.get_trace_record_stream(g4) | 33 | stream = trace_reader.trace_reader(g4) |
| 34 | stdout_printer.print_stream(stream) | 34 | stdout_printer.stdout_printer(stream) |
diff --git a/runtests.py b/runtests.py index 06c5caa..f4a9274 100755 --- a/runtests.py +++ b/runtests.py | |||
| @@ -31,7 +31,7 @@ files = [ | |||
| 31 | 31 | ||
| 32 | # Does the trace reader sort files by time correctly? | 32 | # Does the trace reader sort files by time correctly? |
| 33 | def test1(): | 33 | def test1(): |
| 34 | stream = trace_reader.get_trace_record_stream(files) | 34 | stream = trace_reader.trace_reader(files) |
| 35 | last_time = 0 | 35 | last_time = 0 |
| 36 | for item in stream: | 36 | for item in stream: |
| 37 | if last_time > item.when: | 37 | if last_time > item.when: |
diff --git a/stdout_printer.py b/stdout_printer.py index 98e91fa..1bc0d64 100644 --- a/stdout_printer.py +++ b/stdout_printer.py | |||
| @@ -8,10 +8,12 @@ | |||
| 8 | # Public functions | 8 | # Public functions |
| 9 | ############################################################################### | 9 | ############################################################################### |
| 10 | 10 | ||
| 11 | def print_stream(stream): | 11 | def stdout_printer(stream): |
| 12 | for record in stream: | 12 | for record in stream: |
| 13 | if record.record_type == "event": | 13 | if record.record_type == "event": |
| 14 | _print_event(record) | 14 | _print_event(record) |
| 15 | elif record.record_type == "error": | ||
| 16 | _print_error(record) | ||
| 15 | print("") | 17 | print("") |
| 16 | 18 | ||
| 17 | ############################################################################### | 19 | ############################################################################### |
| @@ -22,3 +24,8 @@ def _print_event(record): | |||
| 22 | print("Job: {}.{}".format(record.pid,record.job)) | 24 | print("Job: {}.{}".format(record.pid,record.job)) |
| 23 | print("Type: {}".format(record.type_name)) | 25 | print("Type: {}".format(record.type_name)) |
| 24 | print("Time: {}".format(record.when)) | 26 | print("Time: {}".format(record.when)) |
| 27 | |||
| 28 | def _print_error(record): | ||
| 29 | print("Job: {}.{}".format(record.pid,record.job)) | ||
| 30 | print("Time: {}".format(record.when)) | ||
| 31 | print("Type: {}".format("ERROR")) | ||
diff --git a/trace_reader.py b/trace_reader.py index a0a32ce..7b579b6 100644 --- a/trace_reader.py +++ b/trace_reader.py | |||
| @@ -2,9 +2,24 @@ | |||
| 2 | # Description | 2 | # Description |
| 3 | ############################################################################### | 3 | ############################################################################### |
| 4 | 4 | ||
| 5 | # get_trace_record_stream(files) returns an iterator which produces records | 5 | # trace_reader(files) returns an iterator which produces records |
| 6 | # in order from the files given. (the param is a list of files.) | 6 | # in order from the files given. (the param is a list of files.) |
| 7 | 7 | # | |
| 8 | # Each record is just a Python object. It is guaranteed to have the following | ||
| 9 | # attributes: | ||
| 10 | # - 'pid': pid of the task | ||
| 11 | # - 'job': job number for that task | ||
| 12 | # - 'cpu', given by LITMUS | ||
| 13 | # - 'when', given by LITMUS as a timestamp. LITMUS does not provide a | ||
| 14 | # timestamp for all records. In this case, when is set to 0. | ||
| 15 | # - 'type', a numerical value given by LITMUS | ||
| 16 | # - 'type_name', a human-readable name defined in this module | ||
| 17 | # - 'record_type', set to 'event' by this module (to distinguish from, e.g., | ||
| 18 | # error records produced elsewhere). | ||
| 19 | # - Possible additional attributes, depending on the type of record. | ||
| 20 | # | ||
| 21 | # To find out exactly what attributes are set for each record type, look at | ||
| 22 | # the trace-parsing information at the bottom of this file. | ||
| 8 | 23 | ||
| 9 | ############################################################################### | 24 | ############################################################################### |
| 10 | # Imports | 25 | # Imports |
| @@ -18,7 +33,7 @@ import struct | |||
| 18 | ############################################################################### | 33 | ############################################################################### |
| 19 | 34 | ||
| 20 | # Generator function returning an iterable over records in a trace file. | 35 | # Generator function returning an iterable over records in a trace file. |
| 21 | def get_trace_record_stream(files): | 36 | def trace_reader(files): |
| 22 | 37 | ||
| 23 | # Create iterators for each file and a buffer to store records in | 38 | # Create iterators for each file and a buffer to store records in |
| 24 | file_iters = [] # file iterators | 39 | file_iters = [] # file iterators |
| @@ -29,7 +44,7 @@ def get_trace_record_stream(files): | |||
| 29 | file_iter_buff.append([next(file_iter)]) | 44 | file_iter_buff.append([next(file_iter)]) |
| 30 | 45 | ||
| 31 | # We keep 100 records in each buffer and then keep the buffer sorted | 46 | # We keep 100 records in each buffer and then keep the buffer sorted |
| 32 | # This is because records may be recorded slightly out of order | 47 | # This is because records may have been recorded slightly out of order |
| 33 | for x in range(0,len(file_iter_buff)): | 48 | for x in range(0,len(file_iter_buff)): |
| 34 | for y in range(0,100): | 49 | for y in range(0,100): |
| 35 | file_iter_buff[x].append(next(file_iters[x])) | 50 | file_iter_buff[x].append(next(file_iters[x])) |
| @@ -89,7 +104,11 @@ def _get_file_iter(file): | |||
| 89 | f.close() | 104 | f.close() |
| 90 | print("Invalid record detected, stopping.") | 105 | print("Invalid record detected, stopping.") |
| 91 | exit() | 106 | exit() |
| 107 | |||
| 108 | # Convert the record_dict into an object | ||
| 92 | record = _dict2obj(record_dict) | 109 | record = _dict2obj(record_dict) |
| 110 | |||
| 111 | # Give it a type name (easier to work with than type number) | ||
| 93 | record.type_name = _get_type_name(type_num) | 112 | record.type_name = _get_type_name(type_num) |
| 94 | 113 | ||
| 95 | # All records should have a 'record type' field. | 114 | # All records should have a 'record type' field. |
| @@ -114,6 +133,12 @@ def _dict2obj(d): | |||
| 114 | # Trace record data types and accessor functions | 133 | # Trace record data types and accessor functions |
| 115 | ############################################################################### | 134 | ############################################################################### |
| 116 | 135 | ||
| 136 | # Each class below represents a type of event record. The format attribute | ||
| 137 | # specifies how to decode the binary record and the keys attribute | ||
| 138 | # specifies how to name the pieces of information decoded. Note that all | ||
| 139 | # event records have a common initial 24 bytes, represented by the StHeader | ||
| 140 | # class. | ||
| 141 | |||
| 117 | RECORD_HEAD_SIZE = 24 | 142 | RECORD_HEAD_SIZE = 24 |
| 118 | 143 | ||
| 119 | class StHeader: | 144 | class StHeader: |
| @@ -190,8 +215,9 @@ def _get_type(type_num): | |||
| 190 | StResumeData,StSysReleaseData] | 215 | StResumeData,StSysReleaseData] |
| 191 | return types[type_num] | 216 | return types[type_num] |
| 192 | 217 | ||
| 193 | # Return the type name, given the type_num | 218 | # Return the type name, given the type_num (this is simply a convenience to |
| 219 | # programmers of other modules) | ||
| 194 | def _get_type_name(type_num): | 220 | def _get_type_name(type_num): |
| 195 | type_names = [None,"name","params","release","assign","switch_to","switch_away", | 221 | type_names = [None,"name","params","release","assign","switch_to", |
| 196 | "completion","block","resume","sys_release"] | 222 | "switch_away","completion","block","resume","sys_release"] |
| 197 | return type_names[type_num] | 223 | return type_names[type_num] |
