1 /* 2 ** 3 ** Copyright 2015, The Android Open Source Project 4 ** 5 ** Licensed under the Apache License, Version 2.0 (the "License"); 6 ** you may not use this file except in compliance with the License. 7 ** You may obtain a copy of the License at 8 ** 9 ** http://www.apache.org/licenses/LICENSE-2.0 10 ** 11 ** Unless required by applicable law or agreed to in writing, software 12 ** distributed under the License is distributed on an "AS IS" BASIS, 13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 ** See the License for the specific language governing permissions and 15 ** limitations under the License. 16 */ 17 18 #include <stdio.h> 19 #include <stdlib.h> 20 #include <string.h> 21 #include <unistd.h> 22 #include <string> 23 #include <sstream> 24 #include <sys/types.h> 25 #include <sys/wait.h> 26 27 #include <android-base/logging.h> 28 #ifdef __BIONIC__ 29 #include <android-base/properties.h> 30 #endif 31 32 #include "cpuconfig.h" 33 34 #define SYSFSCPU "/sys/devices/system/cpu" 35 36 HardwireCpuHelper::HardwireCpuHelper(bool perform) 37 : mpdecision_stopped_(false) 38 { 39 if (perform && GetMpdecisionRunning()) { 40 mpdecision_stopped_ = true; 41 StopMpdecision(); 42 int ncores = GetNumCores(); 43 for (int i = 0; i < ncores; ++i) { 44 OnlineCore(i, 1); 45 } 46 } 47 } 48 49 HardwireCpuHelper::~HardwireCpuHelper() 50 { 51 if (mpdecision_stopped_) { 52 RestartMpdecision(); 53 } 54 } 55 56 bool HardwireCpuHelper::GetMpdecisionRunning() 57 { 58 #ifdef __BIONIC__ 59 return android::base::GetProperty("init.svc.mpdecision", "") == "running"; 60 #else 61 return false; 62 #endif 63 } 64 65 66 int HardwireCpuHelper::GetNumCores() 67 { 68 int ncores = -1; 69 std::string possible(SYSFSCPU "/possible"); 70 FILE *fp = fopen(possible.c_str(), "re"); 71 if (fp) { 72 unsigned lo = 0, hi = 0; 73 if (fscanf(fp, "%u-%u", &lo, &hi) == 2) { 74 ncores = hi - lo + 1; 75 } 76 fclose(fp); 77 } 78 return ncores; 79 } 80 81 void HardwireCpuHelper::OnlineCore(int i, int onoff) 82 { 83 std::stringstream ss; 84 ss << SYSFSCPU "/cpu" << i << "/online"; 85 FILE *fp = fopen(ss.str().c_str(), "we"); 86 if (fp) { 87 fprintf(fp, onoff ? "1\n" : "0\n"); 88 fclose(fp); 89 } else { 90 PLOG(WARNING) << "open failed for " << ss.str(); 91 } 92 } 93 94 void HardwireCpuHelper::StopMpdecision() 95 { 96 #ifdef __BIONIC__ 97 if (!android::base::SetProperty("ctl.stop", "mpdecision")) { 98 LOG(ERROR) << "setprop ctl.stop mpdecision failed"; 99 } 100 #endif 101 } 102 103 void HardwireCpuHelper::RestartMpdecision() 104 { 105 #ifdef __BIONIC__ 106 // Don't try to offline the cores we previously onlined -- let 107 // mpdecision figure out what to do 108 109 if (!android::base::SetProperty("ctl.start", "mpdecision")) { 110 LOG(ERROR) << "setprop ctl.start mpdecision failed"; 111 } 112 #endif 113 } 114