Shared library ABI for ScatteredHeapBuffer
So that clients of the shared library can serialize protobuf messages
into heap memory using the same interface for serializing protobuf
tracing data.
This is useful mostly for:
* Tests, to specify tracing session configuration.
* To serialize tracks in the track event API (future CLs).
Bug: 184929776
Change-Id: I4cbb37f629aec531f4b82a08ebbd7fe4ff34c448
diff --git a/include/perfetto/public/abi/heap_buffer.h b/include/perfetto/public/abi/heap_buffer.h
new file mode 100644
index 0000000..811ed0b
--- /dev/null
+++ b/include/perfetto/public/abi/heap_buffer.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_PUBLIC_ABI_HEAP_BUFFER_H_
+#define INCLUDE_PERFETTO_PUBLIC_ABI_HEAP_BUFFER_H_
+
+#include "perfetto/public/abi/stream_writer_abi.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// A PerfettoHeapBuffer can be used to serialize protobuf data using the
+// PerfettoStreamWriter interface. Stores data on heap allocated buffers, which
+// can be read back with PerfettoHeapBufferCopyContent().
+
+struct PerfettoHeapBuffer;
+
+// Creates a PerfettoHeapBuffer. Takes a pointer to an (uninitialized)
+// PerfettoStreamWriter (owned by the caller). The stream writer can be user
+// later to serialize protobuf data.
+PERFETTO_SDK_EXPORT struct PerfettoHeapBuffer* PerfettoHeapBufferCreate(
+ struct PerfettoStreamWriter*);
+
+// Copies data from the heap buffer to `dst` (up to `size` bytes).
+PERFETTO_SDK_EXPORT void PerfettoHeapBufferCopyInto(
+ struct PerfettoHeapBuffer*,
+ struct PerfettoStreamWriter*,
+ void* dst,
+ size_t size);
+
+// Destroys the heap buffer.
+PERFETTO_SDK_EXPORT void PerfettoHeapBufferDestroy(
+ struct PerfettoHeapBuffer*,
+ struct PerfettoStreamWriter*);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // INCLUDE_PERFETTO_PUBLIC_ABI_HEAP_BUFFER_H_
diff --git a/src/shared_lib/BUILD.gn b/src/shared_lib/BUILD.gn
index 91927df..057b036 100644
--- a/src/shared_lib/BUILD.gn
+++ b/src/shared_lib/BUILD.gn
@@ -15,7 +15,6 @@
shared_library("libperfetto_c") {
deps = [
"../../gn:default_deps",
- "../../include/perfetto/base",
"../../include/perfetto/protozero",
"../../include/perfetto/public:protozero",
"../tracing:client_api",
@@ -23,6 +22,7 @@
]
sources = [
"data_source.cc",
+ "heap_buffer.cc",
"producer.cc",
"stream_writer.cc",
"stream_writer.h",
diff --git a/src/shared_lib/heap_buffer.cc b/src/shared_lib/heap_buffer.cc
new file mode 100644
index 0000000..358dd9f
--- /dev/null
+++ b/src/shared_lib/heap_buffer.cc
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "perfetto/public/abi/heap_buffer.h"
+
+#include "perfetto/protozero/scattered_heap_buffer.h"
+#include "src/shared_lib/stream_writer.h"
+
+struct PerfettoHeapBuffer* PerfettoHeapBufferCreate(
+ struct PerfettoStreamWriter* w) {
+ auto* shb = new protozero::ScatteredHeapBuffer(4096, 4096);
+ auto* sw = new protozero::ScatteredStreamWriter(shb);
+ shb->set_writer(sw);
+
+ w->impl = reinterpret_cast<PerfettoStreamWriterImpl*>(sw);
+ perfetto::UpdateStreamWriter(*sw, w);
+ return reinterpret_cast<PerfettoHeapBuffer*>(shb);
+}
+
+void PerfettoHeapBufferCopyInto(struct PerfettoHeapBuffer* buf,
+ struct PerfettoStreamWriter* w,
+ void* dst,
+ size_t size) {
+ auto* shb = reinterpret_cast<protozero::ScatteredHeapBuffer*>(buf);
+ auto* sw = reinterpret_cast<protozero::ScatteredStreamWriter*>(w->impl);
+ sw->set_write_ptr(w->write_ptr);
+
+ uint8_t* dst_ptr = reinterpret_cast<uint8_t*>(dst);
+ for (const protozero::ScatteredHeapBuffer::Slice& slice : shb->GetSlices()) {
+ if (size == 0) {
+ break;
+ }
+ protozero::ContiguousMemoryRange used_range = slice.GetUsedRange();
+ size_t to_copy = std::min(size, used_range.size());
+ memcpy(dst_ptr, used_range.begin, to_copy);
+ dst_ptr += to_copy;
+ size -= to_copy;
+ }
+}
+
+void PerfettoHeapBufferDestroy(struct PerfettoHeapBuffer* buf,
+ struct PerfettoStreamWriter* w) {
+ auto* shb = reinterpret_cast<protozero::ScatteredHeapBuffer*>(buf);
+ auto* sw = reinterpret_cast<protozero::ScatteredStreamWriter*>(w->impl);
+ delete sw;
+ delete shb;
+}