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 //
6 // The ABI-stable entry points used by trace instrumentation libraries.
7 //
8 // Trace handlers manage the configuration, lifecycle, and external communication
9 // of the trace engine.  The trace engine binds to a single trace handler for
10 // the duration of a trace.  During the trace, the trace engine invokes methods
11 // on the trace handler to ask about enabled categories and to report relevant
12 // state changes.
13 //
14 // Client code shouldn't be using these APIs directly.
15 // See <trace/event.h> for instrumentation macros.
16 //
17 
18 #pragma once
19 
20 #include <stdbool.h>
21 
22 #include <zircon/compiler.h>
23 #include <zircon/types.h>
24 
25 #include <lib/async/dispatcher.h>
26 #include <trace-engine/instrumentation.h>
27 
28 __BEGIN_CDECLS
29 
30 // Trace handler interface.
31 //
32 // Implementations must supply valid function pointers for each function
33 // defined in the |ops| structure.
34 typedef struct trace_handler_ops trace_handler_ops_t;
35 
36 typedef struct trace_handler {
37     const trace_handler_ops_t* ops;
38 } trace_handler_t;
39 
40 struct trace_handler_ops {
41     // Called by the trace engine to ask whether the specified category is enabled.
42     //
43     // This method may be called frequently so it must be efficiently implemented.
44     // Clients may cache the results while a trace is running; dynamic changes
45     // to the enabled categories may go unnoticed until the next trace.
46     //
47     // |handler| is the trace handler object itself.
48     // |category| is the name of the category.
49     //
50     // Called by instrumentation on any thread.  Must be thread-safe.
51     bool (*is_category_enabled)(trace_handler_t* handler, const char* category);
52 
53     // Called by the trace engine to indicate it has completed startup.
54     void (*trace_started)(trace_handler_t* handler);
55 
56     // Called by the trace engine when tracing has stopped.
57     //
58     // The trace collection status is |ZX_OK| if trace collection was successful.
59     // An error indicates that the trace data may be inaccurate or incomplete.
60     //
61     // |handler| is the trace handler object itself.
62     // |async| is the trace engine's asynchronous dispatcher.
63     // |disposition| is |ZX_OK| if tracing stopped normally, otherwise indicates
64     // that tracing was aborted due to an error.
65     // |buffer_bytes_written| is number of bytes which were written to the trace buffer.
66     //
67     // Called on an asynchronous dispatch thread.
68     void (*trace_stopped)(trace_handler_t* handler, async_dispatcher_t* dispatcher,
69                           zx_status_t disposition, size_t buffer_bytes_written);
70 
71     // Called by the trace engine after an attempt to allocate space
72     // for a new record has failed because the buffer is full.
73     //
74     // Called by instrumentation on any thread.  Must be thread-safe.
75     void (*notify_buffer_full)(trace_handler_t* handler,
76                                uint32_t wrapped_count,
77                                uint64_t durable_data_end);
78 };
79 
80 // Asynchronously starts the trace engine.
81 //
82 // |async| is the asynchronous dispatcher which the trace engine will use for dispatch (borrowed).
83 // |handler| is the trace handler which will handle lifecycle events (borrowed).
84 // |buffer| is the trace buffer into which the trace engine will write trace events (borrowed).
85 // |buffer_num_bytes| is the size of the trace buffer in bytes.
86 //
87 // Returns |ZX_OK| if tracing is ready to go.
88 // Returns |ZX_ERR_BAD_STATE| if tracing is already in progress.
89 // Returns |ZX_ERR_NO_MEMORY| if allocation failed.
90 //
91 // This function is thread-safe.
92 //
93 // NOTE: Asynchronous dispatcher shutdown behavior:
94 //
95 // The trace engine will attempt to stop itself automatically when the
96 // asynchronous dispatcher specified in |async| begins the process of shutting
97 // itself down (usually just prior to the dispatcher's destruction).  However,
98 // the trace engine may fail to come to a complete stop if there remain outstanding
99 // references to the trace context during dispatcher shutdown.  When this happens,
100 // the trace handler will not be notified of trace completion and subsequent calls
101 // to |trace_start_engine()| will return |ZX_ERR_BAD_STATE|.
102 //
103 // For this reason, it is a good idea to call |trace_stop_engine()| and wait
104 // for the handler to receive the |trace_handler_ops.trace_stopped()| callback
105 // prior to shutting down the trace engine's asynchronous dispatcher.
106 //
107 // Better yet, don't shut down the trace engine's asynchronous dispatcher unless
108 // the process is already about to exit.
109 zx_status_t trace_start_engine(async_dispatcher_t* dispatcher,
110                                trace_handler_t* handler,
111                                trace_buffering_mode_t buffering_mode,
112                                void* buffer,
113                                size_t buffer_num_bytes);
114 
115 // Asynchronously stops the trace engine.
116 //
117 // The trace handler's |trace_stopped()| method will be invoked asynchronously
118 // when the trace engine transitions to the |TRACE_STOPPED| states.
119 //
120 // |disposition| is |ZX_OK| if tracing is being stopped normally, otherwise indicates
121 // that tracing is being aborted due to an error.
122 //
123 // Returns |ZX_OK| if the current state is |TRACE_STARTED| or |TRACE_STOPPING|.
124 // Returns |ZX_ERR_BAD_STATE| if current state is |TRACE_STOPPED|.
125 //
126 // This function is thread-safe.
127 zx_status_t trace_stop_engine(zx_status_t disposition);
128 
129 // Asynchronously notifies the engine that buffers up to |wrapped_count|
130 // have been saved.
131 //
132 // Returns |ZX_OK| if the current state is |TRACE_STARTED| or |TRACE_STOPPING|.
133 // Returns |ZX_ERR_BAD_STATE| if current state is |TRACE_STOPPED|.
134 //
135 // This function is thread-safe.
136 zx_status_t trace_engine_mark_buffer_saved(uint32_t wrapped_count,
137                                            uint64_t durable_data_end);
138 
139 __END_CDECLS
140