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 36HardwireCpuHelper::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 49HardwireCpuHelper::~HardwireCpuHelper() 50{ 51 if (mpdecision_stopped_) { 52 RestartMpdecision(); 53 } 54} 55 56bool 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 66int 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 81void 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 94void 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 103void 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