Merge "Use /proc/pid/smaps_rollup when available" into oc-mr1-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
ea7a45eb43
@@ -29,6 +29,7 @@
|
|||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <atomic>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
@@ -44,16 +45,11 @@
|
|||||||
#include "jni.h"
|
#include "jni.h"
|
||||||
#include <memtrack/memtrack.h>
|
#include <memtrack/memtrack.h>
|
||||||
#include <memunreachable/memunreachable.h>
|
#include <memunreachable/memunreachable.h>
|
||||||
|
#include "android_os_Debug.h"
|
||||||
|
|
||||||
namespace android
|
namespace android
|
||||||
{
|
{
|
||||||
|
|
||||||
static void safeFclose(FILE* fp) {
|
|
||||||
if (fp) fclose(fp);
|
|
||||||
}
|
|
||||||
|
|
||||||
using UniqueFile = std::unique_ptr<FILE, decltype(&safeFclose)>;
|
|
||||||
|
|
||||||
static inline UniqueFile MakeUniqueFile(const char* path, const char* mode) {
|
static inline UniqueFile MakeUniqueFile(const char* path, const char* mode) {
|
||||||
return UniqueFile(fopen(path, mode), safeFclose);
|
return UniqueFile(fopen(path, mode), safeFclose);
|
||||||
}
|
}
|
||||||
@@ -155,6 +151,14 @@ struct stats_t {
|
|||||||
int swappedOutPss;
|
int swappedOutPss;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum pss_rollup_support {
|
||||||
|
PSS_ROLLUP_UNTRIED,
|
||||||
|
PSS_ROLLUP_SUPPORTED,
|
||||||
|
PSS_ROLLUP_UNSUPPORTED
|
||||||
|
};
|
||||||
|
|
||||||
|
static std::atomic<pss_rollup_support> g_pss_rollup_support;
|
||||||
|
|
||||||
#define BINDER_STATS "/proc/binder/stats"
|
#define BINDER_STATS "/proc/binder/stats"
|
||||||
|
|
||||||
static jlong android_os_Debug_getNativeHeapSize(JNIEnv *env, jobject clazz)
|
static jlong android_os_Debug_getNativeHeapSize(JNIEnv *env, jobject clazz)
|
||||||
@@ -548,6 +552,33 @@ static void android_os_Debug_getDirtyPages(JNIEnv *env, jobject clazz, jobject o
|
|||||||
android_os_Debug_getDirtyPagesPid(env, clazz, getpid(), object);
|
android_os_Debug_getDirtyPagesPid(env, clazz, getpid(), object);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UniqueFile OpenSmapsOrRollup(int pid)
|
||||||
|
{
|
||||||
|
enum pss_rollup_support rollup_support =
|
||||||
|
g_pss_rollup_support.load(std::memory_order_relaxed);
|
||||||
|
if (rollup_support != PSS_ROLLUP_UNSUPPORTED) {
|
||||||
|
std::string smaps_rollup_path =
|
||||||
|
base::StringPrintf("/proc/%d/smaps_rollup", pid);
|
||||||
|
UniqueFile fp_rollup = MakeUniqueFile(smaps_rollup_path.c_str(), "re");
|
||||||
|
if (fp_rollup == nullptr && errno != ENOENT) {
|
||||||
|
return fp_rollup; // Actual error, not just old kernel.
|
||||||
|
}
|
||||||
|
if (fp_rollup != nullptr) {
|
||||||
|
if (rollup_support == PSS_ROLLUP_UNTRIED) {
|
||||||
|
ALOGI("using rollup pss collection");
|
||||||
|
g_pss_rollup_support.store(PSS_ROLLUP_SUPPORTED,
|
||||||
|
std::memory_order_relaxed);
|
||||||
|
}
|
||||||
|
return fp_rollup;
|
||||||
|
}
|
||||||
|
g_pss_rollup_support.store(PSS_ROLLUP_UNSUPPORTED,
|
||||||
|
std::memory_order_relaxed);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string smaps_path = base::StringPrintf("/proc/%d/smaps", pid);
|
||||||
|
return MakeUniqueFile(smaps_path.c_str(), "re");
|
||||||
|
}
|
||||||
|
|
||||||
static jlong android_os_Debug_getPssPid(JNIEnv *env, jobject clazz, jint pid,
|
static jlong android_os_Debug_getPssPid(JNIEnv *env, jobject clazz, jint pid,
|
||||||
jlongArray outUssSwapPss, jlongArray outMemtrack)
|
jlongArray outUssSwapPss, jlongArray outMemtrack)
|
||||||
{
|
{
|
||||||
@@ -563,12 +594,11 @@ static jlong android_os_Debug_getPssPid(JNIEnv *env, jobject clazz, jint pid,
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
std::string smaps_path = base::StringPrintf("/proc/%d/smaps", pid);
|
UniqueFile fp = OpenSmapsOrRollup(pid);
|
||||||
UniqueFile fp = MakeUniqueFile(smaps_path.c_str(), "re");
|
|
||||||
|
|
||||||
if (fp != nullptr) {
|
if (fp != nullptr) {
|
||||||
while (true) {
|
while (true) {
|
||||||
if (fgets(line, 1024, fp.get()) == NULL) {
|
if (fgets(line, sizeof (line), fp.get()) == NULL) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
34
core/jni/android_os_Debug.h
Normal file
34
core/jni/android_os_Debug.h
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2016 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ANDROID_OS_DEBUG_H
|
||||||
|
#define ANDROID_OS_DEBUG_H
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
namespace android {
|
||||||
|
|
||||||
|
inline void safeFclose(FILE* fp) {
|
||||||
|
if (fp) fclose(fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
using UniqueFile = std::unique_ptr<FILE, decltype(&safeFclose)>;
|
||||||
|
UniqueFile OpenSmapsOrRollup(int pid);
|
||||||
|
|
||||||
|
} // namespace android
|
||||||
|
|
||||||
|
#endif // ANDROID_OS_HW_BLOB_H
|
||||||
@@ -31,6 +31,7 @@
|
|||||||
|
|
||||||
#include "android_util_Binder.h"
|
#include "android_util_Binder.h"
|
||||||
#include <nativehelper/JNIHelp.h>
|
#include <nativehelper/JNIHelp.h>
|
||||||
|
#include "android_os_Debug.h"
|
||||||
|
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
@@ -1092,27 +1093,21 @@ static jlong android_os_Process_getElapsedCpuTime(JNIEnv* env, jobject clazz)
|
|||||||
|
|
||||||
static jlong android_os_Process_getPss(JNIEnv* env, jobject clazz, jint pid)
|
static jlong android_os_Process_getPss(JNIEnv* env, jobject clazz, jint pid)
|
||||||
{
|
{
|
||||||
char filename[64];
|
UniqueFile file = OpenSmapsOrRollup(pid);
|
||||||
|
if (file == nullptr) {
|
||||||
snprintf(filename, sizeof(filename), "/proc/%" PRId32 "/smaps", pid);
|
|
||||||
|
|
||||||
FILE * file = fopen(filename, "r");
|
|
||||||
if (!file) {
|
|
||||||
return (jlong) -1;
|
return (jlong) -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tally up all of the Pss from the various maps
|
// Tally up all of the Pss from the various maps
|
||||||
char line[256];
|
char line[256];
|
||||||
jlong pss = 0;
|
jlong pss = 0;
|
||||||
while (fgets(line, sizeof(line), file)) {
|
while (fgets(line, sizeof(line), file.get())) {
|
||||||
jlong v;
|
jlong v;
|
||||||
if (sscanf(line, "Pss: %" SCNd64 " kB", &v) == 1) {
|
if (sscanf(line, "Pss: %" SCNd64 " kB", &v) == 1) {
|
||||||
pss += v;
|
pss += v;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(file);
|
|
||||||
|
|
||||||
// Return the Pss value in bytes, not kilobytes
|
// Return the Pss value in bytes, not kilobytes
|
||||||
return pss * 1024;
|
return pss * 1024;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user