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 API for initializing the trace provider for a process. 7 // 8 9 #pragma once 10 11 #include <zircon/compiler.h> 12 #include <zircon/types.h> 13 14 #include <lib/async/dispatcher.h> 15 16 __BEGIN_CDECLS 17 18 // The format of fifo packets for messages passed between the trace manager 19 // and trace providers. 20 typedef struct trace_provider_packet { 21 // One of TRACE_PROVIDER_*. 22 uint16_t request; 23 24 // For alignment and future concerns, must be zero. 25 uint16_t reserved; 26 27 // Optional data for the request. 28 // The contents depend on the request. 29 // If unused they must be passed as zero. 30 uint32_t data32; 31 uint64_t data64; 32 } trace_provider_packet_t; 33 34 // The protocol version we are using. 35 // This is non-zero to catch initialization bugs. 36 #define TRACE_PROVIDER_FIFO_PROTOCOL_VERSION 1 37 38 // Provider->Manager 39 // Zero is reserved to catch initialization bugs. 40 41 // Indicate the provider successfully started. 42 // |data32| is TRACE_PROVIDER_FIFO_PROTOCOL_VERSION 43 // |data64| is unused (must be zero). 44 #define TRACE_PROVIDER_STARTED (0x1) 45 46 // Provider->Manager 47 // A buffer is full and needs to be saved (streaming mode only). 48 // |data32| is the "wrapped count", which is a count of the number of times 49 // a buffer has filled. 50 // |data64| is current offset in the durable buffer 51 #define TRACE_PROVIDER_SAVE_BUFFER (0x2) 52 53 // Temporary to ease soft-roll into garnet. 54 // Can be removed when garnet side lands. 55 #define TRACE_PROVIDER_BUFFER_OVERFLOW (0x2) 56 57 // Next Provider->Manager packet = 0x3 58 59 // Manager->Provider 60 // A buffer has been saved (streaminng mode only). 61 // |data32| is the "wrapped count", which is a count of the number of times 62 // a buffer has filled. 63 // |data64| is unused (must be zero). 64 #define TRACE_PROVIDER_BUFFER_SAVED (0x100) 65 66 // Next Manager->Provider packet = 0x101 67 68 // End fifo packet descriptions. 69 70 // Represents a trace provider. 71 typedef struct trace_provider trace_provider_t; 72 73 // Creates a trace provider associated with the specified async dispatcher 74 // and registers it with the tracing system. 75 // 76 // The trace provider will start and stop the trace engine in response to requests 77 // from the tracing system. 78 // 79 // |to_service| is the channel to use to connect to the trace manager. 80 // It is consumed regardless of success/failure. 81 // 82 // |dispatcher| is the asynchronous dispatcher which the trace provider and trace 83 // engine will use for dispatch. This must outlive the trace provider instance. 84 // 85 // |name| is the name of the trace provider and is used for diagnostic 86 // purposes. The maximum supported length is 100 characters. 87 // 88 // Returns the trace provider, or null if creation failed. 89 // 90 // TODO(ZX-1036): Currently this connects to the trace manager service. 91 // Switch to passively exporting the trace provider via the "hub" through 92 // the process's exported directory once that stuff is implemented. We'll 93 // probably need to pass some extra parameters to the trace provider then. 94 trace_provider_t* trace_provider_create_with_name_etc( 95 zx_handle_t to_service, async_dispatcher_t* dispatcher, const char* name); 96 97 // Wrapper around trace_provider_create_with_name for backward compatibility. 98 // TODO(DX-422): Update all providers to use create_with_name, then change this 99 // to also take a name, then update all providers to call this one, and then 100 // delete trace_provider_create_with_name. 101 trace_provider_t* trace_provider_create_etc( 102 zx_handle_t to_service, async_dispatcher_t* dispatcher); 103 104 // Same as trace_provider_create_with_name except does not return until the 105 // provider is registered with the trace manager. 106 // On return, if !NULL, |*out_already_started| is true if the trace manager has 107 // already started tracing, which is a hint to the provider to wait for the 108 // Start() message before continuing if it wishes to not drop trace records 109 // before Start() is received. 110 trace_provider_t* trace_provider_create_synchronously_etc( 111 zx_handle_t to_service, async_dispatcher_t* dispatcher, const char* name, 112 bool* out_already_started); 113 114 // Wrappers on the above functions that use fdio. 115 trace_provider_t* trace_provider_create_with_name_fdio( 116 async_dispatcher_t* dispatcher, const char* name); 117 trace_provider_t* trace_provider_create_with_fdio( 118 async_dispatcher_t* dispatcher); 119 trace_provider_t* trace_provider_create_synchronously_with_fdio( 120 async_dispatcher_t* dispatcher, const char* name, 121 bool* out_already_started); 122 123 // Compatibility wrappers. 124 // TODO(PT-63): Remove these (and the _etc suffixes on the above routines) 125 // when all clients are updated. 126 trace_provider_t* trace_provider_create_with_name( 127 async_dispatcher_t* dispatcher, const char* name); 128 trace_provider_t* trace_provider_create(async_dispatcher_t* dispatcher); 129 trace_provider_t* trace_provider_create_synchronously( 130 async_dispatcher_t* dispatcher, const char* name, 131 bool* out_already_started); 132 133 // Destroys the trace provider. 134 void trace_provider_destroy(trace_provider_t* provider); 135 136 __END_CDECLS 137 138 #ifdef __cplusplus 139 140 #include <fbl/unique_ptr.h> 141 #include <lib/zx/channel.h> 142 143 namespace trace { 144 145 // Convenience RAII wrapper for creating and destroying a trace provider. 146 // TODO(PT-63): Remove Etc suffix when all clients are updated. 147 class TraceProviderEtc { 148 public: 149 // Create a trace provider synchronously, and return an indicator of 150 // whether tracing has started already in |*out_already_started|. 151 // Returns a boolean indicating success. 152 // This is done with a factory function because it's more complex than 153 // the basic constructor. CreateSynchronously(zx::channel to_service,async_dispatcher_t * dispatcher,const char * name,fbl::unique_ptr<TraceProviderEtc> * out_provider,bool * out_already_started)154 static bool CreateSynchronously( 155 zx::channel to_service, 156 async_dispatcher_t* dispatcher, 157 const char* name, 158 fbl::unique_ptr<TraceProviderEtc>* out_provider, 159 bool* out_already_started) { 160 auto provider = trace_provider_create_synchronously_etc( 161 to_service.release(), dispatcher, name, out_already_started); 162 if (!provider) 163 return false; 164 *out_provider = fbl::unique_ptr<TraceProviderEtc>( 165 new TraceProviderEtc(provider)); 166 return true; 167 } 168 169 // Creates a trace provider. TraceProviderEtc(zx::channel to_service,async_dispatcher_t * dispatcher)170 TraceProviderEtc(zx::channel to_service, async_dispatcher_t* dispatcher) 171 : provider_(trace_provider_create_etc(to_service.release(), 172 dispatcher)) {} 173 174 // Creates a trace provider. TraceProviderEtc(zx::channel to_service,async_dispatcher_t * dispatcher,const char * name)175 TraceProviderEtc(zx::channel to_service, async_dispatcher_t* dispatcher, 176 const char* name) 177 : provider_(trace_provider_create_with_name_etc(to_service.release(), 178 dispatcher, name)) {} 179 180 // Destroys a trace provider. ~TraceProviderEtc()181 ~TraceProviderEtc() { 182 if (provider_) 183 trace_provider_destroy(provider_); 184 } 185 186 // Returns true if the trace provider was created successfully. is_valid()187 bool is_valid() const { 188 return provider_ != nullptr; 189 } 190 191 protected: TraceProviderEtc(trace_provider_t * provider)192 explicit TraceProviderEtc(trace_provider_t* provider) 193 : provider_(provider) {} 194 195 private: 196 trace_provider_t* const provider_; 197 }; 198 199 class TraceProviderWithFdio : public TraceProviderEtc { 200 public: CreateSynchronously(async_dispatcher_t * dispatcher,const char * name,fbl::unique_ptr<TraceProviderWithFdio> * out_provider,bool * out_already_started)201 static bool CreateSynchronously( 202 async_dispatcher_t* dispatcher, 203 const char* name, 204 fbl::unique_ptr<TraceProviderWithFdio>* out_provider, 205 bool* out_already_started) { 206 auto provider = trace_provider_create_synchronously_with_fdio( 207 dispatcher, name, out_already_started); 208 if (!provider) 209 return false; 210 *out_provider = fbl::unique_ptr<TraceProviderWithFdio>( 211 new TraceProviderWithFdio(provider)); 212 return true; 213 } 214 215 // Creates a trace provider. TraceProviderWithFdio(async_dispatcher_t * dispatcher)216 explicit TraceProviderWithFdio(async_dispatcher_t* dispatcher) 217 : TraceProviderWithFdio( 218 trace_provider_create_with_fdio(dispatcher)) {} 219 220 // Creates a trace provider. TraceProviderWithFdio(async_dispatcher_t * dispatcher,const char * name)221 explicit TraceProviderWithFdio(async_dispatcher_t* dispatcher, 222 const char* name) 223 : TraceProviderWithFdio( 224 trace_provider_create_with_name_fdio(dispatcher, name)) {} 225 226 private: TraceProviderWithFdio(trace_provider_t * provider)227 explicit TraceProviderWithFdio(trace_provider_t* provider) 228 : TraceProviderEtc(provider) {} 229 }; 230 231 // Compatibility wrapper. 232 // TODO(PT-63): Delete (and remove _etc from above version) when all clients 233 // are updated. 234 using TraceProvider = TraceProviderWithFdio; 235 236 } // namespace trace 237 238 #endif // __cplusplus 239