From 2e5e4017225006884b6ebd9efebb9361cd62c043 Mon Sep 17 00:00:00 2001 From: Joe Onorato Date: Tue, 7 Jun 2022 17:16:08 -0700 Subject: [PATCH] Add top level and per-mutator traces to soong_build - Top-level trace for all soong_build runs - Includes adding Peek() to OncePer because not all soong_build invocations have GenerateBuildActions run. - A trace per mutator invocation Test: m && build/bazel/scripts/print_analysis_metrics.py Change-Id: Ief5c04630484fb38ec7e3757de45c7dc294d3b3c --- android/metrics.go | 17 ++++++++++++----- android/onceper.go | 11 +++++++++++ cmd/soong_build/main.go | 12 ++++++++---- 3 files changed, 31 insertions(+), 9 deletions(-) diff --git a/android/metrics.go b/android/metrics.go index 1580f82b1..ecda0266d 100644 --- a/android/metrics.go +++ b/android/metrics.go @@ -32,8 +32,13 @@ type SoongMetrics struct { Variants int } -func ReadSoongMetrics(config Config) SoongMetrics { - return config.Get(soongMetricsOnceKey).(SoongMetrics) +func readSoongMetrics(config Config) (SoongMetrics, bool) { + soongMetrics, ok := config.Peek(soongMetricsOnceKey) + if ok { + return soongMetrics.(SoongMetrics), true + } else { + return SoongMetrics{}, false + } } func init() { @@ -60,9 +65,11 @@ func (soongMetricsSingleton) GenerateBuildActions(ctx SingletonContext) { func collectMetrics(config Config, eventHandler metrics.EventHandler) *soong_metrics_proto.SoongBuildMetrics { metrics := &soong_metrics_proto.SoongBuildMetrics{} - soongMetrics := ReadSoongMetrics(config) - metrics.Modules = proto.Uint32(uint32(soongMetrics.Modules)) - metrics.Variants = proto.Uint32(uint32(soongMetrics.Variants)) + soongMetrics, ok := readSoongMetrics(config) + if ok { + metrics.Modules = proto.Uint32(uint32(soongMetrics.Modules)) + metrics.Variants = proto.Uint32(uint32(soongMetrics.Variants)) + } memStats := runtime.MemStats{} runtime.ReadMemStats(&memStats) diff --git a/android/onceper.go b/android/onceper.go index 481cdea05..fa415d183 100644 --- a/android/onceper.go +++ b/android/onceper.go @@ -79,6 +79,17 @@ func (once *OncePer) Get(key OnceKey) interface{} { return once.maybeWaitFor(key, v) } +// Peek returns the value previously computed with Once for a given key. If Once has not +// been called for the given key Peek will return ok == false. +func (once *OncePer) Peek(key OnceKey) (interface{}, bool) { + v, ok := once.values.Load(key) + if !ok { + return nil, false + } + + return once.maybeWaitFor(key, v), true +} + // OnceStringSlice is the same as Once, but returns the value cast to a []string func (once *OncePer) OnceStringSlice(key OnceKey, value func() []string) []string { return once.Once(key, func() interface{} { return value() }).([]string) diff --git a/cmd/soong_build/main.go b/cmd/soong_build/main.go index c583a4943..53422cd6c 100644 --- a/cmd/soong_build/main.go +++ b/cmd/soong_build/main.go @@ -220,7 +220,7 @@ func writeDepFile(outputFile string, eventHandler metrics.EventHandler, ninjaDep // doChosenActivity runs Soong for a specific activity, like bp2build, queryview // or the actual Soong build for the build.ninja file. Returns the top level // output file of the specific activity. -func doChosenActivity(configuration android.Config, extraNinjaDeps []string, logDir string) string { +func doChosenActivity(ctx *android.Context, configuration android.Config, extraNinjaDeps []string, logDir string) string { mixedModeBuild := configuration.BazelContext.BazelEnabled() generateBazelWorkspace := bp2buildMarker != "" generateQueryView := bazelQueryViewDir != "" @@ -236,7 +236,6 @@ func doChosenActivity(configuration android.Config, extraNinjaDeps []string, log blueprintArgs := cmdlineArgs - ctx := newContext(configuration) if mixedModeBuild { runMixedModeBuild(configuration, ctx, extraNinjaDeps) } else { @@ -284,7 +283,6 @@ func doChosenActivity(configuration android.Config, extraNinjaDeps []string, log } } - writeMetrics(configuration, *ctx.EventHandler, logDir) return cmdlineArgs.OutFile } @@ -344,7 +342,13 @@ func main() { // change between every CI build, so tracking it would require re-running Soong for every build. logDir := availableEnv["LOG_DIR"] - finalOutputFile := doChosenActivity(configuration, extraNinjaDeps, logDir) + ctx := newContext(configuration) + ctx.EventHandler.Begin("soong_build") + + finalOutputFile := doChosenActivity(ctx, configuration, extraNinjaDeps, logDir) + + ctx.EventHandler.End("soong_build") + writeMetrics(configuration, *ctx.EventHandler, logDir) writeUsedEnvironmentFile(configuration, finalOutputFile) }