summaryrefslogtreecommitdiffstats
path: root/unit_trace/viz/convert.py
blob: f9f67931a91bab8968a91cede0f38385bb7bfc98 (plain) (blame)
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
#!/usr/bin/env python
from schedule import *

"""Class that interprets the raw trace data, outputting it
to a Python schedule object.

Doesn't do any checking on the logic of the schedule (except to
check for corrupted data)"""

def get_type(type_num):
    """Return the binary data type, given the type_num"""
    return Trace.DATA_TYPES[type_num]

def get_type_num(type):
    nums = dict(zip(Trace.DATA_TYPES, range(0, 11)))
    return nums[type]

def _get_job_from_record(sched, record):
    tname = _pid_to_task_name(record['pid'])
    job_no = record['job']
    if tname not in sched.get_tasks():
        sched.add_task(Task(tname, []))
    if job_no not in sched.get_tasks()[tname].get_jobs():
        sched.get_tasks()[tname].add_job(Job(job_no, []))
    job = sched.get_tasks()[tname].get_jobs()[job_no]
    return job

def convert_trace_to_schedule(stream):
    """The main function of interest in this module. Coverts a stream of records
    to a Schedule object."""
    def noop():
        pass

    print "Converting"

    num_cpus, stream = _find_num_cpus(stream)
    sched = Schedule('sched', num_cpus)
    for record in stream:
        #if record['record_type'] == 'meta':
        #    if record['type_name'] == 'num_cpus':
        #        sched = Schedule('sched', record.num_cpus)
        #    continue
        if record['record_type'] == 'event':
            job = _get_job_from_record(sched, record)
            cpu = record['cpu']

            # if not hasattr(record, 'deadline'):
            #     record['deadline'] = None

            actions = {
                'name' : (noop),
                'params' : (noop),
                'release' : (lambda :
                (job.add_event(ReleaseEvent(record['when'], cpu)),
                job.add_event(DeadlineEvent(record['deadline'], cpu)))),
                'switch_to' : (lambda :
                job.add_event(SwitchToEvent(record['when'], cpu))),
                'switch_away' : (lambda :
                job.add_event(SwitchAwayEvent(record['when'], cpu))),
                'assign' : (noop),
                'completion' : (lambda :
                job.add_event(CompleteEvent(record['when'], cpu))),
                'block' : (lambda :
                job.add_event(SuspendEvent(record['when'], cpu))),
                'resume' : (lambda :
                job.add_event(ResumeEvent(record['when'], cpu))),
                'sys_release' : (noop)
            }

            actions[record['type_name']]()

        elif record['record_type'] == 'error':
            job = _get_job_from_record(sched, record['job'])

            actions = {
                'inversion_start' : (lambda :
                job.add_event(InversionStartEvent(record['job'].inversion_start))),
                'inversion_end' : (lambda :
                job.add_event(InversionEndEvent(record['job'].inversion_end)))
            }

            actions[record['type_name']]()

    print "Done converting"

    return sched

def _pid_to_task_name(pid):
    """Converts a PID to an appropriate name for a task."""
    return str(pid)

def _find_num_cpus(stream):
    """Determines the number of CPUs used by scanning the binary format."""
    max = 0
    stream_list = []
    for record in stream:
        stream_list.append(record)
        if record['record_type'] == 'event':
            if record['cpu'] > max:
                max = record['cpu']

    def recycle(l):
        for record in l:
            yield record
    return (max + 1, recycle(stream_list))