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
18def is_string(arg):
19    strtype = ('const char*', 'char*', 'const char *', 'char *')
20    if arg.lstrip().startswith(strtype):
21        return True
22    else:
23        return False
24
25def c(events):
26    out('#include "trace.h"',
27        '#include "trace/simple.h"',
28        '',
29        'TraceEvent trace_list[] = {')
30
31    for e in events:
32        out('{.tp_name = "%(name)s", .state=0},',
33            name = e.name,
34            )
35
36    out('};',
37        '')
38
39    for num, event in enumerate(events):
40        out('void trace_%(name)s(%(args)s)',
41            '{',
42            '    TraceBufferRecord rec;',
43            name = event.name,
44            args = event.args,
45            )
46        sizes = []
47        for type_, name in event.args:
48            if is_string(type_):
49                out('    size_t arg%(name)s_len = %(name)s ? MIN(strlen(%(name)s), MAX_TRACE_STRLEN) : 0;',
50                    name = name,
51                   )
52                strsizeinfo = "4 + arg%s_len" % name
53                sizes.append(strsizeinfo)
54            else:
55                sizes.append("8")
56        sizestr = " + ".join(sizes)
57        if len(event.args) == 0:
58            sizestr = '0'
59
60
61        out('',
62            '    if (!trace_list[%(event_id)s].state) {',
63            '        return;',
64            '    }',
65            '',
66            '    if (trace_record_start(&rec, %(event_id)s, %(size_str)s)) {',
67            '        return; /* Trace Buffer Full, Event Dropped ! */',
68            '    }',
69            event_id = num,
70            size_str = sizestr,
71            )
72
73        if len(event.args) > 0:
74            for type_, name in event.args:
75                # string
76                if is_string(type_):
77                    out('    trace_record_write_str(&rec, %(name)s, arg%(name)s_len);',
78                        name = name,
79                       )
80                # pointer var (not string)
81                elif type_.endswith('*'):
82                    out('    trace_record_write_u64(&rec, (uint64_t)(uint64_t *)%(name)s);',
83                        name = name,
84                       )
85                # primitive data type
86                else:
87                    out('    trace_record_write_u64(&rec, (uint64_t)%(name)s);',
88                       name = name,
89                       )
90
91        out('    trace_record_finish(&rec);',
92            '}',
93            '')
94
95
96def h(events):
97    out('#include "trace/simple.h"',
98        '')
99
100    for event in events:
101        out('void trace_%(name)s(%(args)s);',
102            name = event.name,
103            args = event.args,
104            )
105    out('')
106    out('#define NR_TRACE_EVENTS %d' % len(events))
107    out('extern TraceEvent trace_list[NR_TRACE_EVENTS];')
108