Loading core/jni/android_os_Debug.cpp +39 −9 Original line number Original line Diff line number Diff line Loading @@ -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> Loading @@ -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); } } Loading Loading @@ -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) Loading Loading @@ -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) { { Loading @@ -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; } } Loading core/jni/android_os_Debug.h 0 → 100644 +34 −0 Original line number Original line Diff line number Diff line /* * 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 core/jni/android_util_Process.cpp +4 −9 Original line number Original line Diff line number Diff line Loading @@ -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> Loading Loading @@ -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; } } Loading Loading
core/jni/android_os_Debug.cpp +39 −9 Original line number Original line Diff line number Diff line Loading @@ -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> Loading @@ -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); } } Loading Loading @@ -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) Loading Loading @@ -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) { { Loading @@ -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; } } Loading
core/jni/android_os_Debug.h 0 → 100644 +34 −0 Original line number Original line Diff line number Diff line /* * 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
core/jni/android_util_Process.cpp +4 −9 Original line number Original line Diff line number Diff line Loading @@ -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> Loading Loading @@ -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; } } Loading