1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright 2014 Google Inc. 3cb93a386Sopenharmony_ci * 4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be 5cb93a386Sopenharmony_ci * found in the LICENSE file. 6cb93a386Sopenharmony_ci */ 7cb93a386Sopenharmony_ci 8cb93a386Sopenharmony_ci#include "include/core/SkTypes.h" 9cb93a386Sopenharmony_ci#include "tools/ProcStats.h" 10cb93a386Sopenharmony_ci 11cb93a386Sopenharmony_ci#if defined(__Fuchsia__) 12cb93a386Sopenharmony_ci #include <zircon/process.h> 13cb93a386Sopenharmony_ci #include <zircon/syscalls.h> 14cb93a386Sopenharmony_ci #include <zircon/syscalls/object.h> 15cb93a386Sopenharmony_ci #include <zircon/types.h> 16cb93a386Sopenharmony_ci 17cb93a386Sopenharmony_ci int64_t sk_tools::getMaxResidentSetSizeBytes() { 18cb93a386Sopenharmony_ci zx_info_task_stats_t task_stats; 19cb93a386Sopenharmony_ci zx_handle_t process = zx_process_self(); 20cb93a386Sopenharmony_ci zx_status_t status = zx_object_get_info( 21cb93a386Sopenharmony_ci process, ZX_INFO_TASK_STATS, &task_stats, sizeof(task_stats), NULL, NULL); 22cb93a386Sopenharmony_ci if (status != ZX_OK) { 23cb93a386Sopenharmony_ci return -1; 24cb93a386Sopenharmony_ci } 25cb93a386Sopenharmony_ci return (task_stats.mem_private_bytes + task_stats.mem_shared_bytes); 26cb93a386Sopenharmony_ci } 27cb93a386Sopenharmony_ci#elif defined(SK_BUILD_FOR_UNIX) || defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS) || defined(SK_BUILD_FOR_ANDROID) 28cb93a386Sopenharmony_ci #include <sys/resource.h> 29cb93a386Sopenharmony_ci int64_t sk_tools::getMaxResidentSetSizeBytes() { 30cb93a386Sopenharmony_ci struct rusage ru; 31cb93a386Sopenharmony_ci getrusage(RUSAGE_SELF, &ru); 32cb93a386Sopenharmony_ci #if defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS) 33cb93a386Sopenharmony_ci return ru.ru_maxrss; // Darwin reports bytes. 34cb93a386Sopenharmony_ci #else 35cb93a386Sopenharmony_ci return ru.ru_maxrss * 1024; // Linux reports kilobytes. 36cb93a386Sopenharmony_ci #endif 37cb93a386Sopenharmony_ci } 38cb93a386Sopenharmony_ci#elif defined(SK_BUILD_FOR_WIN) 39cb93a386Sopenharmony_ci #include <windows.h> 40cb93a386Sopenharmony_ci #include <psapi.h> 41cb93a386Sopenharmony_ci int64_t sk_tools::getMaxResidentSetSizeBytes() { 42cb93a386Sopenharmony_ci PROCESS_MEMORY_COUNTERS info; 43cb93a386Sopenharmony_ci GetProcessMemoryInfo(GetCurrentProcess(), &info, sizeof(info)); 44cb93a386Sopenharmony_ci return info.PeakWorkingSetSize; 45cb93a386Sopenharmony_ci } 46cb93a386Sopenharmony_ci#else 47cb93a386Sopenharmony_ci int64_t sk_tools::getMaxResidentSetSizeBytes() { return -1; } 48cb93a386Sopenharmony_ci#endif 49cb93a386Sopenharmony_ci 50cb93a386Sopenharmony_ci#if defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS) 51cb93a386Sopenharmony_ci #include <mach/mach.h> 52cb93a386Sopenharmony_ci int64_t sk_tools::getCurrResidentSetSizeBytes() { 53cb93a386Sopenharmony_ci mach_task_basic_info info; 54cb93a386Sopenharmony_ci mach_msg_type_number_t count = MACH_TASK_BASIC_INFO_COUNT; 55cb93a386Sopenharmony_ci if (KERN_SUCCESS != 56cb93a386Sopenharmony_ci task_info(mach_task_self(), MACH_TASK_BASIC_INFO, (task_info_t)&info, &count)) { 57cb93a386Sopenharmony_ci return -1; 58cb93a386Sopenharmony_ci } 59cb93a386Sopenharmony_ci return info.resident_size; 60cb93a386Sopenharmony_ci } 61cb93a386Sopenharmony_ci#elif defined(SK_BUILD_FOR_UNIX) || defined(SK_BUILD_FOR_ANDROID) // N.B. /proc is Linux-only. 62cb93a386Sopenharmony_ci #include <unistd.h> 63cb93a386Sopenharmony_ci #include <stdio.h> 64cb93a386Sopenharmony_ci int64_t sk_tools::getCurrResidentSetSizeBytes() { 65cb93a386Sopenharmony_ci const long pageSize = sysconf(_SC_PAGESIZE); 66cb93a386Sopenharmony_ci long long rssPages = 0; 67cb93a386Sopenharmony_ci if (FILE* statm = fopen("/proc/self/statm", "r")) { 68cb93a386Sopenharmony_ci // statm contains: program-size rss shared text lib data dirty, all in page counts. 69cb93a386Sopenharmony_ci int rc = fscanf(statm, "%*d %lld", &rssPages); 70cb93a386Sopenharmony_ci fclose(statm); 71cb93a386Sopenharmony_ci if (rc != 1) { 72cb93a386Sopenharmony_ci return -1; 73cb93a386Sopenharmony_ci } 74cb93a386Sopenharmony_ci } 75cb93a386Sopenharmony_ci return rssPages * pageSize; 76cb93a386Sopenharmony_ci } 77cb93a386Sopenharmony_ci#elif defined(SK_BUILD_FOR_WIN) 78cb93a386Sopenharmony_ci int64_t sk_tools::getCurrResidentSetSizeBytes() { 79cb93a386Sopenharmony_ci PROCESS_MEMORY_COUNTERS info; 80cb93a386Sopenharmony_ci GetProcessMemoryInfo(GetCurrentProcess(), &info, sizeof(info)); 81cb93a386Sopenharmony_ci return info.WorkingSetSize; 82cb93a386Sopenharmony_ci } 83cb93a386Sopenharmony_ci#else 84cb93a386Sopenharmony_ci int64_t sk_tools::getCurrResidentSetSizeBytes() { return -1; } 85cb93a386Sopenharmony_ci#endif 86cb93a386Sopenharmony_ci 87cb93a386Sopenharmony_ciint sk_tools::getMaxResidentSetSizeMB() { 88cb93a386Sopenharmony_ci int64_t bytes = sk_tools::getMaxResidentSetSizeBytes(); 89cb93a386Sopenharmony_ci return bytes < 0 ? -1 : static_cast<int>(bytes / 1024 / 1024); 90cb93a386Sopenharmony_ci} 91cb93a386Sopenharmony_ci 92cb93a386Sopenharmony_ciint sk_tools::getCurrResidentSetSizeMB() { 93cb93a386Sopenharmony_ci int64_t bytes = sk_tools::getCurrResidentSetSizeBytes(); 94cb93a386Sopenharmony_ci return bytes < 0 ? -1 : static_cast<int>(bytes / 1024 / 1024); 95cb93a386Sopenharmony_ci} 96