Add callsite support
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Tue, 2 Oct 2012 18:47:18 +0000 (14:47 -0400)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Tue, 2 Oct 2012 18:47:18 +0000 (14:47 -0400)
Callsite support has been added to the spec.

Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
converter/babeltrace.c
formats/ctf-text/ctf-text.c
formats/ctf/metadata/ctf-ast.h
formats/ctf/metadata/ctf-lexer.l
formats/ctf/metadata/ctf-parser.y
formats/ctf/metadata/ctf-visitor-generate-io-struct.c
formats/ctf/metadata/ctf-visitor-parent-links.c
formats/ctf/metadata/ctf-visitor-semantic-validator.c
formats/ctf/metadata/ctf-visitor-xml.c
include/babeltrace/babeltrace-internal.h
include/babeltrace/ctf-ir/metadata.h

index dc8b4a700bbb450331e6cb6366b4e8152a8d486d..099a9fa6d62ea50b17164f523573cb9648ca8070 100644 (file)
@@ -134,7 +134,7 @@ static void usage(FILE *fp)
        fprintf(fp, "                                        (default: payload,context)\n");
        fprintf(fp, "  -f, --fields name1<,name2,...> Print additional fields:\n");
        fprintf(fp, "                                     all, trace, trace:hostname, trace:domain,\n");
-       fprintf(fp, "                                     trace:procname, trace:vpid, loglevel, emf.\n");
+       fprintf(fp, "                                     trace:procname, trace:vpid, loglevel, emf, callsite.\n");
        fprintf(fp, "                                     (default: trace:hostname,trace:procname,trace:vpid)\n");
        fprintf(fp, "      --clock-cycles             Timestamp in cycles\n");
        fprintf(fp, "      --clock-offset seconds     Clock offset in seconds\n");
@@ -211,6 +211,8 @@ static int get_fields_args(poptContext *pc)
                        opt_loglevel_field = 1;
                else if (!strcmp(str, "emf"))
                        opt_emf_field = 1;
