Home | History | Annotate | Download | only in vold
      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 <android-base/file.h>
     23 #include <android-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 
     33 using android::base::ReadFileToString;
     34 using android::base::WriteStringToFile;
     35 
     36 namespace android {
     37 namespace vold {
     38 
     39 static 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 
     51 static 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 
    135 nsecs_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