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