1*795d594fSAndroid Build Coastguard Worker /* 2*795d594fSAndroid Build Coastguard Worker * Copyright (C) 2021 The Android Open Source Project 3*795d594fSAndroid Build Coastguard Worker * 4*795d594fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*795d594fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*795d594fSAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*795d594fSAndroid Build Coastguard Worker * 8*795d594fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*795d594fSAndroid Build Coastguard Worker * 10*795d594fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*795d594fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*795d594fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*795d594fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*795d594fSAndroid Build Coastguard Worker * limitations under the License. 15*795d594fSAndroid Build Coastguard Worker */ 16*795d594fSAndroid Build Coastguard Worker 17*795d594fSAndroid Build Coastguard Worker #ifndef ART_ODREFRESH_ODR_METRICS_H_ 18*795d594fSAndroid Build Coastguard Worker #define ART_ODREFRESH_ODR_METRICS_H_ 19*795d594fSAndroid Build Coastguard Worker 20*795d594fSAndroid Build Coastguard Worker #include <chrono> 21*795d594fSAndroid Build Coastguard Worker #include <cstdint> 22*795d594fSAndroid Build Coastguard Worker #include <iosfwd> 23*795d594fSAndroid Build Coastguard Worker #include <optional> 24*795d594fSAndroid Build Coastguard Worker #include <string> 25*795d594fSAndroid Build Coastguard Worker 26*795d594fSAndroid Build Coastguard Worker #include "base/macros.h" 27*795d594fSAndroid Build Coastguard Worker #include "exec_utils.h" 28*795d594fSAndroid Build Coastguard Worker #include "odr_metrics_record.h" 29*795d594fSAndroid Build Coastguard Worker 30*795d594fSAndroid Build Coastguard Worker namespace art { 31*795d594fSAndroid Build Coastguard Worker namespace odrefresh { 32*795d594fSAndroid Build Coastguard Worker 33*795d594fSAndroid Build Coastguard Worker class OdrMetrics final { 34*795d594fSAndroid Build Coastguard Worker public: 35*795d594fSAndroid Build Coastguard Worker // Enumeration used to track the latest stage reached running odrefresh. 36*795d594fSAndroid Build Coastguard Worker // 37*795d594fSAndroid Build Coastguard Worker // These values mirror those in OdrefreshReported::Stage in 38*795d594fSAndroid Build Coastguard Worker // frameworks/proto_logging/atoms/art/odrefresh_extension_atoms.proto. 39*795d594fSAndroid Build Coastguard Worker // NB There are gaps between the values in case an additional stages are introduced. 40*795d594fSAndroid Build Coastguard Worker enum class Stage : uint8_t { 41*795d594fSAndroid Build Coastguard Worker kUnknown = 0, 42*795d594fSAndroid Build Coastguard Worker kCheck = 10, 43*795d594fSAndroid Build Coastguard Worker kPreparation = 20, 44*795d594fSAndroid Build Coastguard Worker kPrimaryBootClasspath = 30, 45*795d594fSAndroid Build Coastguard Worker kSecondaryBootClasspath = 40, 46*795d594fSAndroid Build Coastguard Worker kSystemServerClasspath = 50, 47*795d594fSAndroid Build Coastguard Worker kComplete = 60, 48*795d594fSAndroid Build Coastguard Worker }; 49*795d594fSAndroid Build Coastguard Worker 50*795d594fSAndroid Build Coastguard Worker // Enumeration describing the overall status, processing stops on the first error discovered. 51*795d594fSAndroid Build Coastguard Worker // 52*795d594fSAndroid Build Coastguard Worker // These values mirror those in OdrefreshReported::Status in 53*795d594fSAndroid Build Coastguard Worker // frameworks/proto_logging/atoms/art/odrefresh_extension_atoms.proto. 54*795d594fSAndroid Build Coastguard Worker enum class Status : uint8_t { 55*795d594fSAndroid Build Coastguard Worker kUnknown = 0, 56*795d594fSAndroid Build Coastguard Worker kOK = 1, 57*795d594fSAndroid Build Coastguard Worker kNoSpace = 2, 58*795d594fSAndroid Build Coastguard Worker kIoError = 3, 59*795d594fSAndroid Build Coastguard Worker kDex2OatError = 4, 60*795d594fSAndroid Build Coastguard Worker // Value 5 was kTimeLimitExceeded, but has been removed in favour of 61*795d594fSAndroid Build Coastguard Worker // reporting the exit code for Dex2Oat (set to ExecResult::kTimedOut) 62*795d594fSAndroid Build Coastguard Worker kStagingFailed = 6, 63*795d594fSAndroid Build Coastguard Worker kInstallFailed = 7, 64*795d594fSAndroid Build Coastguard Worker // Failed to access the dalvik-cache directory due to lack of permission. 65*795d594fSAndroid Build Coastguard Worker kDalvikCachePermissionDenied = 8, 66*795d594fSAndroid Build Coastguard Worker }; 67*795d594fSAndroid Build Coastguard Worker 68*795d594fSAndroid Build Coastguard Worker // Enumeration describing the cause of compilation (if any) in odrefresh. 69*795d594fSAndroid Build Coastguard Worker // 70*795d594fSAndroid Build Coastguard Worker // These values mirror those in OdrefreshReported::Trigger in 71*795d594fSAndroid Build Coastguard Worker // frameworks/proto_logging/atoms/art/odrefresh_extension_atoms.proto. 72*795d594fSAndroid Build Coastguard Worker enum class Trigger : uint8_t { 73*795d594fSAndroid Build Coastguard Worker kUnknown = 0, 74*795d594fSAndroid Build Coastguard Worker kApexVersionMismatch = 1, 75*795d594fSAndroid Build Coastguard Worker kDexFilesChanged = 2, 76*795d594fSAndroid Build Coastguard Worker kMissingArtifacts = 3, 77*795d594fSAndroid Build Coastguard Worker }; 78*795d594fSAndroid Build Coastguard Worker 79*795d594fSAndroid Build Coastguard Worker // Enumeration describing the type of boot classpath compilation in odrefresh. 80*795d594fSAndroid Build Coastguard Worker // 81*795d594fSAndroid Build Coastguard Worker // These values mirror those in OdrefreshReported::BcpCompilationType in 82*795d594fSAndroid Build Coastguard Worker // frameworks/proto_logging/atoms/art/odrefresh_extension_atoms.proto. 83*795d594fSAndroid Build Coastguard Worker enum class BcpCompilationType : uint8_t { 84*795d594fSAndroid Build Coastguard Worker kUnknown = 0, 85*795d594fSAndroid Build Coastguard Worker // Compiles for both the primary boot image and the mainline extension. 86*795d594fSAndroid Build Coastguard Worker kPrimaryAndMainline = 1, 87*795d594fSAndroid Build Coastguard Worker // Only compiles for the mainline extension. 88*795d594fSAndroid Build Coastguard Worker kMainline = 2, 89*795d594fSAndroid Build Coastguard Worker }; 90*795d594fSAndroid Build Coastguard Worker 91*795d594fSAndroid Build Coastguard Worker explicit OdrMetrics(const std::string& cache_directory, 92*795d594fSAndroid Build Coastguard Worker const std::string& metrics_file = kOdrefreshMetricsFile); 93*795d594fSAndroid Build Coastguard Worker ~OdrMetrics(); 94*795d594fSAndroid Build Coastguard Worker 95*795d594fSAndroid Build Coastguard Worker // Enables/disables metrics writing. SetEnabled(bool value)96*795d594fSAndroid Build Coastguard Worker void SetEnabled(bool value) { enabled_ = value; } 97*795d594fSAndroid Build Coastguard Worker 98*795d594fSAndroid Build Coastguard Worker // Gets the ART APEX that metrics are being collected on behalf of. GetArtApexVersion()99*795d594fSAndroid Build Coastguard Worker int64_t GetArtApexVersion() const { return art_apex_version_; } 100*795d594fSAndroid Build Coastguard Worker 101*795d594fSAndroid Build Coastguard Worker // Sets the ART APEX that metrics are being collected on behalf of. SetArtApexVersion(int64_t version)102*795d594fSAndroid Build Coastguard Worker void SetArtApexVersion(int64_t version) { art_apex_version_ = version; } 103*795d594fSAndroid Build Coastguard Worker 104*795d594fSAndroid Build Coastguard Worker // Gets the ART APEX last update time in milliseconds. GetArtApexLastUpdateMillis()105*795d594fSAndroid Build Coastguard Worker int64_t GetArtApexLastUpdateMillis() const { return art_apex_last_update_millis_; } 106*795d594fSAndroid Build Coastguard Worker 107*795d594fSAndroid Build Coastguard Worker // Sets the ART APEX last update time in milliseconds. SetArtApexLastUpdateMillis(int64_t last_update_millis)108*795d594fSAndroid Build Coastguard Worker void SetArtApexLastUpdateMillis(int64_t last_update_millis) { 109*795d594fSAndroid Build Coastguard Worker art_apex_last_update_millis_ = last_update_millis; 110*795d594fSAndroid Build Coastguard Worker } 111*795d594fSAndroid Build Coastguard Worker 112*795d594fSAndroid Build Coastguard Worker // Gets the trigger for metrics collection. The trigger is the reason why odrefresh considers 113*795d594fSAndroid Build Coastguard Worker // compilation necessary. GetTrigger()114*795d594fSAndroid Build Coastguard Worker Trigger GetTrigger() const { return trigger_; } 115*795d594fSAndroid Build Coastguard Worker 116*795d594fSAndroid Build Coastguard Worker // Sets the trigger for metrics collection. The trigger is the reason why odrefresh considers 117*795d594fSAndroid Build Coastguard Worker // compilation necessary. Only call this method if compilation is necessary as the presence 118*795d594fSAndroid Build Coastguard Worker // of a trigger means we will try to record and upload metrics. SetTrigger(const Trigger trigger)119*795d594fSAndroid Build Coastguard Worker void SetTrigger(const Trigger trigger) { trigger_ = trigger; } 120*795d594fSAndroid Build Coastguard Worker 121*795d594fSAndroid Build Coastguard Worker // Sets the execution status of the current odrefresh processing stage. SetStatus(const Status status)122*795d594fSAndroid Build Coastguard Worker void SetStatus(const Status status) { status_ = status; } 123*795d594fSAndroid Build Coastguard Worker 124*795d594fSAndroid Build Coastguard Worker // Sets the current odrefresh processing stage. SetStage(Stage stage)125*795d594fSAndroid Build Coastguard Worker void SetStage(Stage stage) { stage_ = stage; } 126*795d594fSAndroid Build Coastguard Worker 127*795d594fSAndroid Build Coastguard Worker // Sets the result of the current dex2oat invocation. 128*795d594fSAndroid Build Coastguard Worker void SetDex2OatResult(Stage stage, 129*795d594fSAndroid Build Coastguard Worker int64_t compilation_time, 130*795d594fSAndroid Build Coastguard Worker const std::optional<ExecResult>& dex2oat_result); 131*795d594fSAndroid Build Coastguard Worker 132*795d594fSAndroid Build Coastguard Worker // Sets the BCP compilation type. 133*795d594fSAndroid Build Coastguard Worker void SetBcpCompilationType(Stage stage, BcpCompilationType type); 134*795d594fSAndroid Build Coastguard Worker 135*795d594fSAndroid Build Coastguard Worker // Captures the current free space as the end free space. 136*795d594fSAndroid Build Coastguard Worker void CaptureSpaceFreeEnd(); 137*795d594fSAndroid Build Coastguard Worker 138*795d594fSAndroid Build Coastguard Worker // Records metrics into an OdrMetricsRecord. 139*795d594fSAndroid Build Coastguard Worker OdrMetricsRecord ToRecord() const; 140*795d594fSAndroid Build Coastguard Worker 141*795d594fSAndroid Build Coastguard Worker private: 142*795d594fSAndroid Build Coastguard Worker OdrMetrics(const OdrMetrics&) = delete; 143*795d594fSAndroid Build Coastguard Worker OdrMetrics operator=(const OdrMetrics&) = delete; 144*795d594fSAndroid Build Coastguard Worker 145*795d594fSAndroid Build Coastguard Worker static int32_t GetFreeSpaceMiB(const std::string& path); 146*795d594fSAndroid Build Coastguard Worker static void WriteToFile(const std::string& path, const OdrMetrics* metrics); 147*795d594fSAndroid Build Coastguard Worker 148*795d594fSAndroid Build Coastguard Worker static OdrMetricsRecord::Dex2OatExecResult 149*795d594fSAndroid Build Coastguard Worker ConvertExecResult(const std::optional<ExecResult>& result); 150*795d594fSAndroid Build Coastguard Worker 151*795d594fSAndroid Build Coastguard Worker const std::string cache_directory_; 152*795d594fSAndroid Build Coastguard Worker const std::string metrics_file_; 153*795d594fSAndroid Build Coastguard Worker 154*795d594fSAndroid Build Coastguard Worker bool enabled_ = false; 155*795d594fSAndroid Build Coastguard Worker 156*795d594fSAndroid Build Coastguard Worker int64_t art_apex_version_ = 0; 157*795d594fSAndroid Build Coastguard Worker int64_t art_apex_last_update_millis_ = 0; 158*795d594fSAndroid Build Coastguard Worker Trigger trigger_ = Trigger::kUnknown; 159*795d594fSAndroid Build Coastguard Worker Stage stage_ = Stage::kUnknown; 160*795d594fSAndroid Build Coastguard Worker Status status_ = Status::kUnknown; 161*795d594fSAndroid Build Coastguard Worker 162*795d594fSAndroid Build Coastguard Worker int32_t cache_space_free_start_mib_ = 0; 163*795d594fSAndroid Build Coastguard Worker int32_t cache_space_free_end_mib_ = 0; 164*795d594fSAndroid Build Coastguard Worker 165*795d594fSAndroid Build Coastguard Worker // The total time spent on compiling primary BCP. 166*795d594fSAndroid Build Coastguard Worker int32_t primary_bcp_compilation_millis_ = 0; 167*795d594fSAndroid Build Coastguard Worker 168*795d594fSAndroid Build Coastguard Worker // The result of the dex2oat invocation for compiling primary BCP, or `std::nullopt` if dex2oat is 169*795d594fSAndroid Build Coastguard Worker // not invoked. 170*795d594fSAndroid Build Coastguard Worker std::optional<ExecResult> primary_bcp_dex2oat_result_; 171*795d594fSAndroid Build Coastguard Worker 172*795d594fSAndroid Build Coastguard Worker BcpCompilationType primary_bcp_compilation_type_ = BcpCompilationType::kUnknown; 173*795d594fSAndroid Build Coastguard Worker 174*795d594fSAndroid Build Coastguard Worker // The total time spent on compiling secondary BCP. 175*795d594fSAndroid Build Coastguard Worker int32_t secondary_bcp_compilation_millis_ = 0; 176*795d594fSAndroid Build Coastguard Worker 177*795d594fSAndroid Build Coastguard Worker // The result of the dex2oat invocation for compiling secondary BCP, or `std::nullopt` if dex2oat 178*795d594fSAndroid Build Coastguard Worker // is not invoked. 179*795d594fSAndroid Build Coastguard Worker std::optional<ExecResult> secondary_bcp_dex2oat_result_; 180*795d594fSAndroid Build Coastguard Worker 181*795d594fSAndroid Build Coastguard Worker BcpCompilationType secondary_bcp_compilation_type_ = BcpCompilationType::kUnknown; 182*795d594fSAndroid Build Coastguard Worker 183*795d594fSAndroid Build Coastguard Worker // The total time spent on compiling system server. 184*795d594fSAndroid Build Coastguard Worker int32_t system_server_compilation_millis_ = 0; 185*795d594fSAndroid Build Coastguard Worker 186*795d594fSAndroid Build Coastguard Worker // The result of the last dex2oat invocation for compiling system server, or `std::nullopt` if 187*795d594fSAndroid Build Coastguard Worker // dex2oat is not invoked. 188*795d594fSAndroid Build Coastguard Worker std::optional<ExecResult> system_server_dex2oat_result_; 189*795d594fSAndroid Build Coastguard Worker }; 190*795d594fSAndroid Build Coastguard Worker 191*795d594fSAndroid Build Coastguard Worker // Generated ostream operators. 192*795d594fSAndroid Build Coastguard Worker std::ostream& operator<<(std::ostream& os, OdrMetrics::Status status); 193*795d594fSAndroid Build Coastguard Worker std::ostream& operator<<(std::ostream& os, OdrMetrics::Stage stage); 194*795d594fSAndroid Build Coastguard Worker std::ostream& operator<<(std::ostream& os, OdrMetrics::Trigger trigger); 195*795d594fSAndroid Build Coastguard Worker 196*795d594fSAndroid Build Coastguard Worker } // namespace odrefresh 197*795d594fSAndroid Build Coastguard Worker } // namespace art 198*795d594fSAndroid Build Coastguard Worker 199*795d594fSAndroid Build Coastguard Worker #endif // ART_ODREFRESH_ODR_METRICS_H_ 200