summaryrefslogtreecommitdiffstats
path: root/unit_trace/viz/convert.py
blob: 278a54161eeb894ce15a783b97c16da5b0f51923 (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
106
107
108
109
110
111
112
113
114
#!/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):
    if record.pid == 0:
        return None
    else:
        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

    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

            # This whole method should be refactored for this posibility
            if job is None:
                if record.type_name == "action":
                    event = ActionEvent(record.when, cpu, record.action)
                    event.set_schedule(sched)
                    sched.add_jobless(event)
                continue

            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))),
                'action' : (lambda :
                job.add_event(ActionEvent(record.when, cpu, record.action))),
                '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]()

    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))