Loading include/cpustats/ThreadCpuUsage.h +2 −1 Original line number Diff line number Diff line Loading @@ -131,7 +131,8 @@ private: uint32_t mCurrentkHz[MAX_CPU]; // current CPU frequency in kHz, not static to avoid a race static pthread_once_t sOnceControl; static int sKernelMax; // like MAX_CPU, but determined at runtime == cpu/kernel_max + 1 static void init(); static void init(); // called once at first ThreadCpuUsage construction static pthread_mutex_t sMutex; // protects sScalingFds[] after initialization }; } // namespace android Loading libs/cpustats/ThreadCpuUsage.cpp +22 −19 Original line number Diff line number Diff line Loading @@ -165,6 +165,7 @@ void ThreadCpuUsage::resetElapsed() int ThreadCpuUsage::sScalingFds[ThreadCpuUsage::MAX_CPU]; pthread_once_t ThreadCpuUsage::sOnceControl = PTHREAD_ONCE_INIT; int ThreadCpuUsage::sKernelMax; pthread_mutex_t ThreadCpuUsage::sMutex = PTHREAD_MUTEX_INITIALIZER; /*static*/ void ThreadCpuUsage::init() Loading Loading @@ -195,27 +196,10 @@ void ThreadCpuUsage::init() } else { ALOGW("Can't open number of CPUs"); } // open fd to each frequency per CPU #define FREQ_SIZE 64 char freq_path[FREQ_SIZE]; #define FREQ_DIGIT 27 COMPILE_TIME_ASSERT_FUNCTION_SCOPE(MAX_CPU <= 10); strlcpy(freq_path, "/sys/devices/system/cpu/cpu?/cpufreq/scaling_cur_freq", sizeof(freq_path)); int i; for (i = 0; i < MAX_CPU; ++i) { sScalingFds[i] = -1; } for (i = 0; i < sKernelMax; ++i) { freq_path[FREQ_DIGIT] = i + '0'; fd = open(freq_path, O_RDONLY); if (fd >= 0) { // keep this fd until process exit sScalingFds[i] = fd; } else { ALOGW("Can't open CPU %d", i); } } } uint32_t ThreadCpuUsage::getCpukHz(int cpuNum) Loading @@ -224,11 +208,30 @@ uint32_t ThreadCpuUsage::getCpukHz(int cpuNum) ALOGW("getCpukHz called with invalid CPU %d", cpuNum); return 0; } // double-checked locking idiom is not broken for atomic values such as fd int fd = sScalingFds[cpuNum]; if (fd < 0) { ALOGW("getCpukHz called for unopened CPU %d", cpuNum); // some kernels can't open a scaling file until hot plug complete pthread_mutex_lock(&sMutex); fd = sScalingFds[cpuNum]; if (fd < 0) { #define FREQ_SIZE 64 char freq_path[FREQ_SIZE]; #define FREQ_DIGIT 27 COMPILE_TIME_ASSERT_FUNCTION_SCOPE(MAX_CPU <= 10); #define FREQ_PATH "/sys/devices/system/cpu/cpu?/cpufreq/scaling_cur_freq" strlcpy(freq_path, FREQ_PATH, sizeof(freq_path)); freq_path[FREQ_DIGIT] = cpuNum + '0'; fd = open(freq_path, O_RDONLY | O_CLOEXEC); // keep this fd until process exit or exec sScalingFds[cpuNum] = fd; } pthread_mutex_unlock(&sMutex); if (fd < 0) { ALOGW("getCpukHz can't open CPU %d", cpuNum); return 0; } } #define KHZ_SIZE 12 char kHz[KHZ_SIZE]; // kHz base 10 ssize_t actual = pread(fd, kHz, sizeof(kHz), (off_t) 0); Loading Loading
include/cpustats/ThreadCpuUsage.h +2 −1 Original line number Diff line number Diff line Loading @@ -131,7 +131,8 @@ private: uint32_t mCurrentkHz[MAX_CPU]; // current CPU frequency in kHz, not static to avoid a race static pthread_once_t sOnceControl; static int sKernelMax; // like MAX_CPU, but determined at runtime == cpu/kernel_max + 1 static void init(); static void init(); // called once at first ThreadCpuUsage construction static pthread_mutex_t sMutex; // protects sScalingFds[] after initialization }; } // namespace android Loading
libs/cpustats/ThreadCpuUsage.cpp +22 −19 Original line number Diff line number Diff line Loading @@ -165,6 +165,7 @@ void ThreadCpuUsage::resetElapsed() int ThreadCpuUsage::sScalingFds[ThreadCpuUsage::MAX_CPU]; pthread_once_t ThreadCpuUsage::sOnceControl = PTHREAD_ONCE_INIT; int ThreadCpuUsage::sKernelMax; pthread_mutex_t ThreadCpuUsage::sMutex = PTHREAD_MUTEX_INITIALIZER; /*static*/ void ThreadCpuUsage::init() Loading Loading @@ -195,27 +196,10 @@ void ThreadCpuUsage::init() } else { ALOGW("Can't open number of CPUs"); } // open fd to each frequency per CPU #define FREQ_SIZE 64 char freq_path[FREQ_SIZE]; #define FREQ_DIGIT 27 COMPILE_TIME_ASSERT_FUNCTION_SCOPE(MAX_CPU <= 10); strlcpy(freq_path, "/sys/devices/system/cpu/cpu?/cpufreq/scaling_cur_freq", sizeof(freq_path)); int i; for (i = 0; i < MAX_CPU; ++i) { sScalingFds[i] = -1; } for (i = 0; i < sKernelMax; ++i) { freq_path[FREQ_DIGIT] = i + '0'; fd = open(freq_path, O_RDONLY); if (fd >= 0) { // keep this fd until process exit sScalingFds[i] = fd; } else { ALOGW("Can't open CPU %d", i); } } } uint32_t ThreadCpuUsage::getCpukHz(int cpuNum) Loading @@ -224,11 +208,30 @@ uint32_t ThreadCpuUsage::getCpukHz(int cpuNum) ALOGW("getCpukHz called with invalid CPU %d", cpuNum); return 0; } // double-checked locking idiom is not broken for atomic values such as fd int fd = sScalingFds[cpuNum]; if (fd < 0) { ALOGW("getCpukHz called for unopened CPU %d", cpuNum); // some kernels can't open a scaling file until hot plug complete pthread_mutex_lock(&sMutex); fd = sScalingFds[cpuNum]; if (fd < 0) { #define FREQ_SIZE 64 char freq_path[FREQ_SIZE]; #define FREQ_DIGIT 27 COMPILE_TIME_ASSERT_FUNCTION_SCOPE(MAX_CPU <= 10); #define FREQ_PATH "/sys/devices/system/cpu/cpu?/cpufreq/scaling_cur_freq" strlcpy(freq_path, FREQ_PATH, sizeof(freq_path)); freq_path[FREQ_DIGIT] = cpuNum + '0'; fd = open(freq_path, O_RDONLY | O_CLOEXEC); // keep this fd until process exit or exec sScalingFds[cpuNum] = fd; } pthread_mutex_unlock(&sMutex); if (fd < 0) { ALOGW("getCpukHz can't open CPU %d", cpuNum); return 0; } } #define KHZ_SIZE 12 char kHz[KHZ_SIZE]; // kHz base 10 ssize_t actual = pread(fd, kHz, sizeof(kHz), (off_t) 0); Loading