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
7#include <zircon/assert.h>
8#include <zircon/syscalls.h>
9
10namespace {
11
12struct EventHelper {
13    EventHelper(trace_context_t* context, const char* name_literal)
14        : ticks(zx_ticks_get()) {
15        trace_context_register_current_thread(context, &thread_ref);
16        trace_context_register_string_literal(context, name_literal, &name_ref);
17    }
18
19    trace_ticks_t const ticks;
20    trace_thread_ref_t thread_ref;
21    trace_string_ref_t name_ref;
22};
23
24struct VThreadEventHelper {
25    VThreadEventHelper(trace_context_t* context,
26                       const char* name_literal,
27                       const char* vthread_literal,
28                       trace_vthread_id_t vthread_id)
29        : ticks(zx_ticks_get()) {
30        trace_context_register_vthread(
31            context, ZX_KOID_INVALID, vthread_literal, vthread_id, &thread_ref);
32        trace_context_register_string_literal(context, name_literal, &name_ref);
33    }
34
35    trace_ticks_t const ticks;
36    trace_thread_ref_t thread_ref;
37    trace_string_ref_t name_ref;
38};
39
40} // namespace
41
42void trace_internal_write_instant_event_record_and_release_context(
43    trace_context_t* context,
44    const trace_string_ref_t* category_ref,
45    const char* name_literal,
46    trace_scope_t scope,
47    const trace_arg_t* args, size_t num_args) {
48    EventHelper helper(context, name_literal);
49    trace_context_write_instant_event_record(
50        context, helper.ticks, &helper.thread_ref, category_ref, &helper.name_ref,
51        scope, args, num_args);
52    trace_release_context(context);
53}
54
55void trace_internal_write_counter_event_record_and_release_context(
56    trace_context_t* context,
57    const trace_string_ref_t* category_ref,
58    const char* name_literal,
59    trace_counter_id_t counter_id,
60    const trace_arg_t* args, size_t num_args) {
61    EventHelper helper(context, name_literal);
62    trace_context_write_counter_event_record(
63        context, helper.ticks, &helper.thread_ref, category_ref, &helper.name_ref,
64        counter_id, args, num_args);
65    trace_release_context(context);
66}
67
68void trace_internal_write_duration_begin_event_record_and_release_context(
69    trace_context_t* context,
70    const trace_string_ref_t* category_ref,
71    const char* name_literal,
72    const trace_arg_t* args, size_t num_args) {
73    EventHelper helper(context, name_literal);
74    trace_context_write_duration_begin_event_record(
75        context, helper.ticks, &helper.thread_ref, category_ref, &helper.name_ref,
76        args, num_args);
77    trace_release_context(context);
78}
79
80void trace_internal_write_duration_end_event_record_and_release_context(
81    trace_context_t* context,
82    const trace_string_ref_t* category_ref,
83    const char* name_literal,
84    const trace_arg_t* args, size_t num_args) {
85    EventHelper helper(context, name_literal);
86    trace_context_write_duration_end_event_record(
87        context, helper.ticks, &helper.thread_ref, category_ref, &helper.name_ref,
88        args, num_args);
89    trace_release_context(context);
90}
91
92void trace_internal_write_async_begin_event_record_and_release_context(
93    trace_context_t* context,
94    const trace_string_ref_t* category_ref,
95    const char* name_literal,
96    trace_async_id_t async_id,
97    const trace_arg_t* args, size_t num_args) {
98    EventHelper helper(context, name_literal);
99    trace_context_write_async_begin_event_record(
100        context, helper.ticks, &helper.thread_ref, category_ref, &helper.name_ref,
101        async_id, args, num_args);
102    trace_release_context(context);
103}
104
105void trace_internal_write_async_instant_event_record_and_release_context(
106    trace_context_t* context,
107    const trace_string_ref_t* category_ref,
108    const char* name_literal,
109    trace_async_id_t async_id,
110    const trace_arg_t* args, size_t num_args) {
111    EventHelper helper(context, name_literal);
112    trace_context_write_async_instant_event_record(
113        context, helper.ticks, &helper.thread_ref, category_ref, &helper.name_ref,
114        async_id, args, num_args);
115    trace_release_context(context);
116}
117
118void trace_internal_write_async_end_event_record_and_release_context(
119    trace_context_t* context,
120    const trace_string_ref_t* category_ref,
121    const char* name_literal,
122    trace_async_id_t async_id,
123    const trace_arg_t* args, size_t num_args) {
124    EventHelper helper(context, name_literal);
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
131void 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    const trace_arg_t* args, size_t num_args) {
137    EventHelper helper(context, name_literal);
138    trace_context_write_flow_begin_event_record(
139        context, helper.ticks, &helper.thread_ref, category_ref, &helper.name_ref,
140        flow_id, args, num_args);
141    trace_release_context(context);
142}
143
144void trace_internal_write_flow_step_event_record_and_release_context(
145    trace_context_t* context,
146    const trace_string_ref_t* category_ref,
147    const char* name_literal,
148    trace_flow_id_t flow_id,
149    const trace_arg_t* args, size_t num_args) {
150    EventHelper helper(context, name_literal);
151    trace_context_write_flow_step_event_record(
152        context, helper.ticks, &helper.thread_ref, category_ref, &helper.name_ref,
153        flow_id, args, num_args);
154    trace_release_context(context);
155}
156
157void trace_internal_write_flow_end_event_record_and_release_context(
158    trace_context_t* context,
159    const trace_string_ref_t* category_ref,
160    const char* name_literal,
161    trace_flow_id_t flow_id,
162    const trace_arg_t* args, size_t num_args) {
163    EventHelper helper(context, name_literal);
164    trace_context_write_flow_end_event_record(
165        context, helper.ticks, &helper.thread_ref, category_ref, &helper.name_ref,
166        flow_id, args, num_args);
167    trace_release_context(context);
168}
169
170void trace_internal_write_kernel_object_record_for_handle_and_release_context(
171    trace_context_t* context,
172    zx_handle_t handle,
173    const trace_arg_t* args, size_t num_args) {
174    trace_context_write_kernel_object_record_for_handle(
175        context, handle, args, num_args);
176    trace_release_context(context);
177}
178
179void trace_internal_write_blob_record_and_release_context(
180    trace_context_t* context,
181    trace_blob_type_t type,
182    const char* name_literal,
183    const void* blob, size_t blob_size) {
184    trace_string_ref_t name_ref;
185    trace_context_register_string_literal(context, name_literal, &name_ref);
186    trace_context_write_blob_record(
187        context, type, &name_ref, blob, blob_size);
188    trace_release_context(context);
189}
190
191void trace_internal_write_vthread_duration_begin_event_record_and_release_context(
192    trace_context_t* context,
193    const trace_string_ref_t* category_ref,
194    const char* name_literal,
195    const char* vthread_literal,
196    trace_vthread_id_t vthread_id,
197    const trace_arg_t* args, size_t num_args) {
198    VThreadEventHelper helper(context, name_literal, vthread_literal, vthread_id);
199    trace_context_write_duration_begin_event_record(
200        context, helper.ticks, &helper.thread_ref, category_ref, &helper.name_ref,
201        args, num_args);
202    trace_release_context(context);
203}
204
205void trace_internal_write_vthread_duration_end_event_record_and_release_context(
206    trace_context_t* context,
207    const trace_string_ref_t* category_ref,
208    const char* name_literal,
209    const char* vthread_literal,
210    trace_vthread_id_t vthread_id,
211    const trace_arg_t* args, size_t num_args) {
212    VThreadEventHelper helper(context, name_literal, vthread_literal, vthread_id);
213    trace_context_write_duration_end_event_record(
214        context, helper.ticks, &helper.thread_ref, category_ref, &helper.name_ref,
215        args, num_args);
216    trace_release_context(context);
217}
218
219void trace_internal_write_vthread_flow_begin_event_record_and_release_context(
220    trace_context_t* context,
221    const trace_string_ref_t* category_ref,
222    const char* name_literal,
223    const char* vthread_literal,
224    trace_vthread_id_t vthread_id,
225    trace_flow_id_t flow_id,
226    const trace_arg_t* args, size_t num_args) {
227    VThreadEventHelper helper(context, name_literal, vthread_literal, vthread_id);
228    trace_context_write_flow_begin_event_record(
229        context, helper.ticks, &helper.thread_ref, category_ref, &helper.name_ref,
230        flow_id, args, num_args);
231    trace_release_context(context);
232}
233
234void trace_internal_write_vthread_flow_step_event_record_and_release_context(
235    trace_context_t* context,
236    const trace_string_ref_t* category_ref,
237    const char* name_literal,
238    const char* vthread_literal,
239    trace_vthread_id_t vthread_id,
240    trace_flow_id_t flow_id,
241    const trace_arg_t* args, size_t num_args) {
242    VThreadEventHelper helper(context, name_literal, vthread_literal, vthread_id);
243    trace_context_write_flow_step_event_record(
244        context, helper.ticks, &helper.thread_ref, category_ref, &helper.name_ref,
245        flow_id, args, num_args);
246    trace_release_context(context);
247}
248
249void trace_internal_write_vthread_flow_end_event_record_and_release_context(
250    trace_context_t* context,
251    const trace_string_ref_t* category_ref,
252    const char* name_literal,
253    const char* vthread_literal,
254    trace_vthread_id_t vthread_id,
255    trace_flow_id_t flow_id,
256    const trace_arg_t* args, size_t num_args) {
257    VThreadEventHelper helper(context, name_literal, vthread_literal, vthread_id);
258    trace_context_write_flow_end_event_record(
259        context, helper.ticks, &helper.thread_ref, category_ref, &helper.name_ref,
260        flow_id, args, num_args);
261    trace_release_context(context);
262}
263