perfprofdcore.cc revision f4605017b29dd98232af9385e71079a3ba0297f1
17e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh/* 27e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh** 37e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh** Copyright 2015, The Android Open Source Project 47e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh** 57e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh** Licensed under the Apache License, Version 2.0 (the "License"); 67e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh** you may not use this file except in compliance with the License. 77e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh** You may obtain a copy of the License at 87e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh** 97e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh** http://www.apache.org/licenses/LICENSE-2.0 107e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh** 117e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh** Unless required by applicable law or agreed to in writing, software 127e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh** distributed under the License is distributed on an "AS IS" BASIS, 137e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 147e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh** See the License for the specific language governing permissions and 157e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh** limitations under the License. 167e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh*/ 177e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh 187e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh#include <assert.h> 197e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh#include <dirent.h> 207e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh#include <errno.h> 217e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh#include <fcntl.h> 227e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh#include <signal.h> 237e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh#include <stdio.h> 247e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh#include <stdlib.h> 257e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh#include <string.h> 267e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh#include <sys/stat.h> 277e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh#include <sys/types.h> 2807f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh#include <sys/wait.h> 297e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh#include <time.h> 307e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh#include <unistd.h> 317e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh#include <string> 3207f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh#include <sstream> 337e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh#include <map> 34f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen#include <set> 357e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh#include <cctype> 367e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh 37f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen#include <base/stringprintf.h> 387e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh#include <cutils/properties.h> 397e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh 407e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh#include "perfprofdcore.h" 417e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh#include "perfprofdutils.h" 427e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh#include "perf_data_converter.h" 4307f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh#include "cpuconfig.h" 447e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh 457e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh// 467e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh// Perf profiling daemon -- collects system-wide profiles using 477e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh// 4807f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh// simpleperf record -a 497e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh// 507e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh// and encodes them so that they can be uploaded by a separate service. 517e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh// 527e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh 537e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh//...................................................................... 547e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh 557e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh// 5607f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh// Output file from 'perf record'. 577e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh// 587e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh#define PERF_OUTPUT "perf.data" 597e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh 607e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh// 617e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh// This enum holds the results of the "should we profile" configuration check. 627e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh// 637e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntoshtypedef enum { 647e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh 657e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh // All systems go for profile collection. 667e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh DO_COLLECT_PROFILE, 677e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh 6858bade36c738ed96137cfcc8d15f0505f085b5aeDehao Chen // The selected configuration directory doesn't exist. 6958bade36c738ed96137cfcc8d15f0505f085b5aeDehao Chen DONT_PROFILE_MISSING_CONFIG_DIR, 707e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh 717e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh // Destination directory does not contain the semaphore file that 727e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh // the perf profile uploading service creates when it determines 737e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh // that the user has opted "in" for usage data collection. No 747e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh // semaphore -> no user approval -> no profiling. 757e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh DONT_PROFILE_MISSING_SEMAPHORE, 767e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh 777e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh // No perf executable present 787e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh DONT_PROFILE_MISSING_PERF_EXECUTABLE, 797e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh 807e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh // We're running in the emulator, perf won't be able to do much 817e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh DONT_PROFILE_RUNNING_IN_EMULATOR 827e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh 837e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh} CKPROFILE_RESULT; 847e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh 857e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh// 867e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh// Are we running in the emulator? If so, stub out profile collection 877e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh// Starts as uninitialized (-1), then set to 1 or 0 at init time. 887e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh// 897e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntoshstatic int running_in_emulator = -1; 907e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh 917e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh// 927e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh// Is this a debug build ('userdebug' or 'eng')? 937e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh// Starts as uninitialized (-1), then set to 1 or 0 at init time. 947e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh// 957e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntoshstatic int is_debug_build = -1; 967e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh 977e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh// 987e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh// Random number generator seed (set at startup time). 997e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh// 1007e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntoshstatic unsigned short random_seed[3]; 1017e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh 1027e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh// 1037e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh// Config file path. May be overridden with -c command line option 1047e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh// 10558bade36c738ed96137cfcc8d15f0505f085b5aeDehao Chenstatic const char *config_file_path = 10658bade36c738ed96137cfcc8d15f0505f085b5aeDehao Chen "/data/data/com.google.android.gms/files/perfprofd.conf"; 1077e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh 1087e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh// 1097e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh// Set by SIGHUP signal handler 1107e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh// 1117e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntoshvolatile unsigned please_reread_config_file = 0; 1127e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh 1137e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh// 1147e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh// This table describes the config file syntax in terms of key/value pairs. 1157e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh// Values come in two flavors: strings, or unsigned integers. In the latter 1167e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh// case the reader sets allowable minimum/maximum for the setting. 1177e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh// 1187e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntoshclass ConfigReader { 1197e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh 1207e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh public: 1217e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh ConfigReader(); 1227e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh ~ConfigReader(); 1237e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh 1247e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh // Ask for the current setting of a config item 12507f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh unsigned getUnsignedValue(const char *key) const; 12607f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh std::string getStringValue(const char *key) const; 1277e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh 1287e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh // read the specified config file, applying any settings it contains 12958bade36c738ed96137cfcc8d15f0505f085b5aeDehao Chen void readFile(); 1307e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh 1317e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh private: 1327e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh void addUnsignedEntry(const char *key, 1337e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh unsigned default_value, 1347e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh unsigned min_value, 1357e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh unsigned max_value); 1367e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh void addStringEntry(const char *key, const char *default_value); 1377e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh void addDefaultEntries(); 1387e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh void parseLine(const char *key, const char *value, unsigned linecount); 1397e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh 1407e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh typedef struct { unsigned minv, maxv; } values; 1417e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh std::map<std::string, values> u_info; 1427e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh std::map<std::string, unsigned> u_entries; 1437e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh std::map<std::string, std::string> s_entries; 1447e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh bool trace_config_read; 1457e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh}; 1467e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh 1477e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntoshConfigReader::ConfigReader() 1487e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh : trace_config_read(false) 1497e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh{ 1507e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh addDefaultEntries(); 1517e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh} 1527e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh 1537e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntoshConfigReader::~ConfigReader() 1547e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh{ 1557e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh} 1567e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh 1577e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh// 1587e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh// Populate the reader with the set of allowable entries 1597e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh// 1607e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntoshvoid ConfigReader::addDefaultEntries() 1617e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh{ 1627e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh // Average number of seconds between perf profile collections (if 1637e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh // set to 100, then over time we want to see a perf profile 1647e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh // collected every 100 seconds). The actual time within the interval 1657e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh // for the collection is chosen randomly. 1667e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh addUnsignedEntry("collection_interval", 901, 100, UINT32_MAX); 1677e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh 1687e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh // Use the specified fixed seed for random number generation (unit 1697e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh // testing) 1707e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh addUnsignedEntry("use_fixed_seed", 0, 0, UINT32_MAX); 1717e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh 1727e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh // For testing purposes, number of times to iterate through main 1737e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh // loop. Value of zero indicates that we should loop forever. 1747e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh addUnsignedEntry("main_loop_iterations", 0, 0, UINT32_MAX); 1757e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh 1767e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh // Destination directory (where to write profiles). This location 1777e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh // chosen since it is accessible to the uploader service. 17858bade36c738ed96137cfcc8d15f0505f085b5aeDehao Chen addStringEntry("destination_directory", "/data/misc/perfprofd"); 17958bade36c738ed96137cfcc8d15f0505f085b5aeDehao Chen 18058bade36c738ed96137cfcc8d15f0505f085b5aeDehao Chen // Config directory (where to read configs). 18158bade36c738ed96137cfcc8d15f0505f085b5aeDehao Chen addStringEntry("config_directory", "/data/data/com.google.android.gms/files"); 1827e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh 18307f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh // Full path to 'perf' executable. 18435bb6be739761482fa7e72214d2aedf2623cbb9aDehao Chen addStringEntry("perf_path", "/system/xbin/simpleperf"); 1857e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh 1867e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh // Desired sampling period (passed to perf -c option). Small 1877e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh // sampling periods can perturb the collected profiles, so enforce 1887e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh // min/max. 1897e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh addUnsignedEntry("sampling_period", 500000, 5000, UINT32_MAX); 1907e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh 1917e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh // Length of time to collect samples (number of seconds for 'perf 1927e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh // record -a' run). 1937e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh addUnsignedEntry("sample_duration", 3, 2, 600); 1947e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh 1957e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh // If this parameter is non-zero it will cause perfprofd to 1967e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh // exit immediately if the build type is not userdebug or eng. 1977e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh // Currently defaults to 1 (true). 1987e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh addUnsignedEntry("only_debug_build", 1, 0, 1); 1997e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh 20007f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh // If the "mpdecision" service is running at the point we are ready 20107f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh // to kick off a profiling run, then temporarily disable the service 20207f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh // and hard-wire all cores on prior to the collection run, provided 20307f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh // that the duration of the recording is less than or equal to the value of 20407f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh // 'hardwire_cpus_max_duration'. 20507f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh addUnsignedEntry("hardwire_cpus", 1, 0, 1); 20607f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh addUnsignedEntry("hardwire_cpus_max_duration", 5, 1, UINT32_MAX); 20707f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh 20807f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh // If set to 1, pass the -g option when invoking 'perf' (requests 2097e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh // stack traces as opposed to flat profile). 2107e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh addUnsignedEntry("stack_profile", 0, 0, 1); 2117e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh 2127e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh // For unit testing only: if set to 1, emit info messages on config 2137e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh // file parsing. 2147e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh addUnsignedEntry("trace_config_read", 0, 0, 1); 2157e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh} 2167e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh 2177e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntoshvoid ConfigReader::addUnsignedEntry(const char *key, 2187e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh unsigned default_value, 2197e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh unsigned min_value, 2207e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh unsigned max_value) 2217e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh{ 2227e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh std::string ks(key); 2237e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh if (u_entries.find(ks) != u_entries.end() || 2247e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh s_entries.find(ks) != s_entries.end()) { 2257e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh W_ALOGE("internal error -- duplicate entry for key %s", key); 2267e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh exit(9); 2277e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh } 2287e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh values vals; 2297e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh vals.minv = min_value; 2307e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh vals.maxv = max_value; 2317e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh u_info[ks] = vals; 2327e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh u_entries[ks] = default_value; 2337e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh} 2347e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh 2357e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntoshvoid ConfigReader::addStringEntry(const char *key, const char *default_value) 2367e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh{ 2377e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh std::string ks(key); 2387e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh if (u_entries.find(ks) != u_entries.end() || 2397e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh s_entries.find(ks) != s_entries.end()) { 2407e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh W_ALOGE("internal error -- duplicate entry for key %s", key); 2417e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh exit(9); 2427e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh } 24307f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh if (default_value == nullptr) { 2447e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh W_ALOGE("internal error -- bad default value for key %s", key); 2457e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh exit(9); 2467e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh } 2477e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh s_entries[ks] = std::string(default_value); 2487e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh} 2497e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh 25007f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntoshunsigned ConfigReader::getUnsignedValue(const char *key) const 2517e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh{ 2527e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh std::string ks(key); 2537e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh auto it = u_entries.find(ks); 2547e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh assert(it != u_entries.end()); 2557e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh return it->second; 2567e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh} 2577e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh 25807f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntoshstd::string ConfigReader::getStringValue(const char *key) const 2597e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh{ 2607e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh std::string ks(key); 2617e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh auto it = s_entries.find(ks); 2627e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh assert(it != s_entries.end()); 2637e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh return it->second; 2647e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh} 2657e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh 2667e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh// 2677e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh// Parse a key=value pair read from the config file. This will issue 2687e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh// warnings or errors to the system logs if the line can't be 2697e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh// interpreted properly. 2707e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh// 2717e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntoshvoid ConfigReader::parseLine(const char *key, 2727e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh const char *value, 2737e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh unsigned linecount) 2747e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh{ 2757e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh assert(key); 2767e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh assert(value); 2777e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh 2787e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh auto uit = u_entries.find(key); 2797e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh if (uit != u_entries.end()) { 2807e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh unsigned uvalue = 0; 28107f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh if (isdigit(value[0]) == 0 || sscanf(value, "%u", &uvalue) != 1) { 2827e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh W_ALOGW("line %d: malformed unsigned value (ignored)", linecount); 2837e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh } else { 2847e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh values vals; 2857e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh auto iit = u_info.find(key); 2867e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh assert(iit != u_info.end()); 2877e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh vals = iit->second; 2887e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh if (uvalue < vals.minv || uvalue > vals.maxv) { 2897e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh W_ALOGW("line %d: specified value %u for '%s' " 2907e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh "outside permitted range [%u %u] (ignored)", 2917e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh linecount, uvalue, key, vals.minv, vals.maxv); 2927e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh } else { 2937e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh if (trace_config_read) { 2947e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh W_ALOGI("option %s set to %u", key, uvalue); 2957e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh } 2967e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh uit->second = uvalue; 2977e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh } 2987e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh } 2997e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh trace_config_read = (getUnsignedValue("trace_config_read") != 0); 3007e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh return; 3017e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh } 3027e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh 3037e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh auto sit = s_entries.find(key); 3047e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh if (sit != s_entries.end()) { 3057e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh if (trace_config_read) { 3067e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh W_ALOGI("option %s set to %s", key, value); 3077e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh } 3087e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh sit->second = std::string(value); 3097e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh return; 3107e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh } 3117e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh 3127e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh W_ALOGW("line %d: unknown option '%s' ignored", linecount, key); 3137e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh} 3147e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh 3157e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntoshstatic bool isblank(const std::string &line) 3167e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh{ 3177e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh for (std::string::const_iterator it = line.begin(); it != line.end(); ++it) 3187e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh { 31907f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh if (isspace(*it) == 0) { 3207e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh return false; 3217e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh } 3227e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh } 3237e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh return true; 3247e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh} 3257e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh 32658bade36c738ed96137cfcc8d15f0505f085b5aeDehao Chenvoid ConfigReader::readFile() 3277e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh{ 32858bade36c738ed96137cfcc8d15f0505f085b5aeDehao Chen FILE *fp = fopen(config_file_path, "r"); 3297e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh if (!fp) { 3307e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh W_ALOGE("unable to open configuration file %s", config_file_path); 3317e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh return; 3327e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh } 3337e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh 3347e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh char *linebuf = NULL; 3357e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh size_t line_length = 0; 3367e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh for (unsigned linecount = 1; 3377e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh getline(&linebuf, &line_length, fp) != -1; 3387e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh ++linecount) { 3397e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh char *eq = 0; 3407e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh char *key, *value; 3417e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh 3427e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh // comment line? 3437e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh if (linebuf[0] == '#') { 3447e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh continue; 3457e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh } 3467e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh 3477e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh // blank line? 3487e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh if (isblank(linebuf)) { 3497e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh continue; 3507e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh } 3517e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh 3527e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh // look for X=Y assignment 3537e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh eq = strchr(linebuf, '='); 3547e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh if (!eq) { 3557e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh W_ALOGW("line %d: line malformed (no '=' found)", linecount); 3567e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh continue; 3577e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh } 3587e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh 3597e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh *eq = '\0'; 3607e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh key = linebuf; 3617e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh value = eq+1; 3627e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh char *ln = strrchr(value, '\n'); 3637e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh if (ln) { *ln = '\0'; } 3647e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh 3657e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh parseLine(key, value, linecount); 3667e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh } 3677e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh free(linebuf); 3687e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh fclose(fp); 3697e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh} 3707e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh 3717e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh// 3727e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh// Parse command line args. Currently you can supply "-c P" to set 3737e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh// the path of the config file to P. 3747e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh// 3757e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntoshstatic void parse_args(int argc, char** argv) 3767e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh{ 3777e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh int ac; 3787e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh 3797e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh for (ac = 1; ac < argc; ++ac) { 3807e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh if (!strcmp(argv[ac], "-c")) { 3817e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh if (ac >= argc-1) { 3827e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh W_ALOGE("malformed command line: -c option requires argument)"); 3837e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh continue; 3847e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh } 3857e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh config_file_path = strdup(argv[ac+1]); 3867e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh W_ALOGI("config file path set to %s", config_file_path); 3877e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh ++ac; 3887e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh } else { 3897e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh W_ALOGE("malformed command line: unknown option or arg %s)", argv[ac]); 3907e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh continue; 3917e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh } 3927e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh } 3937e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh} 3947e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh 3957e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh// 3967e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh// Convert a CKPROFILE_RESULT to a string 3977e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh// 3987e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntoshconst char *ckprofile_result_to_string(CKPROFILE_RESULT result) 3997e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh{ 40007f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh switch (result) { 4017e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh case DO_COLLECT_PROFILE: 4027e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh return "DO_COLLECT_PROFILE"; 40358bade36c738ed96137cfcc8d15f0505f085b5aeDehao Chen case DONT_PROFILE_MISSING_CONFIG_DIR: 40458bade36c738ed96137cfcc8d15f0505f085b5aeDehao Chen return "missing config directory"; 4057e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh case DONT_PROFILE_MISSING_SEMAPHORE: 4067e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh return "missing semaphore file"; 4077e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh case DONT_PROFILE_MISSING_PERF_EXECUTABLE: 4087e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh return "missing 'perf' executable"; 4097e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh case DONT_PROFILE_RUNNING_IN_EMULATOR: 4107e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh return "running in emulator"; 4117e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh default: return "unknown"; 4127e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh } 4137e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh return "notreached"; 4147e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh} 4157e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh 4167e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh// 4177e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh// Convert a PROFILE_RESULT to a string 4187e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh// 4197e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntoshconst char *profile_result_to_string(PROFILE_RESULT result) 4207e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh{ 4217e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh switch(result) { 4227e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh case OK_PROFILE_COLLECTION: 4237e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh return "profile collection succeeded"; 4247e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh case ERR_FORK_FAILED: 4257e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh return "fork() system call failed"; 4267e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh case ERR_PERF_RECORD_FAILED: 4277e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh return "perf record returned bad exit status"; 4287e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh case ERR_PERF_ENCODE_FAILED: 4297e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh return "failure encoding perf.data to protobuf"; 4307e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh case ERR_OPEN_ENCODED_FILE_FAILED: 4317e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh return "failed to open encoded perf file"; 4327e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh case ERR_WRITE_ENCODED_FILE_FAILED: 4337e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh return "write to encoded perf file failed"; 4347e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh default: return "unknown"; 4357e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh } 4367e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh return "notreached"; 4377e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh} 4387e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh 4397e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh// 4407e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh// Check to see whether we should perform a profile collection 4417e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh// 4427e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntoshstatic CKPROFILE_RESULT check_profiling_enabled(ConfigReader &config) 4437e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh{ 4447e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh // 4457e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh // Profile collection in the emulator doesn't make sense 4467e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh // 4477e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh assert(running_in_emulator != -1); 4487e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh if (running_in_emulator) { 4497e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh return DONT_PROFILE_RUNNING_IN_EMULATOR; 4507e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh } 4517e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh 4527e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh // 45358bade36c738ed96137cfcc8d15f0505f085b5aeDehao Chen // Check for existence of semaphore file in config directory 4547e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh // 45558bade36c738ed96137cfcc8d15f0505f085b5aeDehao Chen if (access(config.getStringValue("config_directory").c_str(), F_OK) == -1) { 45658bade36c738ed96137cfcc8d15f0505f085b5aeDehao Chen W_ALOGW("unable to open config directory %s: (%s)", 45758bade36c738ed96137cfcc8d15f0505f085b5aeDehao Chen config.getStringValue("config_directory").c_str(), strerror(errno)); 45858bade36c738ed96137cfcc8d15f0505f085b5aeDehao Chen return DONT_PROFILE_MISSING_CONFIG_DIR; 4597e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh } 4607e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh 46158bade36c738ed96137cfcc8d15f0505f085b5aeDehao Chen 46258bade36c738ed96137cfcc8d15f0505f085b5aeDehao Chen // Check for existence of semaphore file 46358bade36c738ed96137cfcc8d15f0505f085b5aeDehao Chen std::string semaphore_filepath = config.getStringValue("config_directory") 46458bade36c738ed96137cfcc8d15f0505f085b5aeDehao Chen + "/" + SEMAPHORE_FILENAME; 46558bade36c738ed96137cfcc8d15f0505f085b5aeDehao Chen if (access(semaphore_filepath.c_str(), F_OK) == -1) { 46658bade36c738ed96137cfcc8d15f0505f085b5aeDehao Chen return DONT_PROFILE_MISSING_SEMAPHORE; 46758bade36c738ed96137cfcc8d15f0505f085b5aeDehao Chen } 4687e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh 46907f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh // Check for existence of simpleperf/perf executable 4707e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh std::string pp = config.getStringValue("perf_path"); 4717e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh if (access(pp.c_str(), R_OK|X_OK) == -1) { 4727e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh W_ALOGW("unable to access/execute %s", pp.c_str()); 4737e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh return DONT_PROFILE_MISSING_PERF_EXECUTABLE; 4747e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh } 4757e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh 4767e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh // 4777e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh // We are good to go 4787e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh // 4797e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh return DO_COLLECT_PROFILE; 4807e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh} 4817e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh 4827e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntoshinline char* string_as_array(std::string* str) { 4837e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh return str->empty() ? NULL : &*str->begin(); 4847e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh} 4857e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh 4867e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntoshPROFILE_RESULT encode_to_proto(const std::string &data_file_path, 487f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen const char *encoded_file_path) 4887e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh{ 4897e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh // 4907e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh // Open and read perf.data file 4917e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh // 4927e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh const wireless_android_play_playlog::AndroidPerfProfile &encodedProfile = 4937e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh wireless_android_logging_awp::RawPerfDataToAndroidPerfProfile(data_file_path); 4947e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh 4957e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh // 4967e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh // Issue error if no samples 4977e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh // 4987e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh if (encodedProfile.programs().size() == 0) { 4997e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh return ERR_PERF_ENCODE_FAILED; 5007e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh } 5017e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh 5027e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh // 5037e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh // Serialize protobuf to array 5047e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh // 5057e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh int size = encodedProfile.ByteSize(); 5067e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh std::string data; 5077e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh data.resize(size); 5087e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh ::google::protobuf::uint8* dtarget = 5097e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh reinterpret_cast<::google::protobuf::uint8*>(string_as_array(&data)); 5107e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh encodedProfile.SerializeWithCachedSizesToArray(dtarget); 5117e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh 5127e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh // 5137e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh // Open file and write encoded data to it 5147e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh // 515f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen FILE *fp = fopen(encoded_file_path, "w"); 5167e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh if (!fp) { 5177e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh return ERR_OPEN_ENCODED_FILE_FAILED; 5187e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh } 5197e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh size_t fsiz = size; 5207e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh if (fwrite(dtarget, fsiz, 1, fp) != 1) { 5217e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh fclose(fp); 5227e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh return ERR_WRITE_ENCODED_FILE_FAILED; 5237e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh } 5247e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh fclose(fp); 525f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen chmod(encoded_file_path, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH); 5267e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh 5277e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh return OK_PROFILE_COLLECTION; 5287e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh} 5297e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh 5307e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh// 53107f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh// Invoke "perf record". Return value is OK_PROFILE_COLLECTION for 53207f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh// success, or some other error code if something went wrong. 53307f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh// 53407f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntoshstatic PROFILE_RESULT invoke_perf(const std::string &perf_path, 53507f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh unsigned sampling_period, 53607f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh const char *stack_profile_opt, 53707f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh unsigned duration, 53807f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh const std::string &data_file_path, 53907f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh const std::string &perf_stderr_path) 54007f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh{ 54107f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh pid_t pid = fork(); 54207f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh 54307f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh if (pid == -1) { 54407f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh return ERR_FORK_FAILED; 54507f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh } 54607f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh 54707f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh if (pid == 0) { 54807f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh // child 54907f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh 55007f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh // Open file to receive stderr/stdout from perf 55107f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh FILE *efp = fopen(perf_stderr_path.c_str(), "w"); 55207f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh if (efp) { 55307f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh dup2(fileno(efp), STDERR_FILENO); 55407f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh dup2(fileno(efp), STDOUT_FILENO); 55507f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh } else { 55607f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh W_ALOGW("unable to open %s for writing", perf_stderr_path.c_str()); 55707f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh } 55807f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh 55907f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh // marshall arguments 56007f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh constexpr unsigned max_args = 12; 56107f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh const char *argv[max_args]; 56207f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh unsigned slot = 0; 56307f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh argv[slot++] = perf_path.c_str(); 56407f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh argv[slot++] = "record"; 56507f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh 56607f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh // -o perf.data 56707f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh argv[slot++] = "-o"; 56807f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh argv[slot++] = data_file_path.c_str(); 56907f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh 57007f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh // -c N 57107f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh argv[slot++] = "-c"; 572f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen std::string p_str = android::base::StringPrintf("%u", sampling_period); 573f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen argv[slot++] = p_str.c_str(); 57407f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh 57507f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh // -g if desired 57607f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh if (stack_profile_opt) 57707f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh argv[slot++] = stack_profile_opt; 57807f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh 57907f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh // system wide profiling 58007f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh argv[slot++] = "-a"; 58107f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh 58207f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh // sleep <duration> 58307f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh argv[slot++] = "/system/bin/sleep"; 584f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen std::string d_str = android::base::StringPrintf("%u", duration); 585f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen argv[slot++] = d_str.c_str(); 58607f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh 58707f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh // terminator 58807f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh argv[slot++] = nullptr; 58907f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh assert(slot < max_args); 59007f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh 59107f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh // record the final command line in the error output file for 59207f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh // posterity/debugging purposes 59307f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh fprintf(stderr, "perf invocation (pid=%d):\n", getpid()); 59407f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh for (unsigned i = 0; argv[i] != nullptr; ++i) { 59507f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh fprintf(stderr, "%s%s", i ? " " : "", argv[i]); 59607f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh } 59707f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh fprintf(stderr, "\n"); 59807f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh 59907f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh // exec 60007f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh execvp(argv[0], (char * const *)argv); 60107f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh fprintf(stderr, "exec failed: %s\n", strerror(errno)); 60207f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh exit(1); 60307f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh 60407f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh } else { 60507f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh // parent 60607f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh int st = 0; 60707f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh pid_t reaped = TEMP_FAILURE_RETRY(waitpid(pid, &st, 0)); 60807f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh 60907f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh if (reaped == -1) { 61007f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh W_ALOGW("waitpid failed: %s", strerror(errno)); 61107f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh } else if (WIFSIGNALED(st)) { 61207f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh W_ALOGW("perf killed by signal %d", WTERMSIG(st)); 61307f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh } else if (WEXITSTATUS(st) != 0) { 61407f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh W_ALOGW("perf bad exit status %d", WEXITSTATUS(st)); 61507f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh } else { 61607f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh return OK_PROFILE_COLLECTION; 61707f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh } 61807f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh } 61907f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh 62007f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh return ERR_PERF_RECORD_FAILED; 62107f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh} 62207f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh 62307f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh// 624f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen// Remove all files in the destination directory during initialization 625f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen// 626f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chenstatic void cleanup_destination_dir(const ConfigReader &config) 627f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen{ 628f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen std::string dest_dir = config.getStringValue("destination_directory"); 629f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen DIR* dir = opendir(dest_dir.c_str()); 630f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen if (dir != NULL) { 631f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen struct dirent* e; 632f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen while ((e = readdir(dir)) != 0) { 633f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen if (e->d_name[0] != '.') { 634f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen std::string file_path = dest_dir + "/" + e->d_name; 635f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen remove(file_path.c_str()); 636f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen } 637f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen } 638f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen closedir(dir); 639f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen } 640f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen} 641f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen 642f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen// 643f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen// Post-processes after profile is collected and converted to protobuf. 644f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen// * GMS core stores processed file sequence numbers in 645f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen// /data/data/com.google.android.gms/files/perfprofd_processed.txt 646f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen// * Update /data/misc/perfprofd/perfprofd_produced.txt to remove the sequence 647f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen// numbers that have been processed and append the current seq number 648f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen// Returns true if the current_seq should increment. 649f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen// 650f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chenstatic bool post_process(const ConfigReader &config, int current_seq) 651f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen{ 652f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen std::string dest_dir = config.getStringValue("destination_directory"); 653f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen std::string processed_file_path = 654f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen config.getStringValue("config_directory") + "/" + PROCESSED_FILENAME; 655f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen std::string produced_file_path = dest_dir + "/" + PRODUCED_FILENAME; 656f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen 657f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen 658f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen std::set<int> processed; 659f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen FILE *fp = fopen(processed_file_path.c_str(), "r"); 660f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen if (fp != NULL) { 661f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen int seq; 662f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen while(fscanf(fp, "%d\n", &seq) > 0) { 663f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen if (remove(android::base::StringPrintf( 664f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen "%s/perf.data.encoded.%d", dest_dir.c_str(),seq).c_str()) == 0) { 665f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen processed.insert(seq); 666f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen } 667f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen } 668f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen fclose(fp); 669f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen } 670f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen 671f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen std::set<int> produced; 672f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen fp = fopen(produced_file_path.c_str(), "r"); 673f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen if (fp != NULL) { 674f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen int seq; 675f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen while(fscanf(fp, "%d\n", &seq) > 0) { 676f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen if (processed.find(seq) == processed.end()) { 677f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen produced.insert(seq); 678f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen } 679f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen } 680f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen fclose(fp); 681f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen } 682f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen 683f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen if (produced.size() >= MAX_UNPROCESSED_FILE) { 684f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen return false; 685f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen } 686f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen 687f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen produced.insert(current_seq); 688f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen fp = fopen(produced_file_path.c_str(), "w"); 689f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen if (fp == NULL) { 690f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen W_ALOGW("Cannot write %s", produced_file_path.c_str()); 691f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen return false; 692f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen } 693f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen for (std::set<int>::const_iterator iter = produced.begin(); 694f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen iter != produced.end(); ++iter) { 695f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen fprintf(fp, "%d\n", *iter); 696f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen } 697f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen fclose(fp); 698f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen chmod(produced_file_path.c_str(), 699f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH); 700f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen return true; 701f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen} 702f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen 703f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen// 7047e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh// Collect a perf profile. Steps for this operation are: 7057e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh// - kick off 'perf record' 7067e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh// - read perf.data, convert to protocol buf 7077e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh// 708f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chenstatic PROFILE_RESULT collect_profile(const ConfigReader &config, int seq) 7097e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh{ 7107e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh // 7117e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh // Form perf.data file name, perf error output file name 7127e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh // 7137e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh std::string destdir = config.getStringValue("destination_directory"); 7147e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh std::string data_file_path(destdir); 7157e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh data_file_path += "/"; 7167e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh data_file_path += PERF_OUTPUT; 7177e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh std::string perf_stderr_path(destdir); 7187e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh perf_stderr_path += "/perferr.txt"; 7197e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh 7207e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh // 7217e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh // Remove any existing perf.data file -- if we don't do this, perf 7227e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh // will rename the old file and we'll have extra cruft lying around. 7237e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh // 7247e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh struct stat statb; 7257e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh if (stat(data_file_path.c_str(), &statb) == 0) { // if file exists... 7267e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh if (unlink(data_file_path.c_str())) { // then try to remove 7277e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh W_ALOGW("unable to unlink previous perf.data file"); 7287e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh } 7297e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh } 7307e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh 7317e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh // 73207f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh // The "mpdecision" daemon can cause problems for profile 73307f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh // collection: if it decides to online a CPU partway through the 73407f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh // 'perf record' run, the activity on that CPU will be invisible to 73507f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh // perf, and if it offlines a CPU during the recording this can 73607f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh // sometimes leave the PMU in an unusable state (dmesg errors of the 73707f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh // form "perfevents: unable to request IRQXXX for ..."). To avoid 73807f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh // these issues, if "mpdecision" is running the helper below will 73907f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh // stop the service and then online all available CPUs. The object 74007f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh // destructor (invoked when this routine terminates) will then 74107f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh // restart the service again when needed. 7427e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh // 7437e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh unsigned duration = config.getUnsignedValue("sample_duration"); 74407f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh unsigned hardwire = config.getUnsignedValue("hardwire_cpus"); 74507f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh unsigned max_duration = config.getUnsignedValue("hardwire_cpus_max_duration"); 74607f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh bool take_action = (hardwire && duration <= max_duration); 74707f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh HardwireCpuHelper helper(take_action); 74807f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh 74907f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh // 75007f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh // Invoke perf 75107f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh // 75207f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh const char *stack_profile_opt = 75307f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh (config.getUnsignedValue("stack_profile") != 0 ? "-g" : nullptr); 75407f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh std::string perf_path = config.getStringValue("perf_path"); 7557e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh unsigned period = config.getUnsignedValue("sampling_period"); 75607f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh 75707f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh PROFILE_RESULT ret = invoke_perf(perf_path.c_str(), 75807f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh period, 75907f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh stack_profile_opt, 76007f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh duration, 76107f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh data_file_path, 76207f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh perf_stderr_path); 76307f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh if (ret != OK_PROFILE_COLLECTION) { 76407f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh return ret; 7657e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh } 7667e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh 7677e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh // 7687e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh // Read the resulting perf.data file, encode into protocol buffer, then write 76907f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh // the result to the file perf.data.encoded 7707e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh // 771f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen std::string path = android::base::StringPrintf( 772f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen "%s.encoded.%d", data_file_path.c_str(), seq); 773f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen return encode_to_proto(data_file_path, path.c_str()); 7747e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh} 7757e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh 7767e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh// 7777e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh// SIGHUP handler. Sets a flag to indicate that we should reread the 7787e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh// config file 7797e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh// 7807e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntoshstatic void sig_hup(int /* signum */) 7817e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh{ 7827e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh please_reread_config_file = 1; 7837e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh} 7847e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh 7857e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh// 7867e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh// Assuming that we want to collect a profile every N seconds, 7877e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh// randomly partition N into two sub-intervals. 7887e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh// 7897e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntoshstatic void determine_before_after(unsigned &sleep_before_collect, 7907e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh unsigned &sleep_after_collect, 7917e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh unsigned collection_interval) 7927e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh{ 7937e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh double frac = erand48(random_seed); 7947e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh sleep_before_collect = (unsigned) (((double)collection_interval) * frac); 7957e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh assert(sleep_before_collect <= collection_interval); 7967e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh sleep_after_collect = collection_interval - sleep_before_collect; 7977e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh} 7987e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh 7997e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh// 8007e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh// Set random number generator seed 8017e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh// 8027e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntoshstatic void set_seed(ConfigReader &config) 8037e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh{ 8047e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh unsigned seed = 0; 8057e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh unsigned use_fixed_seed = config.getUnsignedValue("use_fixed_seed"); 8067e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh if (use_fixed_seed) { 8077e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh // 8087e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh // Use fixed user-specified seed 8097e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh // 8107e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh seed = use_fixed_seed; 8117e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh } else { 8127e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh // 8137e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh // Randomized seed 8147e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh // 8157e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh seed = arc4random(); 8167e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh } 8177e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh W_ALOGI("random seed set to %u", seed); 8187e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh // Distribute the 32-bit seed into the three 16-bit array 8197e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh // elements. The specific values being written do not especially 8207e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh // matter as long as we are setting them to something based on the seed. 8217e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh random_seed[0] = seed & 0xffff; 8227e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh random_seed[1] = (seed >> 16); 8237e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh random_seed[2] = (random_seed[0] ^ random_seed[1]); 8247e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh} 8257e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh 8267e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh// 8277e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh// Initialization 8287e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh// 8297e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntoshstatic void init(ConfigReader &config) 8307e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh{ 83158bade36c738ed96137cfcc8d15f0505f085b5aeDehao Chen config.readFile(); 8327e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh set_seed(config); 833f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen cleanup_destination_dir(config); 8347e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh 8357e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh char propBuf[PROPERTY_VALUE_MAX]; 8367e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh propBuf[0] = '\0'; 8377e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh property_get("ro.kernel.qemu", propBuf, ""); 8387e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh running_in_emulator = (propBuf[0] == '1'); 8397e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh property_get("ro.debuggable", propBuf, ""); 8407e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh is_debug_build = (propBuf[0] == '1'); 8417e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh 8427e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh signal(SIGHUP, sig_hup); 8437e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh} 8447e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh 8457e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh// 8467e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh// Main routine: 8477e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh// 1. parse cmd line args 8487e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh// 2. read config file 8497e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh// 3. loop: { 8507e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh// sleep for a while 8517e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh// perform a profile collection 8527e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh// } 8537e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh// 8547e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntoshint perfprofd_main(int argc, char** argv) 8557e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh{ 8567e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh ConfigReader config; 8577e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh 8587e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh W_ALOGI("starting Android Wide Profiling daemon"); 8597e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh 8607e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh parse_args(argc, argv); 8617e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh init(config); 8627e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh 8637e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh // Early exit if we're not supposed to run on this build flavor 8647e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh if (is_debug_build != 1 && 8657e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh config.getUnsignedValue("only_debug_build") == 1) { 8667e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh W_ALOGI("early exit due to inappropriate build type"); 8677e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh return 0; 8687e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh } 8697e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh 8707e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh unsigned iterations = 0; 871f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen int seq = 0; 87207f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh while(config.getUnsignedValue("main_loop_iterations") == 0 || 8737e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh iterations < config.getUnsignedValue("main_loop_iterations")) { 8747e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh 8757e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh // Figure out where in the collection interval we're going to actually 8767e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh // run perf 8777e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh unsigned sleep_before_collect = 0; 8787e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh unsigned sleep_after_collect = 0; 8797e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh determine_before_after(sleep_before_collect, sleep_after_collect, 8807e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh config.getUnsignedValue("collection_interval")); 8817e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh perfprofd_sleep(sleep_before_collect); 8827e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh 8837e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh // Reread config file if someone sent a SIGHUP 8847e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh if (please_reread_config_file) { 88558bade36c738ed96137cfcc8d15f0505f085b5aeDehao Chen config.readFile(); 8867e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh please_reread_config_file = 0; 8877e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh } 8887e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh 8897e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh // Check for profiling enabled... 8907e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh CKPROFILE_RESULT ckresult = check_profiling_enabled(config); 8917e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh if (ckresult != DO_COLLECT_PROFILE) { 8927e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh W_ALOGI("profile collection skipped (%s)", 8937e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh ckprofile_result_to_string(ckresult)); 8947e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh } else { 8957e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh // Kick off the profiling run... 8967e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh W_ALOGI("initiating profile collection"); 897f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen PROFILE_RESULT result = collect_profile(config, seq); 8987e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh if (result != OK_PROFILE_COLLECTION) { 8997e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh W_ALOGI("profile collection failed (%s)", 9007e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh profile_result_to_string(result)); 9017e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh } else { 902f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen if (post_process(config, seq)) { 903f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen seq++; 904f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen } 9057e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh W_ALOGI("profile collection complete"); 9067e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh } 9077e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh } 9087e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh perfprofd_sleep(sleep_after_collect); 9097e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh iterations += 1; 9107e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh } 9117e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh 9127e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh W_ALOGI("finishing Android Wide Profiling daemon"); 9137e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh return 0; 9147e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh} 915