From: Mathieu Desnoyers Date: Tue, 2 Oct 2012 18:47:18 +0000 (-0400) Subject: Add callsite support X-Git-Tag: v1.0.0-rc6~18 X-Git-Url: http://git.efficios.com/?p=babeltrace.git;a=commitdiff_plain;h=f133896d405417ba90ac250d243d4b8e539e98f1 Add callsite support Callsite support has been added to the spec. Signed-off-by: Mathieu Desnoyers --- diff --git a/converter/babeltrace.c b/converter/babeltrace.c index dc8b4a70..099a9fa6 100644 --- a/converter/babeltrace.c +++ b/converter/babeltrace.c @@ -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; diff --git a/formats/ctf-text/ctf-text.c b/formats/ctf-text/ctf-text.c index e23bb9e2..4f46427b 100644 --- a/formats/ctf-text/ctf-text.c +++ b/formats/ctf-text/ctf-text.c @@ -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); diff --git a/formats/ctf/metadata/ctf-ast.h b/formats/ctf/metadata/ctf-ast.h index 8d2e5d77..f3107fd2 100644 --- a/formats/ctf/metadata/ctf-ast.h +++ b/formats/ctf/metadata/ctf-ast.h @@ -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 */ diff --git a/formats/ctf/metadata/ctf-lexer.l b/formats/ctf/metadata/ctf-lexer.l index bedda4ad..a689d4ce 100644 --- a/formats/ctf/metadata/ctf-lexer.l +++ b/formats/ctf/metadata/ctf-lexer.l @@ -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; diff --git a/formats/ctf/metadata/ctf-parser.y b/formats/ctf/metadata/ctf-parser.y index 28b7bebe..7f91365d 100644 --- a/formats/ctf/metadata/ctf-parser.y +++ b/formats/ctf/metadata/ctf-parser.y @@ -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 IDENTIFIER ID_TYPE %token ERROR %union @@ -935,6 +961,7 @@ void ctf_scanner_free(struct ctf_scanner *scanner) %type env_declaration %type trace_declaration %type clock_declaration +%type callsite_declaration %type integer_declaration_specifiers %type declaration_specifiers %type 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 { diff --git a/formats/ctf/metadata/ctf-visitor-generate-io-struct.c b/formats/ctf/metadata/ctf-visitor-generate-io-struct.c index af75788a..0e9fe796 100644 --- a/formats/ctf/metadata/ctf-visitor-generate-io-struct.c +++ b/formats/ctf/metadata/ctf-visitor-generate-io-struct.c @@ -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; } diff --git a/formats/ctf/metadata/ctf-visitor-parent-links.c b/formats/ctf/metadata/ctf-visitor-parent-links.c index 766ce42f..403adf82 100644 --- a/formats/ctf/metadata/ctf-visitor-parent-links.c +++ b/formats/ctf/metadata/ctf-visitor-parent-links.c @@ -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++; diff --git a/formats/ctf/metadata/ctf-visitor-semantic-validator.c b/formats/ctf/metadata/ctf-visitor-semantic-validator.c index 3db7fd77..1af74c42 100644 --- a/formats/ctf/metadata/ctf-visitor-semantic-validator.c +++ b/formats/ctf/metadata/ctf-visitor-semantic-validator.c @@ -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; diff --git a/formats/ctf/metadata/ctf-visitor-xml.c b/formats/ctf/metadata/ctf-visitor-xml.c index 428a8956..437748ca 100644 --- a/formats/ctf/metadata/ctf-visitor-xml.c +++ b/formats/ctf/metadata/ctf-visitor-xml.c @@ -443,6 +443,17 @@ int ctf_visitor_print_xml(FILE *fd, int depth, struct ctf_node *node) print_tabs(fd, depth); fprintf(fd, "\n"); break; + case NODE_CALLSITE: + print_tabs(fd, depth); + fprintf(fd, "\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, "\n"); + break; case NODE_CTF_EXPRESSION: diff --git a/include/babeltrace/babeltrace-internal.h b/include/babeltrace/babeltrace-internal.h index b3d51ef3..3200d651 100644 --- a/include/babeltrace/babeltrace-internal.h +++ b/include/babeltrace/babeltrace-internal.h @@ -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, diff --git a/include/babeltrace/ctf-ir/metadata.h b/include/babeltrace/ctf-ir/metadata.h index 3176bbd4..137e3b58 100644 --- a/include/babeltrace/ctf-ir/metadata.h +++ b/include/babeltrace/ctf-ir/metadata.h @@ -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 */