tp: switch track table to be a Python table
Change-Id: Ic40ccc427a5013e251909cf5ef21b81e40a61800
diff --git a/Android.bp b/Android.bp
index 4502a31..6ed4c87 100644
--- a/Android.bp
+++ b/Android.bp
@@ -10101,6 +10101,7 @@
srcs: [
"src/trace_processor/tables/android_tables.py",
"src/trace_processor/tables/metadata_tables.py",
+ "src/trace_processor/tables/track_tables.py",
],
tools: [
"perfetto_src_trace_processor_tables_tables_python_binary",
@@ -10109,6 +10110,7 @@
out: [
"src/trace_processor/tables/android_tables_py.h",
"src/trace_processor/tables/metadata_tables_py.h",
+ "src/trace_processor/tables/track_tables_py.h",
],
}
@@ -10121,6 +10123,7 @@
"python/generators/trace_processor_table/util.py",
"src/trace_processor/tables/android_tables.py",
"src/trace_processor/tables/metadata_tables.py",
+ "src/trace_processor/tables/track_tables.py",
"tools/gen_tp_table_headers.py",
],
main: "tools/gen_tp_table_headers.py",
diff --git a/BUILD b/BUILD
index 1d80406..877f5d9 100644
--- a/BUILD
+++ b/BUILD
@@ -1986,10 +1986,12 @@
srcs = [
"src/trace_processor/tables/android_tables.py",
"src/trace_processor/tables/metadata_tables.py",
+ "src/trace_processor/tables/track_tables.py",
],
outs = [
"src/trace_processor/tables/android_tables_py.h",
"src/trace_processor/tables/metadata_tables_py.h",
+ "src/trace_processor/tables/track_tables_py.h",
],
)
diff --git a/python/generators/trace_processor_table/public.py b/python/generators/trace_processor_table/public.py
index 6b326e8..6d51877 100644
--- a/python/generators/trace_processor_table/public.py
+++ b/python/generators/trace_processor_table/public.py
@@ -124,15 +124,17 @@
class_name: Name of the C++ table class.
sql_name: Name of the table in SQL.
columns: The columns in this table.
- wrapping_sql_view: See |WrappingSqlView|.
tabledoc: Documentation for this table. Can include
documentation overrides for auto-added columns (i.e.
id and type) and aliases added in |wrapping_sql_view|.
+ parent: The parent ("super-class") table for this table.
+ wrapping_sql_view: See |WrappingSqlView|.
"""
class_name: str
sql_name: str
columns: List[Column]
tabledoc: TableDoc
+ parent: Optional['Table'] = None
wrapping_sql_view: Optional[WrappingSqlView] = None
@@ -152,6 +154,11 @@
@dataclass
+class CppDouble(CppColumnType):
+ """Represents the double C++ type."""
+
+
+@dataclass
class CppString(CppColumnType):
"""Represents the StringPool::Id C++ type."""
diff --git a/python/generators/trace_processor_table/serialize.py b/python/generators/trace_processor_table/serialize.py
index 43ca5cd..5b3cb92 100644
--- a/python/generators/trace_processor_table/serialize.py
+++ b/python/generators/trace_processor_table/serialize.py
@@ -56,6 +56,19 @@
return None
return f'{self.name}(std::move(in_{self.name}))'
+ def const_row_ref_getter(self) -> Optional[str]:
+ return f'''ColumnType::{self.name}::type {self.name}() const {{
+ return table_->{self.name}()[row_number_];
+ }}'''
+
+ def row_ref_getter(self) -> Optional[str]:
+ if self.col._is_auto_added_id or self.col._is_auto_added_type:
+ return None
+ return f'''void set_{self.name}(
+ ColumnType::{self.name}::non_optional_type v) {{
+ return mutable_table()->mutable_{self.name}()->Set(row_number_, v);
+ }}'''
+
def flag(self) -> Optional[str]:
if self.col._is_auto_added_id or self.col._is_auto_added_type:
return None
@@ -155,7 +168,8 @@
ColumnSerializer.row_initializer, delimiter=',\n ')
return f'''
struct Row : public macros_internal::RootParentTable::Row {{
- Row({param})
+ Row({param},
+ std::nullptr_t = nullptr)
: macros_internal::RootParentTable::Row(nullptr),
{row_init} {{
type_ = "{self.table.sql_name}";
@@ -164,6 +178,42 @@
}};
'''
+ def const_row_reference_struct(self) -> str:
+ row_ref_getters = self.foreach_col(
+ ColumnSerializer.const_row_ref_getter, delimiter='\n ')
+ return f'''
+ class ConstRowReference : public macros_internal::AbstractConstRowReference<
+ {self.table_name}, RowNumber> {{
+ public:
+ ConstRowReference(const {self.table_name}* table, uint32_t row_number)
+ : AbstractConstRowReference(table, row_number) {{}}
+
+ {row_ref_getters}
+ }};
+ static_assert(std::is_trivially_destructible<ConstRowReference>::value,
+ "Inheritance used without trivial destruction");
+ '''
+
+ def row_reference_struct(self) -> str:
+ row_ref_getters = self.foreach_col(
+ ColumnSerializer.row_ref_getter, delimiter='\n ')
+ return f'''
+ class RowReference : public ConstRowReference {{
+ public:
+ RowReference(const {self.table_name}* table, uint32_t row_number)
+ : ConstRowReference(table, row_number) {{}}
+
+ {row_ref_getters}
+
+ private:
+ {self.table_name}* mutable_table() const {{
+ return const_cast<{self.table_name}*>(table_);
+ }}
+ }};
+ static_assert(std::is_trivially_destructible<RowReference>::value,
+ "Inheritance used without trivial destruction");
+ '''
+
def constructor(self) -> str:
col_init = self.foreach_col(
ColumnSerializer.storage_init, delimiter=',\n ')
@@ -190,11 +240,28 @@
{self.row_struct().strip()}
struct IdAndRow {{
uint32_t row;
+ Id id;
}};
struct ColumnFlag {{
{self.foreach_col(ColumnSerializer.flag)}
}};
+ class RowNumber;
+ class ConstRowReference;
+ class RowReference;
+
+ class RowNumber : public macros_internal::AbstractRowNumber<
+ {self.table_name}, ConstRowReference, RowReference> {{
+ public:
+ explicit RowNumber(uint32_t row_number)
+ : AbstractRowNumber(row_number) {{}}
+ }};
+ static_assert(std::is_trivially_destructible<RowNumber>::value,
+ "Inheritance used without trivial destruction");
+
+ {self.const_row_reference_struct().strip()}
+ {self.row_reference_struct().strip()}
+
{self.constructor().strip()}
~{self.table_name}() override;
@@ -204,12 +271,26 @@
{self.foreach_col(ColumnSerializer.shrink_to_fit)}
}}
+ base::Optional<ConstRowReference> FindById(Id find_id) const {{
+ base::Optional<uint32_t> row = id().IndexOf(find_id);
+ if (!row)
+ return base::nullopt;
+ return ConstRowReference(this, *row);
+ }}
+
+ base::Optional<RowReference> FindById(Id find_id) {{
+ base::Optional<uint32_t> row = id().IndexOf(find_id);
+ if (!row)
+ return base::nullopt;
+ return RowReference(this, *row);
+ }}
+
IdAndRow Insert(const Row& row) {{
uint32_t row_number = row_count();
type_.Append(string_pool_->InternString(row.type()));
{self.foreach_col(ColumnSerializer.append)}
UpdateSelfOverlayAfterInsert();
- return IdAndRow{{row_number}};
+ return IdAndRow{{row_number, Id{{row_number}}}};
}}
{self.foreach_col(ColumnSerializer.accessor)}
diff --git a/src/trace_processor/storage/trace_storage.h b/src/trace_processor/storage/trace_storage.h
index 325f3b0..5790beb 100644
--- a/src/trace_processor/storage/trace_storage.h
+++ b/src/trace_processor/storage/trace_storage.h
@@ -828,7 +828,7 @@
tables::ClockSnapshotTable clock_snapshot_table_{&string_pool_, nullptr};
// Metadata for tracks.
- tables::TrackTable track_table_{&string_pool_, nullptr};
+ tables::TrackTable track_table_{&string_pool_};
tables::ThreadStateTable thread_state_table_{&string_pool_, nullptr};
tables::GpuTrackTable gpu_track_table_{&string_pool_, &track_table_};
tables::ProcessTrackTable process_track_table_{&string_pool_, &track_table_};
diff --git a/src/trace_processor/tables/BUILD.gn b/src/trace_processor/tables/BUILD.gn
index dfa7781..955fbc1 100644
--- a/src/trace_processor/tables/BUILD.gn
+++ b/src/trace_processor/tables/BUILD.gn
@@ -19,6 +19,7 @@
sources = [
"android_tables.py",
"metadata_tables.py",
+ "track_tables.py",
]
generate_docs = true
}
diff --git a/src/trace_processor/tables/profiler_tables.h b/src/trace_processor/tables/profiler_tables.h
index a517101..bc22a9a 100644
--- a/src/trace_processor/tables/profiler_tables.h
+++ b/src/trace_processor/tables/profiler_tables.h
@@ -34,8 +34,6 @@
// @param private_dirty_kb KB of this mapping that are private dirty RSS.
// @param swap_kb KB of this mapping that are in swap.
// @param file_name
-// @param file_name_iid
-// @param path_iid
// @param start_address
// @param module_timestamp
// @param module_debugid
@@ -159,9 +157,7 @@
PERFETTO_TP_TABLE(PERFETTO_TP_STACK_SAMPLE_DEF);
// Samples from the Chromium stack sampler.
-// @param ts timestamp this sample was taken at.
// @param utid thread that was active when the sample was taken.
-// @param callsite_id callstack in active thread at time of sample.
// @tablegroup Callstack profilers
#define PERFETTO_TP_CPU_PROFILE_STACK_SAMPLE_DEF(NAME, PARENT, C) \
NAME(CpuProfileStackSampleTable, "cpu_profile_stack_sample") \
diff --git a/src/trace_processor/tables/track_tables.h b/src/trace_processor/tables/track_tables.h
index ed24ef2..60c515a 100644
--- a/src/trace_processor/tables/track_tables.h
+++ b/src/trace_processor/tables/track_tables.h
@@ -18,23 +18,19 @@
#define SRC_TRACE_PROCESSOR_TABLES_TRACK_TABLES_H_
#include "src/trace_processor/tables/macros.h"
+#include "src/trace_processor/tables/track_tables_py.h"
namespace perfetto {
namespace trace_processor {
namespace tables {
-// @tablegroup Tracks
-// @param source_arg_set_id {@joinable args.arg_set_id}
-// @param parent_id id of a parent track {@joinable track.id}
+// TODO(lalitm): delete this once none of the child classes depends on this.
#define PERFETTO_TP_TRACK_TABLE_DEF(NAME, PARENT, C) \
- NAME(TrackTable, "track") \
- PERFETTO_TP_ROOT_TABLE(PARENT, C) \
+ NAME(TrackTable, "unused") \
C(StringPool::Id, name) \
C(base::Optional<TrackTable::Id>, parent_id) \
C(base::Optional<uint32_t>, source_arg_set_id)
-PERFETTO_TP_TABLE(PERFETTO_TP_TRACK_TABLE_DEF);
-
// @tablegroup Tracks
#define PERFETTO_TP_PROCESS_TRACK_TABLE_DEF(NAME, PARENT, C) \
NAME(ProcessTrackTable, "process_track") \
diff --git a/src/trace_processor/tables/track_tables.py b/src/trace_processor/tables/track_tables.py
new file mode 100644
index 0000000..38555d1
--- /dev/null
+++ b/src/trace_processor/tables/track_tables.py
@@ -0,0 +1,67 @@
+# 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.
+"""Contains tables for tracks."""
+
+from python.generators.trace_processor_table.public import Column as C
+from python.generators.trace_processor_table.public import CppInt64
+from python.generators.trace_processor_table.public import CppOptional
+from python.generators.trace_processor_table.public import CppString
+from python.generators.trace_processor_table.public import Table
+from python.generators.trace_processor_table.public import TableDoc
+from python.generators.trace_processor_table.public import ColumnDoc
+from python.generators.trace_processor_table.public import CppSelfTableId
+from python.generators.trace_processor_table.public import CppUint32
+from src.trace_processor.tables.metadata_tables import THREAD_TABLE
+
+TRACK_TABLE = Table(
+ class_name="TrackTable",
+ sql_name="track",
+ columns=[
+ C("name", CppString()),
+ C("parent_id", CppOptional(CppSelfTableId())),
+ C("source_arg_set_id", CppOptional(CppUint32())),
+ ],
+ tabledoc=TableDoc(
+ doc='''
+ Tracks are a fundamental concept in trace processor and represent a
+ "timeline" for events of the same type and with the same context. See
+ https://perfetto.dev/docs/analysis/trace-processor#tracks for a more
+ detailed explanation, with examples.
+ ''',
+ group='Tracks',
+ columns={
+ 'name':
+ '''
+ Name of the track; can be null for some types of tracks (e.g.
+ thread tracks).
+ ''',
+ 'parent_id':
+ '''
+ The track which is the "parent" of this track. Only non-null
+ for tracks created using Perfetto's track_event API.
+ ''',
+ 'source_arg_set_id':
+ ColumnDoc(
+ doc='''
+ Args for this track which store information about "source"
+ of this track in the trace. For example: whether this
+ track orginated from atrace, Chrome tracepoints etc.
+ ''',
+ joinable='args.arg_set_id'),
+ }))
+
+# Keep this list sorted.
+ALL_TABLES = [
+ TRACK_TABLE,
+]