1/* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include "Benchmark.h" 18#include "BenchmarkGen.h" 19#include "VolumeManager.h" 20#include "ResponseCode.h" 21 22#include <base/file.h> 23#include <base/logging.h> 24#include <cutils/iosched_policy.h> 25#include <private/android_filesystem_config.h> 26 27#include <sys/time.h> 28#include <sys/resource.h> 29#include <unistd.h> 30 31#define ENABLE_DROP_CACHES 1 32 33using android::base::ReadFileToString; 34using android::base::WriteStringToFile; 35 36namespace android { 37namespace vold { 38 39static void notifyResult(const std::string& path, int64_t create_d, 40 int64_t drop_d, int64_t run_d, int64_t destroy_d) { 41 std::string res(path + 42 + " " + BenchmarkIdent() 43 + " " + std::to_string(create_d) 44 + " " + std::to_string(drop_d) 45 + " " + std::to_string(run_d) 46 + " " + std::to_string(destroy_d)); 47 VolumeManager::Instance()->getBroadcaster()->sendBroadcast( 48 ResponseCode::BenchmarkResult, res.c_str(), false); 49} 50 51static nsecs_t benchmark(const std::string& path) { 52 errno = 0; 53 int orig_prio = getpriority(PRIO_PROCESS, 0); 54 if (errno != 0) { 55 PLOG(ERROR) << "Failed to getpriority"; 56 return -1; 57 } 58 if (setpriority(PRIO_PROCESS, 0, -10) != 0) { 59 PLOG(ERROR) << "Failed to setpriority"; 60 return -1; 61 } 62 63 IoSchedClass orig_clazz = IoSchedClass_NONE; 64 int orig_ioprio = 0; 65 if (android_get_ioprio(0, &orig_clazz, &orig_ioprio)) { 66 PLOG(ERROR) << "Failed to android_get_ioprio"; 67 return -1; 68 } 69 if (android_set_ioprio(0, IoSchedClass_RT, 0)) { 70 PLOG(ERROR) << "Failed to android_set_ioprio"; 71 return -1; 72 } 73 74 char orig_cwd[PATH_MAX]; 75 if (getcwd(orig_cwd, PATH_MAX) == NULL) { 76 PLOG(ERROR) << "Failed getcwd"; 77 return -1; 78 } 79 if (chdir(path.c_str()) != 0) { 80 PLOG(ERROR) << "Failed chdir"; 81 return -1; 82 } 83 84 sync(); 85 86 LOG(INFO) << "Benchmarking " << path; 87 nsecs_t start = systemTime(SYSTEM_TIME_BOOTTIME); 88 89 BenchmarkCreate(); 90 sync(); 91 nsecs_t create = systemTime(SYSTEM_TIME_BOOTTIME); 92 93#if ENABLE_DROP_CACHES 94 LOG(VERBOSE) << "Before drop_caches"; 95 if (!WriteStringToFile("3", "/proc/sys/vm/drop_caches")) { 96 PLOG(ERROR) << "Failed to drop_caches"; 97 } 98 LOG(VERBOSE) << "After drop_caches"; 99#endif 100 nsecs_t drop = systemTime(SYSTEM_TIME_BOOTTIME); 101 102 BenchmarkRun(); 103 sync(); 104 nsecs_t run = systemTime(SYSTEM_TIME_BOOTTIME); 105 106 BenchmarkDestroy(); 107 sync(); 108 nsecs_t destroy = systemTime(SYSTEM_TIME_BOOTTIME); 109 110 if (chdir(orig_cwd) != 0) { 111 PLOG(ERROR) << "Failed to chdir"; 112 } 113 if (android_set_ioprio(0, orig_clazz, orig_ioprio)) { 114 PLOG(ERROR) << "Failed to android_set_ioprio"; 115 } 116 if (setpriority(PRIO_PROCESS, 0, orig_prio) != 0) { 117 PLOG(ERROR) << "Failed to setpriority"; 118 } 119 120 nsecs_t create_d = create - start; 121 nsecs_t drop_d = drop - create; 122 nsecs_t run_d = run - drop; 123 nsecs_t destroy_d = destroy - run; 124 125 LOG(INFO) << "create took " << nanoseconds_to_milliseconds(create_d) << "ms"; 126 LOG(INFO) << "drop took " << nanoseconds_to_milliseconds(drop_d) << "ms"; 127 LOG(INFO) << "run took " << nanoseconds_to_milliseconds(run_d) << "ms"; 128 LOG(INFO) << "destroy took " << nanoseconds_to_milliseconds(destroy_d) << "ms"; 129 130 notifyResult(path, create_d, drop_d, run_d, destroy_d); 131 132 return run_d; 133} 134 135nsecs_t BenchmarkPrivate(const std::string& path) { 136 std::string benchPath(path); 137 benchPath += "/misc"; 138 if (android::vold::PrepareDir(benchPath, 01771, AID_SYSTEM, AID_MISC)) { 139 return -1; 140 } 141 benchPath += "/vold"; 142 if (android::vold::PrepareDir(benchPath, 0700, AID_ROOT, AID_ROOT)) { 143 return -1; 144 } 145 benchPath += "/bench"; 146 if (android::vold::PrepareDir(benchPath, 0700, AID_ROOT, AID_ROOT)) { 147 return -1; 148 } 149 return benchmark(benchPath); 150} 151 152} // namespace vold 153} // namespace android 154