1 // Copyright 2017 The Fuchsia Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include <trace/event.h>
6 #include <zircon/syscalls.h>
7 
8 namespace {
9 
10 struct EventHelper {
EventHelper__anon557c90cb0111::EventHelper11     EventHelper(trace_context_t* context, const char* name_literal)
12         : ticks(zx_ticks_get()) {
13         trace_context_register_current_thread(context, &thread_ref);
14         trace_context_register_string_literal(context, name_literal, &name_ref);
15     }
16 
17     trace_ticks_t const ticks;
18     trace_thread_ref_t thread_ref;
19     trace_string_ref_t name_ref;
20 };
21 
22 } // namespace
23 
24 // Argument names are temporarily stored in |name_ref.inline_string|.
25 // Convert them to string references.
trace_internal_complete_args(trace_context_t * context,trace_arg_t * args,size_t num_args)26 void trace_internal_complete_args(trace_context_t* context,
27                                   trace_arg_t* args, size_t num_args) {
28     for (size_t i = 0; i < num_args; ++i) {
29         trace_context_register_string_literal(context,
30                                               args[i].name_ref.inline_string,
31                                               &args[i].name_ref);
32     }
33 }
34 
trace_internal_write_instant_event_record_and_release_context(trace_context_t * context,const trace_string_ref_t * category_ref,const char * name_literal,trace_scope_t scope,trace_arg_t * args,size_t num_args)35 void trace_internal_write_instant_event_record_and_release_context(
36     trace_context_t* context,
37     const trace_string_ref_t* category_ref,
38     const char* name_literal,
39     trace_scope_t scope,
40     trace_arg_t* args, size_t num_args) {
41     EventHelper helper(context, name_literal);
42     trace_internal_complete_args(context, args, num_args);
43     trace_context_write_instant_event_record(
44         context, helper.ticks, &helper.thread_ref, category_ref, &helper.name_ref,
45         scope, args, num_args);
46     trace_release_context(context);
47 }
48 
trace_internal_write_counter_event_record_and_release_context(trace_context_t * context,const trace_string_ref_t * category_ref,const char * name_literal,trace_counter_id_t counter_id,trace_arg_t * args,size_t num_args)49 void trace_internal_write_counter_event_record_and_release_context(
50     trace_context_t* context,
51     const trace_string_ref_t* category_ref,
52     const char* name_literal,
53     trace_counter_id_t counter_id,
54     trace_arg_t* args, size_t num_args) {
55     EventHelper helper(context, name_literal);
56     trace_internal_complete_args(context, args, num_args);
57     trace_context_write_counter_event_record(
58         context, helper.ticks, &helper.thread_ref, category_ref, &helper.name_ref,
59         counter_id, args, num_args);
60     trace_release_context(context);
61 }
62 
trace_internal_write_duration_begin_event_record_and_release_context(trace_context_t * context,const trace_string_ref_t * category_ref,const char * name_literal,trace_arg_t * args,size_t num_args)63 void trace_internal_write_duration_begin_event_record_and_release_context(
64     trace_context_t* context,
65     const trace_string_ref_t* category_ref,
66     const char* name_literal,
67     trace_arg_t* args, size_t num_args) {
68     EventHelper helper(context, name_literal);
69     trace_internal_complete_args(context, args, num_args);
70     trace_context_write_duration_begin_event_record(
71         context, helper.ticks, &helper.thread_ref, category_ref, &helper.name_ref,
72         args, num_args);
73     trace_release_context(context);
74 }
75 
trace_internal_write_duration_end_event_record_and_release_context(trace_context_t * context,const trace_string_ref_t * category_ref,const char * name_literal,trace_arg_t * args,size_t num_args)76 void trace_internal_write_duration_end_event_record_and_release_context(
77     trace_context_t* context,
78     const trace_string_ref_t* category_ref,
79     const char* name_literal,
80     trace_arg_t* args, size_t num_args) {
81     EventHelper helper(context, name_literal);
82     trace_internal_complete_args(context, args, num_args);
83     trace_context_write_duration_end_event_record(
84         context, helper.ticks, &helper.thread_ref, category_ref, &helper.name_ref,
85         args, num_args);
86     trace_release_context(context);
87 }
88 
trace_internal_write_async_begin_event_record_and_release_context(trace_context_t * context,const trace_string_ref_t * category_ref,const char * name_literal,trace_async_id_t async_id,trace_arg_t * args,size_t num_args)89 void trace_internal_write_async_begin_event_record_and_release_context(
90     trace_context_t* context,
91     const trace_string_ref_t* category_ref,
92     const char* name_literal,
93     trace_async_id_t async_id,
94     trace_arg_t* args, size_t num_args) {
95     EventHelper helper(context, name_literal);
96     trace_internal_complete_args(context, args, num_args);
97     trace_context_write_async_begin_event_record(
98         context, helper.ticks, &helper.thread_ref, category_ref, &helper.name_ref,
99         async_id, args, num_args);
100     trace_release_context(context);
101 }
102 
trace_internal_write_async_instant_event_record_and_release_context(trace_context_t * context,const trace_string_ref_t * category_ref,const char * name_literal,trace_async_id_t async_id,trace_arg_t * args,size_t num_args)103 void trace_internal_write_async_instant_event_record_and_release_context(
104     trace_context_t* context,
105     const trace_string_ref_t* category_ref,
106     const char* name_literal,
107     trace_async_id_t async_id,
108     trace_arg_t* args, size_t num_args) {
109     EventHelper helper(context, name_literal);
110     trace_internal_complete_args(context, args, num_args);
111     trace_context_write_async_instant_event_record(
112         context, helper.ticks, &helper.thread_ref, category_ref, &helper.name_ref,
113         async_id, args, num_args);
114     trace_release_context(context);
115 }
116 
trace_internal_write_async_end_event_record_and_release_context(trace_context_t * context,const trace_string_ref_t * category_ref,const char * name_literal,trace_async_id_t async_id,trace_arg_t * args,size_t num_args)117 void trace_internal_write_async_end_event_record_and_release_context(
118     trace_context_t* context,
119     const trace_string_ref_t* category_ref,
120     const char* name_literal,
121     trace_async_id_t async_id,
122     trace_arg_t* args, size_t num_args) {
123     EventHelper helper(context, name_literal);
124     trace_internal_complete_args(context, args, num_args);
125     trace_context_write_async_end_event_record(
126         context, helper.ticks, &helper.thread_ref, category_ref, &helper.name_ref,
127         async_id, args, num_args);
128     trace_release_context(context);
129 }
130 
trace_internal_write_flow_begin_event_record_and_release_context(trace_context_t * context,const trace_string_ref_t * category_ref,const char * name_literal,trace_flow_id_t flow_id,trace_arg_t * args,size_t num_args)131 void trace_internal_write_flow_begin_event_record_and_release_context(
132     trace_context_t* context,
133     const trace_string_ref_t* category_ref,
134     const char* name_literal,
135     trace_flow_id_t flow_id,
136     trace_arg_t* args, size_t num_args) {
137     EventHelper helper(context, name_literal);
138     trace_internal_complete_args(context, args, num_args);
139     trace_context_write_flow_begin_event_record(
140         context, helper.ticks, &helper.thread_ref, category_ref, &helper.name_ref,
141         flow_id, args, num_args);
142     trace_release_context(context);
143 }
144 
trace_internal_write_flow_step_event_record_and_release_context(trace_context_t * context,const trace_string_ref_t * category_ref,const char * name_literal,trace_flow_id_t flow_id,trace_arg_t * args,size_t num_args)145 void trace_internal_write_flow_step_event_record_and_release_context(
146     trace_context_t* context,
147     const trace_string_ref_t* category_ref,
148     const char* name_literal,
149     trace_flow_id_t flow_id,
150     trace_arg_t* args, size_t num_args) {
151     EventHelper helper(context, name_literal);
152     trace_internal_complete_args(context, args, num_args);
153     trace_context_write_flow_step_event_record(
154         context, helper.ticks, &helper.thread_ref, category_ref, &helper.name_ref,
155         flow_id, args, num_args);
156     trace_release_context(context);
157 }
158 
trace_internal_write_flow_end_event_record_and_release_context(trace_context_t * context,const trace_string_ref_t * category_ref,const char * name_literal,trace_flow_id_t flow_id,trace_arg_t * args,size_t num_args)159 void trace_internal_write_flow_end_event_record_and_release_context(
160     trace_context_t* context,
161     const trace_string_ref_t* category_ref,
162     const char* name_literal,
163     trace_flow_id_t flow_id,
164     trace_arg_t* args, size_t num_args) {
165     EventHelper helper(context, name_literal);
166     trace_internal_complete_args(context, args, num_args);
167     trace_context_write_flow_end_event_record(
168         context, helper.ticks, &helper.thread_ref, category_ref, &helper.name_ref,
169         flow_id, args, num_args);
170     trace_release_context(context);
171 }
172 
trace_internal_write_kernel_object_record_for_handle_and_release_context(trace_context_t * context,zx_handle_t handle,trace_arg_t * args,size_t num_args)173 void trace_internal_write_kernel_object_record_for_handle_and_release_context(
174     trace_context_t* context,
175     zx_handle_t handle,
176     trace_arg_t* args, size_t num_args) {
177     trace_internal_complete_args(context, args, num_args);
178     trace_context_write_kernel_object_record_for_handle(
179         context, handle, args, num_args);
180     trace_release_context(context);
181 }
182 
trace_internal_write_blob_record_and_release_context(trace_context_t * context,trace_blob_type_t type,const char * name_literal,const void * blob,size_t blob_size)183 void trace_internal_write_blob_record_and_release_context(
184     trace_context_t* context,
185     trace_blob_type_t type,
186     const char* name_literal,
187     const void* blob, size_t blob_size) {
188     trace_string_ref_t name_ref;
189     trace_context_register_string_literal(context, name_literal, &name_ref);
190     trace_context_write_blob_record(
191         context, type, &name_ref, blob, blob_size);
192     trace_release_context(context);
193 }
194