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 // Trace handlers manage the configuration, lifecycle, and external communication
7 // of the trace engine.
8 //
9 // See <trace-engine/handler.h> for the C API and more detailed documentation.
10 //
11 
12 #pragma once
13 
14 #include <trace-engine/handler.h>
15 
16 #ifdef __cplusplus
17 
18 namespace trace {
19 
20 // Implements |trace_handler_t|.
21 // Make sure the trace has fully stopped before destroying the handler object.
22 class TraceHandler : public trace_handler_t {
23 public:
24     TraceHandler();
25     virtual ~TraceHandler();
26 
27     // Called by the trace engine to ask whether the specified category is enabled.
28     //
29     // This method may be called frequently so it must be efficiently implemented.
30     // Clients may cache the results while a trace is running; dynamic changes
31     // to the enabled categories may go unnoticed until the next trace.
32     //
33     // |category| is the name of the category.
34     //
35     // Called by instrumentation on any thread.  Must be thread-safe.
IsCategoryEnabled(const char * category)36     virtual bool IsCategoryEnabled(const char* category) { return true; }
37 
38     // Called by the trace engine to indicate it has completed startup.
TraceStarted()39     virtual void TraceStarted() {}
40 
41     // Called by the trace engine when tracing has stopped.
42     //
43     // The trace collection status is |ZX_OK| if trace collection was successful.
44     // An error indicates that the trace data may be inaccurate or incomplete.
45     //
46     // |async| is the trace engine's asynchronous dispatcher.
47     // |disposition| is |ZX_OK| if tracing stopped normally, otherwise indicates
48     // that tracing was aborted due to an error. If records were dropped (due
49     // to the trace buffer being full) then |disposition| is |ZX_ERR_NO_MEMORY|.
50     // |buffer_bytes_written| is number of bytes which were written to the trace buffer.
51     //
52     // Called on an asynchronous dispatch thread.
TraceStopped(async_dispatcher_t * dispatcher,zx_status_t disposition,size_t buffer_bytes_written)53     virtual void TraceStopped(async_dispatcher_t* dispatcher,
54                               zx_status_t disposition, size_t buffer_bytes_written) {}
55 
56     // Called by the trace engine in streaming mode to indicate a buffer is full.
57     // This is only used in streaming mode where double-buffering is used.
58     // |wrapped_count| is the number of times writing to the buffer has
59     // switched from one buffer to the other.
60     // |durable_data_end| is the offset into the durable buffer when the
61     // buffer filled. It is provided so that TraceManager can save the data
62     // thus far written to the durable buffer.
NotifyBufferFull(uint32_t wrapped_count,uint64_t durable_data_end)63     virtual void NotifyBufferFull(uint32_t wrapped_count, uint64_t durable_data_end) {}
64 
65 private:
66     static bool CallIsCategoryEnabled(trace_handler_t* handler, const char* category);
67     static void CallTraceStarted(trace_handler_t* handler);
68     static void CallTraceStopped(trace_handler_t* handler, async_dispatcher_t* dispatcher,
69                                  zx_status_t disposition, size_t buffer_bytes_written);
70     static void CallNotifyBufferFull(trace_handler_t* handler,
71                                      uint32_t wrapped_count,
72                                      uint64_t durable_data_end);
73 
74     static const trace_handler_ops_t kOps;
75 };
76 
77 } // namespace trace
78 
79 #endif // __cplusplus
80