1 /* 2 * Copyright (C) 2017 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_EXT_TRACING_CORE_TRACE_WRITER_H_ 18 #define INCLUDE_PERFETTO_EXT_TRACING_CORE_TRACE_WRITER_H_ 19 20 #include <functional> 21 22 #include "perfetto/base/export.h" 23 #include "perfetto/ext/tracing/core/basic_types.h" 24 #include "perfetto/protozero/message_handle.h" 25 #include "perfetto/tracing/trace_writer_base.h" 26 27 namespace perfetto { 28 29 namespace protos { 30 namespace pbzero { 31 class TracePacket; 32 } // namespace pbzero 33 } // namespace protos 34 35 // This is a single-thread write interface that allows to write protobufs 36 // directly into the tracing shared buffer without making any copies. 37 // It takes care of acquiring and releasing chunks from the 38 // SharedMemoryArbiter and splitting protos over chunks. 39 // The idea is that each data source creates one (or more) TraceWriter for each 40 // thread it wants to write from. Each TraceWriter will get its own dedicated 41 // chunk and will write into the shared buffer without any locking most of the 42 // time. Locking will happen only when a chunk is exhausted and a new one is 43 // acquired from the arbiter. 44 45 // TODO: TraceWriter needs to keep the shared memory buffer alive (refcount?). 46 // Otherwise if the shared memory buffer goes away (e.g. the Service crashes) 47 // the TraceWriter will keep writing into unmapped memory. 48 49 class PERFETTO_EXPORT TraceWriter : public TraceWriterBase { 50 public: 51 using TracePacketHandle = 52 protozero::MessageHandle<protos::pbzero::TracePacket>; 53 54 TraceWriter(); 55 ~TraceWriter() override; 56 57 // Returns a handle to the root proto message for the trace. The message will 58 // be finalized either by calling directly handle.Finalize() or by letting the 59 // handle go out of scope. The returned handle can be std::move()'d but cannot 60 // be used after either: (i) the TraceWriter instance is destroyed, (ii) a 61 // subsequence NewTracePacket() call is made on the same TraceWriter instance. 62 TracePacketHandle NewTracePacket() override = 0; 63 64 // Commits the data pending for the current chunk into the shared memory 65 // buffer and sends a CommitDataRequest() to the service. This can be called 66 // only if the handle returned by NewTracePacket() has been destroyed (i.e. we 67 // cannot Flush() while writing a TracePacket). 68 // Note: Flush() also happens implicitly when destroying the TraceWriter. 69 // |callback| is an optional callback. When non-null it will request the 70 // service to ACK the flush and will be invoked after the service has 71 // acknowledged it. The callback might be NEVER INVOKED if the service crashes 72 // or the IPC connection is dropped. The callback should be used only by tests 73 // and best-effort features (logging). 74 // TODO(primiano): right now the |callback| will be called on the IPC thread. 75 // This is fine in the current single-thread scenario, but long-term 76 // trace_writer_impl.cc should be smarter and post it on the right thread. 77 void Flush(std::function<void()> callback = {}) override = 0; 78 79 virtual WriterID writer_id() const = 0; 80 81 // Bytes written since creation. Is not reset when new chunks are acquired. 82 virtual uint64_t written() const override = 0; 83 84 private: 85 TraceWriter(const TraceWriter&) = delete; 86 TraceWriter& operator=(const TraceWriter&) = delete; 87 }; 88 89 } // namespace perfetto 90 91 #endif // INCLUDE_PERFETTO_EXT_TRACING_CORE_TRACE_WRITER_H_ 92