summaryrefslogtreecommitdiffstats
path: root/libs/cpustats
diff options
context:
space:
mode:
authorGlenn Kasten <gkasten@google.com>2012-05-14 10:49:17 -0700
committerGlenn Kasten <gkasten@google.com>2012-05-14 16:55:26 -0700
commit542af12d10e5923a6e811c72e2bbe4e7507b6448 (patch)
tree5e4840966c6ade07f9bfbfc28f6b0546e971a7b0 /libs/cpustats
parentb194ec926bf3fb3c546244b135f602ceb3a0a6b0 (diff)
downloadframeworks_native-542af12d10e5923a6e811c72e2bbe4e7507b6448.zip
frameworks_native-542af12d10e5923a6e811c72e2bbe4e7507b6448.tar.gz
frameworks_native-542af12d10e5923a6e811c72e2bbe4e7507b6448.tar.bz2
Fix log spam about CPU frequency on one device
Previous kernels have allowed opening the CPU frequency file regardless whether the CPU is up or not. This fixes some log spam on one device with dynamic hot plug CPU feature, which does not allow opening the CPU frequency file if CPU is down. Also, since the file descriptors are global and have long lives, add the close-on-exec flag. Change-Id: Ia14a2b9e20038dfb96a573920176a47a96bd3f5a
Diffstat (limited to 'libs/cpustats')
-rw-r--r--libs/cpustats/ThreadCpuUsage.cpp41
1 files changed, 22 insertions, 19 deletions
diff --git a/libs/cpustats/ThreadCpuUsage.cpp b/libs/cpustats/ThreadCpuUsage.cpp
index 99b4c83..637402a 100644
--- a/libs/cpustats/ThreadCpuUsage.cpp
+++ b/libs/cpustats/ThreadCpuUsage.cpp
@@ -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()
@@ -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)
@@ -224,10 +208,29 @@ 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);
- return 0;
+ // 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