1 /* 2 * Copyright (C) 2019 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef INCLUDE_PERFETTO_TRACING_TRACE_WRITER_BASE_H_ 18 #define INCLUDE_PERFETTO_TRACING_TRACE_WRITER_BASE_H_ 19 20 #include "perfetto/protozero/message_handle.h" 21 22 namespace perfetto { 23 24 namespace protos { 25 namespace pbzero { 26 class TracePacket; 27 } // namespace pbzero 28 } // namespace protos 29 30 // This is a single-thread write interface that allows to write protobufs 31 // directly into the tracing shared buffer without making any copies. 32 // The idea is that each data source creates one (or more) TraceWriter for each 33 // thread it wants to write from. Each TraceWriter will get its own dedicated 34 // chunk and will write into the shared buffer without any locking most of the 35 // time. 36 37 class TraceWriterBase { 38 public: 39 virtual ~TraceWriterBase(); 40 41 // Creates a new trace packet and returns a handle to a protozero Message that 42 // will write to it. The message will be finalized either by calling directly 43 // handle.Finalize() or by letting the handle go out of scope (the message 44 // should be finalized before a new call to NewTracePacket is made). The 45 // returned handle can be std::move()'d but cannot be used after either: (i) 46 // the TraceWriter instance is destroyed, (ii) a subsequence NewTracePacket() 47 // call is made on the same TraceWriter instance. 48 // 49 // The caller can use protozero::MessageHandle::TakeStreamWriter() to write. 50 // 51 // The caller must call ->Finalize() on the returned trace packet (the handle 52 // destructor will take care of that) or explicitly call FinishTracePacket (if 53 // using TakeStreamWriter) before calling any method on the same TraceWriter 54 // instance. 55 // 56 // The returned packet handle is always valid, but note that, when using 57 // BufferExhaustedPolicy::kDrop and the SMB is exhausted, it may be assigned 58 // a garbage chunk and any trace data written into it will be lost. For more 59 // details on buffer size choices: https://perfetto.dev/docs/concepts/buffers. 60 virtual protozero::MessageHandle<protos::pbzero::TracePacket> 61 NewTracePacket() = 0; 62 63 // Tells the TraceWriterBase that the previous packet started with 64 // NewTracePacket() is finished. 65 // 66 // Calling this is optional: the TraceWriterBase can realize that the previous 67 // packet is finished when the next NewTracePacket() is called. It is still 68 // useful, because the next NewTracePacket may not happen for a while. 69 virtual void FinishTracePacket() = 0; 70 71 // Commits the data pending for the current chunk. This can be called 72 // only if the handle returned by NewTracePacket() has been destroyed (i.e. we 73 // cannot Flush() while writing a TracePacket). 74 // 75 // Note: Flush() also happens implicitly when destroying the TraceWriter. 76 // 77 // |callback| is an optional callback. When non-null it will request the 78 // service to ACK the flush and will be invoked after the service has 79 // acknowledged it. The callback might be NEVER INVOKED if the service crashes 80 // or the IPC connection is dropped. The callback should be used only by tests 81 // and best-effort features (logging). 82 virtual void Flush(std::function<void()> callback = {}) = 0; 83 84 // Bytes written since creation. Not reset when new chunks are acquired. 85 virtual uint64_t written() const = 0; 86 }; 87 88 } // namespace perfetto 89 90 #endif // INCLUDE_PERFETTO_TRACING_TRACE_WRITER_BASE_H_ 91