1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3
4"""
5Simple built-in backend.
6"""
7
8__author__     = "Lluís Vilanova <vilanova@ac.upc.edu>"
9__copyright__  = "Copyright 2012, Lluís Vilanova <vilanova@ac.upc.edu>"
10__license__    = "GPL version 2 or (at your option) any later version"
11
12__maintainer__ = "Stefan Hajnoczi"
13__email__      = "stefanha@linux.vnet.ibm.com"
14
15
16from tracetool import out
17
18
19PUBLIC = True
20
21
22def is_string(arg):
23    strtype = ('const char*', 'char*', 'const char *', 'char *')
24    if arg.lstrip().startswith(strtype):
25        return True
26    else:
27        return False
28
29def c(events):
30    out('#include "trace.h"',
31        '#include "trace/control.h"',
32        '#include "trace/simple.h"',
33        '',
34        )
35
36    for num, event in enumerate(events):
37        out('void trace_%(name)s(%(args)s)',
38            '{',
39            '    TraceBufferRecord rec;',
40            name = event.name,
41            args = event.args,
42            )
43        sizes = []
44        for type_, name in event.args:
45            if is_string(type_):
46                out('    size_t arg%(name)s_len = %(name)s ? MIN(strlen(%(name)s), MAX_TRACE_STRLEN) : 0;',
47                    name = name,
48                   )
49                strsizeinfo = "4 + arg%s_len" % name
50                sizes.append(strsizeinfo)
51            else:
52                sizes.append("8")
53        sizestr = " + ".join(sizes)
54        if len(event.args) == 0:
55            sizestr = '0'
56
57
58        out('',
59            '    TraceEvent *eventp = trace_event_id(%(event_id)s);',
60            '    bool _state = trace_event_get_state_dynamic(eventp);',
61            '    if (!_state) {',
62            '        return;',
63            '    }',
64            '',
65            '    if (trace_record_start(&rec, %(event_id)s, %(size_str)s)) {',
66            '        return; /* Trace Buffer Full, Event Dropped ! */',
67            '    }',
68            event_id = num,
69            size_str = sizestr,
70            )
71
72        if len(event.args) > 0:
73            for type_, name in event.args:
74                # string
75                if is_string(type_):
76                    out('    trace_record_write_str(&rec, %(name)s, arg%(name)s_len);',
77                        name = name,
78                       )
79                # pointer var (not string)
80                elif type_.endswith('*'):
81                    out('    trace_record_write_u64(&rec, (uintptr_t)(uint64_t *)%(name)s);',
82                        name = name,
83                       )
84                # primitive data type
85                else:
86                    out('    trace_record_write_u64(&rec, (uint64_t)%(name)s);',
87                       name = name,
88                       )
89
90        out('    trace_record_finish(&rec);',
91            '}',
92            '')
93
94
95def h(events):
96    out('#include "trace/simple.h"',
97        '')
98
99    for event in events:
100        out('void trace_%(name)s(%(args)s);',
101            name = event.name,
102            args = event.args,
103            )
104