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_enum)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_enum = 'TRACE_' + event.name.upper(),
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, (uintptr_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    for event in events:
98        out('void trace_%(name)s(%(args)s);',
99            name = event.name,
100            args = event.args,
101            )
102