+               else if (!strcmp(str, "callsite"))
+                       opt_callsite_field = 1;
                else {
                        fprintf(stderr, "[error] unknown field type %s\n", str);
                        return -EINVAL;
index e23bb9e2c4093ab2ca45029bd7046c02c642ed94..4f46427be5ec38bb5fce23e4a905267486fa12a4 100644 (file)
@@ -50,6 +50,7 @@ int opt_all_field_names,
        opt_trace_default_fields = 1,
        opt_loglevel_field,
        opt_emf_field,
+       opt_callsite_field,
        opt_delta_field = 1;
 
 enum field_item {
@@ -117,6 +118,14 @@ void __attribute__((constructor)) init_quarks(void)
        Q_STREAM_PACKET_CONTEXT_PACKET_SIZE = g_quark_from_static_string("stream.packet.context.packet_size");
 }
 
+static
+struct ctf_callsite *ctf_trace_callsite_lookup(struct ctf_trace *trace,
+                       GQuark callsite_name)
+{
+       return g_hash_table_lookup(trace->callsites,
+                       (gpointer) (unsigned long) callsite_name);
+}
+
 int print_field(struct definition *definition)
 {
        /* Print all fields in verbose mode */
@@ -399,6 +408,26 @@ int ctf_text_write_event(struct stream_pos *ppos, struct ctf_stream_definition *
                        fprintf(pos->fp, ", ");
                dom_print = 1;
        }
+       if ((opt_callsite_field || opt_all_fields)) {
+               struct ctf_callsite *callsite;
+
+               callsite = ctf_trace_callsite_lookup(stream_class->trace,
+                               event_class->name);
+               if (callsite) {
+                       set_field_names_print(pos, ITEM_HEADER);
+                       if (pos->print_names) {
+                               fprintf(pos->fp, "callsite = ");
+                       } else if (dom_print) {
+                               fprintf(pos->fp, ":");
+                       }
+                       fprintf(pos->fp, "[%s@%s:%" PRIu64 "]",
+                               callsite->func, callsite->file,
+                               callsite->line);
+                       if (pos->print_names)
+                               fprintf(pos->fp, ", ");
+                       dom_print = 1;
+               }
+       }
        if (dom_print && !pos->print_names)
                fprintf(pos->fp, " ");
        set_field_names_print(pos, ITEM_HEADER);
index 8d2e5d776b838232de8ec5f5c08f18043f786618..f3107fd29f02e313ceddf62d2384d2f92adea3c9 100644 (file)
@@ -41,6 +41,7 @@ enum node_type {
        NODE_ENV,
        NODE_TRACE,
        NODE_CLOCK,
+       NODE_CALLSITE,
 
        NODE_CTF_EXPRESSION,
        NODE_UNARY_EXPRESSION,
@@ -91,6 +92,7 @@ struct ctf_node {
                        struct bt_list_head stream;
                        struct bt_list_head event;
                        struct bt_list_head clock;
+                       struct bt_list_head callsite;
                } root;
                struct {
                        /*
@@ -127,6 +129,13 @@ struct ctf_node {
                         */
                        struct bt_list_head declaration_list;
                } clock;
+               struct {
+                       /*
+                        * Children nodes are ctf_expression, typedef,
+                        * typealias and type_specifier_list.
+                        */
+                       struct bt_list_head declaration_list;
+               } callsite;
                struct {
                        struct bt_list_head left;       /* Should be string */
                        struct bt_list_head right;      /* Unary exp. or type */
index bedda4ada67198883724b5ab1cd10b9a7134eebb..a689d4cea5f6c6399ad065b88978f953f736e6c4 100644 (file)
@@ -112,6 +112,7 @@ stream                              setstring(yyextra, yylval, yytext); return STREAM;
 string                         setstring(yyextra, yylval, yytext); return STRING;
 struct                         setstring(yyextra, yylval, yytext); return STRUCT;
 trace                          setstring(yyextra, yylval, yytext); return TRACE;
+callsite                       setstring(yyextra, yylval, yytext); return CALLSITE;
 typealias                      setstring(yyextra, yylval, yytext); return TYPEALIAS;
 typedef                                setstring(yyextra, yylval, yytext); return TYPEDEF;
 unsigned                       setstring(yyextra, yylval, yytext); return UNSIGNED;
index 28b7bebe60309e2420c45dc5d0ffb8e1cace28b1..7f91365d329f4eea2bdb54cb7262f5561e752257 100644 (file)
@@ -72,6 +72,7 @@ static const char *node_type_to_str[] = {
        [ NODE_STREAM ] = "NODE_STREAM",
        [ NODE_TRACE ] = "NODE_TRACE",
        [ NODE_CLOCK ] = "NODE_CLOCK",
+       [ NODE_CALLSITE ] = "NODE_CALLSITE",
        [ NODE_CTF_EXPRESSION ] = "NODE_CTF_EXPRESSION",
        [ NODE_UNARY_EXPRESSION ] = "NODE_UNARY_EXPRESSION",
        [ NODE_TYPEDEF ] = "NODE_TYPEDEF",
@@ -261,6 +262,9 @@ static struct ctf_node *make_node(struct ctf_scanner *scanner,
        case NODE_CLOCK:
                BT_INIT_LIST_HEAD(&node->u.clock.declaration_list);
                break;
+       case NODE_CALLSITE:
+               BT_INIT_LIST_HEAD(&node->u.callsite.declaration_list);
+               break;
 
        case NODE_CTF_EXPRESSION:
                BT_INIT_LIST_HEAD(&node->u.ctf_expression.left);
@@ -347,6 +351,9 @@ static int reparent_ctf_expression(struct ctf_node *node,
        case NODE_CLOCK:
                _bt_list_splice_tail(&node->tmp_head, &parent->u.clock.declaration_list);
                break;
+       case NODE_CALLSITE:
+               _bt_list_splice_tail(&node->tmp_head, &parent->u.callsite.declaration_list);
+               break;
        case NODE_FLOATING_POINT:
                _bt_list_splice_tail(&node->tmp_head, &parent->u.floating_point.expressions);
                break;
@@ -405,6 +412,9 @@ static int reparent_typedef(struct ctf_node *node, struct ctf_node *parent)
        case NODE_CLOCK:
                _bt_list_splice_tail(&node->tmp_head, &parent->u.clock.declaration_list);
                break;
+       case NODE_CALLSITE:
+               _bt_list_splice_tail(&node->tmp_head, &parent->u.callsite.declaration_list);
+               break;
        case NODE_VARIANT:
                _bt_list_splice_tail(&node->tmp_head, &parent->u.variant.declaration_list);
                break;
@@ -460,6 +470,9 @@ static int reparent_typealias(struct ctf_node *node, struct ctf_node *parent)
        case NODE_CLOCK:
                _bt_list_splice_tail(&node->tmp_head, &parent->u.clock.declaration_list);
                break;
+       case NODE_CALLSITE:
+               _bt_list_splice_tail(&node->tmp_head, &parent->u.callsite.declaration_list);
+               break;
        case NODE_VARIANT:
                _bt_list_splice_tail(&node->tmp_head, &parent->u.variant.declaration_list);
                break;
@@ -508,6 +521,7 @@ static int reparent_type_specifier(struct ctf_node *node,
        case NODE_ENV:
        case NODE_TRACE:
        case NODE_CLOCK:
+       case NODE_CALLSITE:
        case NODE_VARIANT:
        case NODE_STRUCT:
        case NODE_TYPEDEF:
@@ -557,6 +571,9 @@ static int reparent_type_specifier_list(struct ctf_node *node,
        case NODE_CLOCK:
                bt_list_add_tail(&node->siblings, &parent->u.clock.declaration_list);
                break;
+       case NODE_CALLSITE:
+               bt_list_add_tail(&node->siblings, &parent->u.callsite.declaration_list);
+               break;
        case NODE_VARIANT:
                bt_list_add_tail(&node->siblings, &parent->u.variant.declaration_list);
                break;
@@ -626,6 +643,7 @@ static int reparent_type_declarator(struct ctf_node *node,
        case NODE_ENV:
        case NODE_TRACE:
        case NODE_CLOCK:
+       case NODE_CALLSITE:
        case NODE_VARIANT:
        case NODE_STRUCT:
        case NODE_TYPEALIAS:
@@ -705,6 +723,13 @@ static int set_parent_node(struct ctf_node *node,
                        return -EPERM;
                }
                break;
+       case NODE_CALLSITE:
+               if (parent->type == NODE_ROOT) {
+                       _bt_list_splice_tail(&node->tmp_head, &parent->u.root.callsite);
+               } else {
+                       return -EPERM;
+               }
+               break;
 
        case NODE_CTF_EXPRESSION:
                return reparent_ctf_expression(node, parent);
@@ -825,6 +850,7 @@ static struct ctf_ast *ctf_ast_alloc(void)
        BT_INIT_LIST_HEAD(&ast->root.u.root.stream);
        BT_INIT_LIST_HEAD(&ast->root.u.root.event);
        BT_INIT_LIST_HEAD(&ast->root.u.root.clock);
+       BT_INIT_LIST_HEAD(&ast->root.u.root.callsite);
        return ast;
 }
 
@@ -913,7 +939,7 @@ void ctf_scanner_free(struct ctf_scanner *scanner)
  */
 %expect 2
 %start file
-%token CHARACTER_CONSTANT_START SQUOTE STRING_LITERAL_START DQUOTE ESCSEQ CHAR_STRING_TOKEN LSBRAC RSBRAC LPAREN RPAREN LBRAC RBRAC RARROW STAR PLUS MINUS LT GT TYPEASSIGN COLON SEMICOLON DOTDOTDOT DOT EQUAL COMMA CONST CHAR DOUBLE ENUM ENV EVENT FLOATING_POINT FLOAT INTEGER INT LONG SHORT SIGNED STREAM STRING STRUCT TRACE CLOCK TYPEALIAS TYPEDEF UNSIGNED VARIANT VOID _BOOL _COMPLEX _IMAGINARY DECIMAL_CONSTANT OCTAL_CONSTANT HEXADECIMAL_CONSTANT TOK_ALIGN
+%token CHARACTER_CONSTANT_START SQUOTE STRING_LITERAL_START DQUOTE ESCSEQ CHAR_STRING_TOKEN LSBRAC RSBRAC LPAREN RPAREN LBRAC RBRAC RARROW STAR PLUS MINUS LT GT TYPEASSIGN COLON SEMICOLON DOTDOTDOT DOT EQUAL COMMA CONST CHAR DOUBLE ENUM ENV EVENT FLOATING_POINT FLOAT INTEGER INT LONG SHORT SIGNED STREAM STRING STRUCT TRACE CALLSITE CLOCK TYPEALIAS TYPEDEF UNSIGNED VARIANT VOID _BOOL _COMPLEX _IMAGINARY DECIMAL_CONSTANT OCTAL_CONSTANT HEXADECIMAL_CONSTANT TOK_ALIGN
 %token <gs> IDENTIFIER ID_TYPE
 %token ERROR
 %union
@@ -935,6 +961,7 @@ void ctf_scanner_free(struct ctf_scanner *scanner)
 %type <n> env_declaration
 %type <n> trace_declaration
 %type <n> clock_declaration
+%type <n> callsite_declaration
 %type <n> integer_declaration_specifiers
 %type <n> declaration_specifiers
 %type <n> alias_declaration_specifiers
@@ -1031,6 +1058,8 @@ keywords:
                {       $$ = yylval.gs;         }
        |       CLOCK
                {       $$ = yylval.gs;         }
+       |       CALLSITE
+               {       $$ = yylval.gs;         }
        |       TOK_ALIGN
                {       $$ = yylval.gs;         }
        ;
@@ -1232,6 +1261,8 @@ declaration:
                {       $$ = $1;        }
        |       clock_declaration
                {       $$ = $1;        }
+       |       callsite_declaration
+               {       $$ = $1;        }
        |       declaration_specifiers TYPEDEF declaration_specifiers type_declarator_list SEMICOLON
                {
                        struct ctf_node *list;
@@ -1399,6 +1430,29 @@ clock_declaration_end:
                {       pop_scope(scanner);     }
        ;
 
+callsite_declaration:
+               CALLSITE callsite_declaration_begin callsite_declaration_end
+               {
+                       $$ = make_node(scanner, NODE_CALLSITE);
+               }
+       |       CALLSITE callsite_declaration_begin ctf_assignment_expression_list callsite_declaration_end
+               {
+                       $$ = make_node(scanner, NODE_CALLSITE);
+                       if (set_parent_node($3, $$))
+                               reparent_error(scanner, "trace_declaration");
+               }
+       ;
+
+callsite_declaration_begin:
+               LBRAC
+               {       push_scope(scanner);    }
+       ;
+
+callsite_declaration_end:
+               RBRAC SEMICOLON
+               {       pop_scope(scanner);     }
+       ;
+
 integer_declaration_specifiers:
                CONST
                {
index af75788aa92dedfd9794ea9b2f80473330e23cca..0e9fe7961845ca9b99c8d7d30d881eb1bb26fc58 100644 (file)
@@ -2433,6 +2433,150 @@ void clock_free(gpointer data)
        g_free(clock);
 }
 
+static
+int ctf_callsite_declaration_visit(FILE *fd, int depth, struct ctf_node *node,
+               struct ctf_callsite *callsite, struct ctf_trace *trace)
+{
+       int ret = 0;
+
+       switch (node->type) {
+       case NODE_CTF_EXPRESSION:
+       {
+               char *left;
+
+               left = concatenate_unary_strings(&node->u.ctf_expression.left);
+               if (!strcmp(left, "name")) {
+                       char *right;
+
+                       if (CTF_CALLSITE_FIELD_IS_SET(callsite, name)) {
+                               fprintf(fd, "[error] %s: name already declared in callsite declaration\n", __func__);
+                               ret = -EPERM;
+                               goto error;
+                       }
+                       right = concatenate_unary_strings(&node->u.ctf_expression.right);
+                       if (!right) {
+                               fprintf(fd, "[error] %s: unexpected unary expression for callsite name\n", __func__);
+                               ret = -EINVAL;
+                               goto error;
+                       }
+                       callsite->name = g_quark_from_string(right);
+                       g_free(right);
+                       CTF_CALLSITE_SET_FIELD(callsite, name);
+               } else if (!strcmp(left, "func")) {
+                       char *right;
+
+                       if (CTF_CALLSITE_FIELD_IS_SET(callsite, func)) {
+                               fprintf(fd, "[error] %s: func already declared in callsite declaration\n", __func__);
+                               ret = -EPERM;
+                               goto error;
+                       }
+                       right = concatenate_unary_strings(&node->u.ctf_expression.right);
+                       if (!right) {
+                               fprintf(fd, "[error] %s: unexpected unary expression for callsite func\n", __func__);
+                               ret = -EINVAL;
+                               goto error;
+                       }
+                       callsite->func = right;
+                       CTF_CALLSITE_SET_FIELD(callsite, func);
+               } else if (!strcmp(left, "file")) {
+                       char *right;
+
+                       if (CTF_CALLSITE_FIELD_IS_SET(callsite, file)) {
+                               fprintf(fd, "[error] %s: file already declared in callsite declaration\n", __func__);
+                               ret = -EPERM;
+                               goto error;
+                       }
+                       right = concatenate_unary_strings(&node->u.ctf_expression.right);
+                       if (!right) {
+                               fprintf(fd, "[error] %s: unexpected unary expression for callsite file\n", __func__);
+                               ret = -EINVAL;
+                               goto error;
+                       }
+                       callsite->file = right;
+                       CTF_CALLSITE_SET_FIELD(callsite, file);
+               } else if (!strcmp(left, "line")) {
+                       if (CTF_CALLSITE_FIELD_IS_SET(callsite, line)) {
+                               fprintf(fd, "[error] %s: line already declared in callsite declaration\n", __func__);
+                               ret = -EPERM;
+                               goto error;
+                       }
+                       ret = get_unary_unsigned(&node->u.ctf_expression.right, &callsite->line);
+                       if (ret) {
+                               fprintf(fd, "[error] %s: unexpected unary expression for callsite line\n", __func__);
+                               ret = -EINVAL;
+                               goto error;
+                       }
+                       CTF_CALLSITE_SET_FIELD(callsite, line);
+               } else {
+                       fprintf(fd, "[warning] %s: attribute \"%s\" is unknown in callsite declaration.\n", __func__, left);
+               }
+
+error:
+               g_free(left);
+               break;
+       }
+       default:
+               return -EPERM;
+       /* TODO: declaration specifier should be added. */
+       }
+
+       return ret;
+}
+
+static
+int ctf_callsite_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_trace *trace)
+{
+       int ret = 0;
+       struct ctf_node *iter;
+       struct ctf_callsite *callsite;
+
+       callsite = g_new0(struct ctf_callsite, 1);
+       bt_list_for_each_entry(iter, &node->u.callsite.declaration_list, siblings) {
+               ret = ctf_callsite_declaration_visit(fd, depth + 1, iter, callsite, trace);
+               if (ret)
+                       goto error;
+       }
+       if (!CTF_CALLSITE_FIELD_IS_SET(callsite, name)) {
+               ret = -EPERM;
+               fprintf(fd, "[error] %s: missing name field in callsite declaration\n", __func__);
+               goto error;
+       }
+       if (!CTF_CALLSITE_FIELD_IS_SET(callsite, func)) {
+               ret = -EPERM;
+               fprintf(fd, "[error] %s: missing func field in callsite declaration\n", __func__);
+               goto error;
+       }
+       if (!CTF_CALLSITE_FIELD_IS_SET(callsite, file)) {
+               ret = -EPERM;
+               fprintf(fd, "[error] %s: missing file field in callsite declaration\n", __func__);
+               goto error;
+       }
+       if (!CTF_CALLSITE_FIELD_IS_SET(callsite, line)) {
+               ret = -EPERM;
+               fprintf(fd, "[error] %s: missing line field in callsite declaration\n", __func__);
+               goto error;
+       }
+
+       g_hash_table_insert(trace->callsites, (gpointer) (unsigned long) callsite->name, callsite);
+       return 0;
+
+error:
+       g_free(callsite->func);
+       g_free(callsite->file);
+       g_free(callsite);
+       return ret;
+}
+
+static
+void callsite_free(gpointer data)
+{
+       struct ctf_callsite *callsite = data;
+
+       g_free(callsite->func);
+       g_free(callsite->file);
+       g_free(callsite);
+}
+
 static
 int ctf_env_declaration_visit(FILE *fd, int depth, struct ctf_node *node,
                struct ctf_trace *trace)
@@ -2665,6 +2809,8 @@ int ctf_visitor_construct_metadata(FILE *fd, int depth, struct ctf_node *node,
        trace->byte_order = byte_order;
        trace->clocks = g_hash_table_new_full(g_direct_hash, g_direct_equal,
                                NULL, clock_free);
+       trace->callsites = g_hash_table_new_full(g_direct_hash, g_direct_equal,
+                               NULL, callsite_free);
 
 retry:
        trace->root_declaration_scope = new_declaration_scope(NULL);
@@ -2714,6 +2860,14 @@ retry:
                                goto error;
                        }
                }
+               bt_list_for_each_entry(iter, &node->u.root.callsite, siblings) {
+                       ret = ctf_callsite_visit(fd, depth + 1, iter,
+                                             trace);
+                       if (ret) {
+                               fprintf(fd, "[error] %s: callsite declaration error\n", __func__);
+                               goto error;
+                       }
+               }
                if (!trace->streams) {
                        fprintf(fd, "[error] %s: missing trace declaration\n", __func__);
                        ret = -EINVAL;
@@ -2755,6 +2909,7 @@ retry:
 
 error:
        free_declaration_scope(trace->root_declaration_scope);
+       g_hash_table_destroy(trace->callsites);
        g_hash_table_destroy(trace->clocks);
        return ret;
 }
index 766ce42f1aa16930deecddbe1c1d81cb110595ea..403adf82cabc8267aa09458fbd195173894a1e55 100644 (file)
@@ -211,6 +211,12 @@ int ctf_visitor_parent_links(FILE *fd, int depth, struct ctf_node *node)
                        if (ret)
                                return ret;
                }
+               bt_list_for_each_entry(iter, &node->u.root.callsite, siblings) {
+                       iter->parent = node;
+                       ret = ctf_visitor_parent_links(fd, depth + 1, iter);
+                       if (ret)
+                               return ret;
+               }
                break;
 
        case NODE_EVENT:
@@ -253,6 +259,14 @@ int ctf_visitor_parent_links(FILE *fd, int depth, struct ctf_node *node)
                                return ret;
                }
                break;
+       case NODE_CALLSITE:
+               bt_list_for_each_entry(iter, &node->u.callsite.declaration_list, siblings) {
+                       iter->parent = node;
+                       ret = ctf_visitor_parent_links(fd, depth + 1, iter);
+                       if (ret)
+                               return ret;
+               }
+               break;
 
        case NODE_CTF_EXPRESSION:
                depth++;
index 3db7fd7751eaa29672de85c317db11384b5ac030..1af74c42a8db04577d47a4d35c28c5509f9195f0 100644 (file)
@@ -110,6 +110,7 @@ int ctf_visitor_unary_expression(FILE *fd, int depth, struct ctf_node *node)
        case NODE_ENV:
        case NODE_TRACE:
        case NODE_CLOCK:
+       case NODE_CALLSITE:
        case NODE_TYPEDEF:
        case NODE_TYPEALIAS_TARGET:
        case NODE_TYPEALIAS_ALIAS:
@@ -214,6 +215,7 @@ int ctf_visitor_type_specifier_list(FILE *fd, int depth, struct ctf_node *node)
        case NODE_ENV:
        case NODE_TRACE:
        case NODE_CLOCK:
+       case NODE_CALLSITE:
        case NODE_UNARY_EXPRESSION:
        case NODE_TYPEALIAS:
        case NODE_TYPE_SPECIFIER:
@@ -255,6 +257,7 @@ int ctf_visitor_type_specifier(FILE *fd, int depth, struct ctf_node *node)
        case NODE_ENV:
        case NODE_TRACE:
        case NODE_CLOCK:
+       case NODE_CALLSITE:
        case NODE_UNARY_EXPRESSION:
        case NODE_TYPEALIAS:
        case NODE_TYPE_SPECIFIER:
@@ -337,6 +340,7 @@ int ctf_visitor_type_declarator(FILE *fd, int depth, struct ctf_node *node)
        case NODE_ENV:
        case NODE_TRACE:
        case NODE_CLOCK:
+       case NODE_CALLSITE:
        case NODE_CTF_EXPRESSION:
        case NODE_UNARY_EXPRESSION:
        case NODE_TYPEALIAS:
@@ -516,7 +520,20 @@ int _ctf_visitor_semantic_check(FILE *fd, int depth, struct ctf_node *node)
                                return ret;
                }
                break;
+       case NODE_CALLSITE:
+               switch (node->parent->type) {
+               case NODE_ROOT:
+                       break;                  /* OK */
+               default:
+                       goto errinval;
+               }
 
+               bt_list_for_each_entry(iter, &node->u.callsite.declaration_list, siblings) {
+                       ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
+                       if (ret)
+                               return ret;
+               }
+               break;
 
        case NODE_CTF_EXPRESSION:
                switch (node->parent->type) {
@@ -526,6 +543,7 @@ int _ctf_visitor_semantic_check(FILE *fd, int depth, struct ctf_node *node)
                case NODE_ENV:
                case NODE_TRACE:
                case NODE_CLOCK:
+               case NODE_CALLSITE:
                case NODE_FLOATING_POINT:
                case NODE_INTEGER:
                case NODE_STRING:
@@ -593,6 +611,7 @@ int _ctf_visitor_semantic_check(FILE *fd, int depth, struct ctf_node *node)
                case NODE_ENUMERATOR:
                case NODE_ENUM:
                case NODE_CLOCK:
+               case NODE_CALLSITE:
                case NODE_ENV:
                default:
                        goto errinval;
@@ -699,6 +718,7 @@ int _ctf_visitor_semantic_check(FILE *fd, int depth, struct ctf_node *node)
                case NODE_ENUMERATOR:
                case NODE_ENUM:
                case NODE_CLOCK:
+               case NODE_CALLSITE:
                case NODE_ENV:
                default:
                        goto errinval;
index 428a89560e9baa1bf0aa25ff881462609c8af851..437748cab323f5cedaf9fc3a530e8bf2b4bd5772 100644 (file)
@@ -443,6 +443,17 @@ int ctf_visitor_print_xml(FILE *fd, int depth, struct ctf_node *node)
                print_tabs(fd, depth);
                fprintf(fd, "</clock>\n");
                break;
+       case NODE_CALLSITE:
+               print_tabs(fd, depth);
+               fprintf(fd, "<callsite>\n");
+               bt_list_for_each_entry(iter, &node->u.callsite.declaration_list, siblings) {
+                       ret = ctf_visitor_print_xml(fd, depth + 1, iter);
+                       if (ret)
+                               return ret;
+               }
+               print_tabs(fd, depth);
+               fprintf(fd, "</callsite>\n");
+               break;
 
 
        case NODE_CTF_EXPRESSION:
index b3d51ef35d6778c1e704d74b9912032e68535643..3200d65157201df29173fb3cc96bb7b8e4a8fc30 100644 (file)
@@ -63,6 +63,7 @@ extern int opt_all_field_names,
        opt_trace_default_fields,
        opt_loglevel_field,
        opt_emf_field,
+       opt_callsite_field,
        opt_delta_field,
        opt_clock_cycles,
        opt_clock_seconds,
index 3176bbd4d46ec48cb82ce997dfb4644c5ce7c6ee..137e3b58652075fcf26f48e48ded13bbd55fc12d 100644 (file)
@@ -32,6 +32,7 @@ struct ctf_trace;
 struct ctf_stream_declaration;
 struct ctf_event_declaration;
 struct ctf_clock;
+struct ctf_callsite;
 
 struct ctf_stream_definition {
        struct ctf_stream_declaration *stream_class;
@@ -101,6 +102,33 @@ struct ctf_clock {
        } field_mask;
 };
 
+#define CTF_CALLSITE_SET_FIELD(ctf_callsite, field)                    \
+       do {                                                            \
+               (ctf_callsite)->field_mask |= CTF_CALLSITE_ ## field;   \
+       } while (0)
+
+#define CTF_CALLSITE_FIELD_IS_SET(ctf_callsite, field)                 \
+               ((ctf_callsite)->field_mask & CTF_CALLSITE_ ## field)
+
+#define CTF_CALLSITE_GET_FIELD(ctf_callsite, field)                    \
+       ({                                                              \
+               assert(CTF_CALLSITE_FIELD_IS_SET(ctf_callsite, field)); \
+               (ctf_callsite)->(field);                                \
+       })
+
+struct ctf_callsite {
+       GQuark name;            /* event name associated with callsite */
+       char *func;
+       char *file;
+       uint64_t line;
+       enum {                                  /* Fields populated mask */
+               CTF_CALLSITE_name       =       (1U << 0),
+               CTF_CALLSITE_func       =       (1U << 1),
+               CTF_CALLSITE_file       =       (1U << 2),
+               CTF_CALLSITE_line       =       (1U << 3),
+       } field_mask;
+};
+
 #define CTF_TRACE_SET_FIELD(ctf_trace, field)                          \
        do {                                                            \
                (ctf_trace)->field_mask |= CTF_TRACE_ ## field;         \
@@ -141,6 +169,7 @@ struct ctf_trace {
        GPtrArray *streams;                     /* Array of struct ctf_stream_declaration pointers */
        struct ctf_stream_definition *metadata;
        GHashTable *clocks;
+       GHashTable *callsites;
        struct ctf_clock *single_clock;         /* currently supports only one clock */
        struct trace_collection *collection;    /* Container of this trace */
        GPtrArray *event_declarations;          /* Array of all the struct bt_ctf_event_decl */
This page took 0.035255 seconds and 4 git commands to generate.