diff options
| -rw-r--r-- | gedf_test.py | 6 | ||||
| -rw-r--r-- | naive_trace_reader.py | 88 | ||||
| -rwxr-xr-x | runtests.py | 4 | ||||
| -rwxr-xr-x | sample_script.py | 2 | ||||
| -rw-r--r-- | stats.py | 2 | ||||
| -rw-r--r-- | stdout_printer.py | 62 | ||||
| -rw-r--r-- | trace_reader.py | 75 |
7 files changed, 120 insertions, 119 deletions
diff --git a/gedf_test.py b/gedf_test.py index 5a3c0c4..8457901 100644 --- a/gedf_test.py +++ b/gedf_test.py | |||
| @@ -80,7 +80,7 @@ def gedf_test(stream): | |||
| 80 | ############################################################################### | 80 | ############################################################################### |
| 81 | 81 | ||
| 82 | # Internal representation of a Job | 82 | # Internal representation of a Job |
| 83 | class Job(): | 83 | class Job(object): |
| 84 | def __init__(self, record): | 84 | def __init__(self, record): |
| 85 | self.pid = record.pid | 85 | self.pid = record.pid |
| 86 | self.job = record.job | 86 | self.job = record.job |
| @@ -89,10 +89,10 @@ class Job(): | |||
| 89 | self.inversion_start = None | 89 | self.inversion_start = None |
| 90 | self.inversion_end = None | 90 | self.inversion_end = None |
| 91 | def __str__(self): | 91 | def __str__(self): |
| 92 | return "({}.{}:{})".format(self.pid,self.job,self.deadline) | 92 | return "(%d.%d:%d)" % (self.pid,self.job,self.deadline) |
| 93 | 93 | ||
| 94 | # G-EDF errors: the start or end of an inversion | 94 | # G-EDF errors: the start or end of an inversion |
| 95 | class Error(): | 95 | class Error(object): |
| 96 | def __init__(self, job, eligible, on_cpu): | 96 | def __init__(self, job, eligible, on_cpu): |
| 97 | self.job = copy.copy(job) | 97 | self.job = copy.copy(job) |
| 98 | self.eligible = copy.copy(eligible) | 98 | self.eligible = copy.copy(eligible) |
diff --git a/naive_trace_reader.py b/naive_trace_reader.py index 9a59353..0f117b8 100644 --- a/naive_trace_reader.py +++ b/naive_trace_reader.py | |||
| @@ -26,38 +26,38 @@ import struct | |||
| 26 | # Generator function returning an iterable over records in a trace file. | 26 | # Generator function returning an iterable over records in a trace file. |
| 27 | def trace_reader(files): | 27 | def trace_reader(files): |
| 28 | for file in files: | 28 | for file in files: |
| 29 | with open(file,'rb') as f: | 29 | f = open(file,'rb') |
| 30 | while True: | 30 | while True: |
| 31 | data = f.read(RECORD_HEAD_SIZE) | 31 | data = f.read(RECORD_HEAD_SIZE) |
| 32 | try: | 32 | try: |
| 33 | type_num = struct.unpack_from('b',data)[0] | 33 | type_num = struct.unpack_from('b',data)[0] |
| 34 | except struct.error: | 34 | except struct.error: |
| 35 | break #We read to the end of the file | 35 | break #We read to the end of the file |
| 36 | type = _get_type(type_num) | 36 | type = _get_type(type_num) |
| 37 | try: | 37 | try: |
| 38 | values = struct.unpack_from(StHeader.format + | 38 | values = struct.unpack_from(StHeader.format + |
| 39 | type.format,data) | 39 | type.format,data) |
| 40 | record_dict = dict(zip(type.keys,values)) | 40 | record_dict = dict(zip(type.keys,values)) |
| 41 | except struct.error: | 41 | except struct.error: |
| 42 | f.close() | 42 | f.close() |
| 43 | print("Invalid record detected, stopping.") | 43 | print "Invalid record detected, stopping." |
| 44 | exit() | 44 | exit() |
| 45 | 45 | ||
| 46 | # Convert the record_dict into an object | 46 | # Convert the record_dict into an object |
| 47 | record = _dict2obj(record_dict) | 47 | record = _dict2obj(record_dict) |
| 48 | 48 | ||
| 49 | # Give it a type name (easier to work with than type number) | 49 | # Give it a type name (easier to work with than type number) |
| 50 | record.type_name = _get_type_name(type_num) | 50 | record.type_name = _get_type_name(type_num) |
| 51 | 51 | ||
| 52 | # All records should have a 'record type' field. | 52 | # All records should have a 'record type' field. |
| 53 | # e.g. these are 'event's as opposed to 'error's | 53 | # e.g. these are 'event's as opposed to 'error's |
| 54 | record.record_type = "event" | 54 | record.record_type = "event" |
| 55 | 55 | ||
| 56 | # If there is no timestamp, set the time to 0 | 56 | # If there is no timestamp, set the time to 0 |
| 57 | if 'when' not in record.__dict__.keys(): | 57 | if 'when' not in record.__dict__.keys(): |
| 58 | record.when = 0 | 58 | record.when = 0 |
| 59 | 59 | ||
| 60 | yield record | 60 | yield record |
| 61 | 61 | ||
| 62 | ############################################################################### | 62 | ############################################################################### |
| 63 | # Private functions | 63 | # Private functions |
| @@ -83,68 +83,68 @@ def _dict2obj(d): | |||
| 83 | 83 | ||
| 84 | RECORD_HEAD_SIZE = 24 | 84 | RECORD_HEAD_SIZE = 24 |
| 85 | 85 | ||
| 86 | class StHeader: | 86 | class StHeader(object): |
| 87 | format = '<bbhi' | 87 | format = '<bbhi' |
| 88 | formatStr = struct.Struct(format) | 88 | formatStr = struct.Struct(format) |
| 89 | keys = ['type','cpu','pid','job'] | 89 | keys = ['type','cpu','pid','job'] |
| 90 | message = 'The header.' | 90 | message = 'The header.' |
| 91 | 91 | ||
| 92 | class StNameData: | 92 | class StNameData(object): |
| 93 | format = '16s' | 93 | format = '16s' |
| 94 | formatStr = struct.Struct(StHeader.format + format) | 94 | formatStr = struct.Struct(StHeader.format + format) |
| 95 | keys = StHeader.keys + ['name'] | 95 | keys = StHeader.keys + ['name'] |
| 96 | message = 'The name of the executable of this process.' | 96 | message = 'The name of the executable of this process.' |
| 97 | 97 | ||
| 98 | class StParamData: | 98 | class StParamData(object): |
| 99 | format = 'IIIc' | 99 | format = 'IIIc' |
| 100 | formatStr = struct.Struct(StHeader.format + format) | 100 | formatStr = struct.Struct(StHeader.format + format) |
| 101 | keys = StHeader.keys + ['wcet','period','phase','partition'] | 101 | keys = StHeader.keys + ['wcet','period','phase','partition'] |
| 102 | message = 'Regular parameters.' | 102 | message = 'Regular parameters.' |
| 103 | 103 | ||
| 104 | class StReleaseData: | 104 | class StReleaseData(object): |
| 105 | format = 'QQ' | 105 | format = 'QQ' |
| 106 | formatStr = struct.Struct(StHeader.format + format) | 106 | formatStr = struct.Struct(StHeader.format + format) |
| 107 | keys = StHeader.keys + ['when','deadline'] | 107 | keys = StHeader.keys + ['when','deadline'] |
| 108 | message = 'A job was/is going to be released.' | 108 | message = 'A job was/is going to be released.' |
| 109 | 109 | ||
| 110 | #Not yet used by Sched Trace | 110 | #Not yet used by Sched Trace |
| 111 | class StAssignedData: | 111 | class StAssignedData(object): |
| 112 | format = 'Qc' | 112 | format = 'Qc' |
| 113 | formatStr = struct.Struct(StHeader.format + format) | 113 | formatStr = struct.Struct(StHeader.format + format) |
| 114 | keys = StHeader.keys + ['when','target'] | 114 | keys = StHeader.keys + ['when','target'] |
| 115 | message = 'A job was assigned to a CPU.' | 115 | message = 'A job was assigned to a CPU.' |
| 116 | 116 | ||
| 117 | class StSwitchToData: | 117 | class StSwitchToData(object): |
| 118 | format = 'QI' | 118 | format = 'QI' |
| 119 | formatStr = struct.Struct(StHeader.format + format) | 119 | formatStr = struct.Struct(StHeader.format + format) |
| 120 | keys = StHeader.keys + ['when','exec_time'] | 120 | keys = StHeader.keys + ['when','exec_time'] |
| 121 | message = 'A process was switched to on a given CPU.' | 121 | message = 'A process was switched to on a given CPU.' |
| 122 | 122 | ||
| 123 | class StSwitchAwayData: | 123 | class StSwitchAwayData(object): |
| 124 | format = 'QI' | 124 | format = 'QI' |
| 125 | formatStr = struct.Struct(StHeader.format + format) | 125 | formatStr = struct.Struct(StHeader.format + format) |
| 126 | keys = StHeader.keys + ['when','exec_time'] | 126 | keys = StHeader.keys + ['when','exec_time'] |
| 127 | message = 'A process was switched away on a given CPU.' | 127 | message = 'A process was switched away on a given CPU.' |
| 128 | 128 | ||
| 129 | class StCompletionData: | 129 | class StCompletionData(object): |
| 130 | format = 'Q3x?c' | 130 | format = 'Q3xcc' |
| 131 | formatStr = struct.Struct(StHeader.format + format) | 131 | formatStr = struct.Struct(StHeader.format + format) |
| 132 | keys = StHeader.keys + ['when','forced?','flags'] | 132 | keys = StHeader.keys + ['when','forced?','flags'] |
| 133 | message = 'A job completed.' | 133 | message = 'A job completed.' |
| 134 | 134 | ||
| 135 | class StBlockData: | 135 | class StBlockData(object): |
| 136 | format = 'Q' | 136 | format = 'Q' |
| 137 | formatStr = struct.Struct(StHeader.format + format) | 137 | formatStr = struct.Struct(StHeader.format + format) |
| 138 | keys = StHeader.keys + ['when'] | 138 | keys = StHeader.keys + ['when'] |
| 139 | message = 'A task blocks.' | 139 | message = 'A task blocks.' |
| 140 | 140 | ||
| 141 | class StResumeData: | 141 | class StResumeData(object): |
| 142 | format = 'Q' | 142 | format = 'Q' |
| 143 | formatStr = struct.Struct(StHeader.format + format) | 143 | formatStr = struct.Struct(StHeader.format + format) |
| 144 | keys = StHeader.keys + ['when'] | 144 | keys = StHeader.keys + ['when'] |
| 145 | message = 'A task resumes.' | 145 | message = 'A task resumes.' |
| 146 | 146 | ||
| 147 | class StSysReleaseData: | 147 | class StSysReleaseData(object): |
| 148 | format = 'QQ' | 148 | format = 'QQ' |
| 149 | formatStr = struct.Struct(StHeader.format + format) | 149 | formatStr = struct.Struct(StHeader.format + format) |
| 150 | keys = StHeader.keys + ['when','release'] | 150 | keys = StHeader.keys + ['when','release'] |
diff --git a/runtests.py b/runtests.py index c235e2e..88dddf4 100755 --- a/runtests.py +++ b/runtests.py | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | #!/usr/bin/env python3 | 1 | #!/usr/bin/python |
| 2 | 2 | ||
| 3 | ############################################################################### | 3 | ############################################################################### |
| 4 | # Description | 4 | # Description |
| @@ -44,4 +44,4 @@ def test1(): | |||
| 44 | return "[FAIL]" | 44 | return "[FAIL]" |
| 45 | return "[SUCCESS]" | 45 | return "[SUCCESS]" |
| 46 | 46 | ||
| 47 | print("Test 1: {}".format(test1())) | 47 | print "Test 1: %s" % (test1()) |
diff --git a/sample_script.py b/sample_script.py index 6fdb6cc..c3b7843 100755 --- a/sample_script.py +++ b/sample_script.py | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | #!/usr/bin/env python3 | 1 | #!/usr/bin/python |
| 2 | 2 | ||
| 3 | # This is a sample script for using the tool. I would recommend copying | 3 | # This is a sample script for using the tool. I would recommend copying |
| 4 | # this and modifying it to suit your needs for a particular test. Make | 4 | # this and modifying it to suit your needs for a particular test. Make |
| @@ -28,7 +28,7 @@ def stats(stream): | |||
| 28 | avg_inversion = int(sum_inversions / num_inversions) | 28 | avg_inversion = int(sum_inversions / num_inversions) |
| 29 | else: | 29 | else: |
| 30 | avg_inversion = 0 | 30 | avg_inversion = 0 |
| 31 | class Obj(): pass | 31 | class Obj(object): pass |
| 32 | rec = Obj() | 32 | rec = Obj() |
| 33 | rec.record_type = "meta" | 33 | rec.record_type = "meta" |
| 34 | rec.type_name = "stats" | 34 | rec.type_name = "stats" |
diff --git a/stdout_printer.py b/stdout_printer.py index 5bbcead..f8d9a84 100644 --- a/stdout_printer.py +++ b/stdout_printer.py | |||
| @@ -20,50 +20,50 @@ def stdout_printer(stream): | |||
| 20 | _print_inversion_end(record) | 20 | _print_inversion_end(record) |
| 21 | else: | 21 | else: |
| 22 | continue | 22 | continue |
| 23 | print("") | 23 | print "" |
| 24 | 24 | ||
| 25 | ############################################################################### | 25 | ############################################################################### |
| 26 | # Private functions | 26 | # Private functions |
| 27 | ############################################################################### | 27 | ############################################################################### |
| 28 | 28 | ||
| 29 | def _print_event(record): | 29 | def _print_event(record): |
| 30 | print("Job: {}.{}".format(record.pid,record.job)) | 30 | print "Job: %d.%d" % (record.pid,record.job) |
| 31 | print("Type: {}".format(record.type_name)) | 31 | print "Type: %s" % (record.type_name) |
| 32 | print("Time: {}".format(record.when)) | 32 | print "Time: %d" % (record.when) |
| 33 | 33 | ||
| 34 | def _print_inversion_start(record): | 34 | def _print_inversion_start(record): |
| 35 | print("Type: {}".format("Inversion start")) | 35 | print "Type: %s" % ("Inversion start") |
| 36 | print("Time: {}".format(record.job.inversion_start)) | 36 | print "Time: %d" % (record.job.inversion_start) |
| 37 | print("Job: {}.{}".format(record.job.pid,record.job.job)) | 37 | print "Job: %d.%d" % (record.job.pid,record.job.job) |
| 38 | print("Deadline: {}".format(record.job.deadline)) | 38 | print "Deadline: %d" % (record.job.deadline) |
| 39 | print("Eligible: ",end="") | 39 | print "Eligible: ", |
| 40 | for job in record.eligible: | 40 | for job in record.eligible: |
| 41 | print(str(job) + " ",end="") | 41 | print str(job) + " ", |
| 42 | print("") | 42 | |
| 43 | print("On CPU: ",end="") | 43 | print "On CPU: ", |
| 44 | for job in record.on_cpu: | 44 | for job in record.on_cpu: |
| 45 | print(str(job) + " ",end="") | 45 | print str(job) + " ", |
| 46 | print("") #newline | 46 | print #newline |
| 47 | 47 | ||
| 48 | def _print_inversion_end(record): | 48 | def _print_inversion_end(record): |
| 49 | print("Type: {}".format("Inversion end")) | 49 | print "Type: %s" % ("Inversion end") |
| 50 | print("Time: {}".format(record.job.inversion_end)) | 50 | print "Time: %d" % (record.job.inversion_end) |
| 51 | print("Duration: {}".format( | 51 | print "Duration: %d" % ( |
| 52 | record.job.inversion_end - record.job.inversion_start)) | 52 | record.job.inversion_end - record.job.inversion_start) |
| 53 | print("Job: {}.{}".format(record.job.pid,record.job.job)) | 53 | print "Job: %d.%d" % (record.job.pid,record.job.job) |
| 54 | print("Deadline: {}".format(record.job.deadline)) | 54 | print "Deadline: %d" % (record.job.deadline) |
| 55 | print("Eligible: ",end="") | 55 | print "Eligible: ", |
| 56 | for job in record.eligible: | 56 | for job in record.eligible: |
| 57 | print(str(job) + " ",end="") | 57 | print str(job) + " ", |
| 58 | print("") | 58 | |
| 59 | print("On CPU: ",end="") | 59 | print "On CPU: ", |
| 60 | for job in record.on_cpu: | 60 | for job in record.on_cpu: |
| 61 | print(str(job) + " ",end="") | 61 | print str(job) + " ", |
| 62 | print("") #newline | 62 | print #newline |
| 63 | 63 | ||
| 64 | def _print_stats(record): | 64 | def _print_stats(record): |
| 65 | print("Inversion statistics") | 65 | print "Inversion statistics" |
| 66 | print("Num inversions: {}".format(record.num_inversions)) | 66 | print "Num inversions: %d" % (record.num_inversions) |
| 67 | print("Min inversion: {}".format(record.min_inversion)) | 67 | print "Min inversion: %d" % (record.min_inversion) |
| 68 | print("Max inversion: {}".format(record.max_inversion)) | 68 | print "Max inversion: %d" % (record.max_inversion) |
| 69 | print("Avg inversion: {}".format(record.avg_inversion)) | 69 | print "Avg inversion: %d" % (record.avg_inversion) |
diff --git a/trace_reader.py b/trace_reader.py index e18547e..a4ff964 100644 --- a/trace_reader.py +++ b/trace_reader.py | |||
| @@ -49,7 +49,7 @@ def trace_reader(files): | |||
| 49 | for file in files: | 49 | for file in files: |
| 50 | file_iter = _get_file_iter(file) | 50 | file_iter = _get_file_iter(file) |
| 51 | file_iters.append(file_iter) | 51 | file_iters.append(file_iter) |
| 52 | file_iter_buff.append([next(file_iter)]) | 52 | file_iter_buff.append([file_iter.next()]) |
| 53 | 53 | ||
| 54 | # We keep 100 records in each buffer and then keep the buffer sorted | 54 | # We keep 100 records in each buffer and then keep the buffer sorted |
| 55 | # This is because records may have been recorded slightly out of order | 55 | # This is because records may have been recorded slightly out of order |
| @@ -57,7 +57,7 @@ def trace_reader(files): | |||
| 57 | # overwhelmingly probably. | 57 | # overwhelmingly probably. |
| 58 | for x in range(0,len(file_iter_buff)): | 58 | for x in range(0,len(file_iter_buff)): |
| 59 | for y in range(0,100): | 59 | for y in range(0,100): |
| 60 | file_iter_buff[x].append(next(file_iters[x])) | 60 | file_iter_buff[x].append(file_iters[x].next()) |
| 61 | for x in range(0,len(file_iter_buff)): | 61 | for x in range(0,len(file_iter_buff)): |
| 62 | file_iter_buff[x] = sorted(file_iter_buff[x],key=lambda rec: rec.when) | 62 | file_iter_buff[x] = sorted(file_iter_buff[x],key=lambda rec: rec.when) |
| 63 | 63 | ||
| @@ -83,7 +83,7 @@ def trace_reader(files): | |||
| 83 | # Try to append a new record to the buffer (if there is another) and | 83 | # Try to append a new record to the buffer (if there is another) and |
| 84 | # then keep the buffer sorted | 84 | # then keep the buffer sorted |
| 85 | try: | 85 | try: |
| 86 | file_iter_buff[buff_to_refill].append(next(file_iters[buff_to_refill])) | 86 | file_iter_buff[buff_to_refill].append(file_iters[buff_to_refill].next()) |
| 87 | file_iter_buff[buff_to_refill] = sorted(file_iter_buff[buff_to_refill], | 87 | file_iter_buff[buff_to_refill] = sorted(file_iter_buff[buff_to_refill], |
| 88 | key=lambda rec: rec.when) | 88 | key=lambda rec: rec.when) |
| 89 | 89 | ||
| @@ -109,42 +109,42 @@ def trace_reader(files): | |||
| 109 | 109 | ||
| 110 | # Returns an iterator to pull records from a file | 110 | # Returns an iterator to pull records from a file |
| 111 | def _get_file_iter(file): | 111 | def _get_file_iter(file): |
| 112 | with open(file,'rb') as f: | 112 | f = open(file,'rb') |
| 113 | while True: | 113 | while True: |
| 114 | data = f.read(RECORD_HEAD_SIZE) | 114 | data = f.read(RECORD_HEAD_SIZE) |
| 115 | try: | 115 | try: |
| 116 | type_num = struct.unpack_from('b',data)[0] | 116 | type_num = struct.unpack_from('b',data)[0] |
| 117 | except struct.error: | 117 | except struct.error: |
| 118 | break #We read to the end of the file | 118 | break #We read to the end of the file |
| 119 | type = _get_type(type_num) | 119 | type = _get_type(type_num) |
| 120 | try: | 120 | try: |
| 121 | values = struct.unpack_from(StHeader.format + | 121 | values = struct.unpack_from(StHeader.format + |
| 122 | type.format,data) | 122 | type.format,data) |
| 123 | record_dict = dict(zip(type.keys,values)) | 123 | record_dict = dict(zip(type.keys,values)) |
| 124 | except struct.error: | 124 | except struct.error: |
| 125 | f.close() | 125 | f.close() |
| 126 | print("Invalid record detected, stopping.") | 126 | print "Invalid record detected, stopping." |
| 127 | exit() | 127 | exit() |
| 128 | 128 | ||
| 129 | # Convert the record_dict into an object | 129 | # Convert the record_dict into an object |
| 130 | record = _dict2obj(record_dict) | 130 | record = _dict2obj(record_dict) |
| 131 | 131 | ||
| 132 | # Give it a type name (easier to work with than type number) | 132 | # Give it a type name (easier to work with than type number) |
| 133 | record.type_name = _get_type_name(type_num) | 133 | record.type_name = _get_type_name(type_num) |
| 134 | 134 | ||
| 135 | # All records should have a 'record type' field. | 135 | # All records should have a 'record type' field. |
| 136 | # e.g. these are 'event's as opposed to 'error's | 136 | # e.g. these are 'event's as opposed to 'error's |
| 137 | record.record_type = "event" | 137 | record.record_type = "event" |
| 138 | 138 | ||
| 139 | # If there is no timestamp, set the time to 0 | 139 | # If there is no timestamp, set the time to 0 |
| 140 | if 'when' not in record.__dict__.keys(): | 140 | if 'when' not in record.__dict__.keys(): |
| 141 | record.when = 0 | 141 | record.when = 0 |
| 142 | 142 | ||
| 143 | yield record | 143 | yield record |
| 144 | 144 | ||
| 145 | # Convert a dict into an object | 145 | # Convert a dict into an object |
| 146 | def _dict2obj(d): | 146 | def _dict2obj(d): |
| 147 | class Obj: pass | 147 | class Obj(object): pass |
| 148 | o = Obj() | 148 | o = Obj() |
| 149 | for key in d.keys(): | 149 | for key in d.keys(): |
| 150 | o.__dict__[key] = d[key] | 150 | o.__dict__[key] = d[key] |
| @@ -206,7 +206,8 @@ class StSwitchAwayData: | |||
| 206 | message = 'A process was switched away on a given CPU.' | 206 | message = 'A process was switched away on a given CPU.' |
| 207 | 207 | ||
| 208 | class StCompletionData: | 208 | class StCompletionData: |
| 209 | format = 'Q3x?c' | 209 | #format = 'Q3x?c' |
| 210 | format = 'Q3xcc' | ||
| 210 | formatStr = struct.Struct(StHeader.format + format) | 211 | formatStr = struct.Struct(StHeader.format + format) |
| 211 | keys = StHeader.keys + ['when','forced?','flags'] | 212 | keys = StHeader.keys + ['when','forced?','flags'] |
| 212 | message = 'A job completed.' | 213 | message = 'A job completed.' |
