1*6777b538SAndroid Build Coastguard Worker // Copyright 2013 The Chromium Authors 2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be 3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file. 4*6777b538SAndroid Build Coastguard Worker 5*6777b538SAndroid Build Coastguard Worker #include "base/process/process_metrics.h" 6*6777b538SAndroid Build Coastguard Worker 7*6777b538SAndroid Build Coastguard Worker #include <limits.h> 8*6777b538SAndroid Build Coastguard Worker #include <stddef.h> 9*6777b538SAndroid Build Coastguard Worker #include <stdint.h> 10*6777b538SAndroid Build Coastguard Worker #include <sys/time.h> 11*6777b538SAndroid Build Coastguard Worker #include <unistd.h> 12*6777b538SAndroid Build Coastguard Worker 13*6777b538SAndroid Build Coastguard Worker #include "base/allocator/buildflags.h" 14*6777b538SAndroid Build Coastguard Worker #include "base/logging.h" 15*6777b538SAndroid Build Coastguard Worker #include "build/blink_buildflags.h" 16*6777b538SAndroid Build Coastguard Worker #include "build/build_config.h" 17*6777b538SAndroid Build Coastguard Worker 18*6777b538SAndroid Build Coastguard Worker #if !BUILDFLAG(IS_FUCHSIA) 19*6777b538SAndroid Build Coastguard Worker #include <sys/resource.h> 20*6777b538SAndroid Build Coastguard Worker #endif 21*6777b538SAndroid Build Coastguard Worker 22*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_APPLE) 23*6777b538SAndroid Build Coastguard Worker #include <malloc/malloc.h> 24*6777b538SAndroid Build Coastguard Worker #else 25*6777b538SAndroid Build Coastguard Worker #include <malloc.h> 26*6777b538SAndroid Build Coastguard Worker #endif 27*6777b538SAndroid Build Coastguard Worker 28*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID) 29*6777b538SAndroid Build Coastguard Worker #include <features.h> 30*6777b538SAndroid Build Coastguard Worker 31*6777b538SAndroid Build Coastguard Worker #include "base/numerics/safe_conversions.h" 32*6777b538SAndroid Build Coastguard Worker #endif 33*6777b538SAndroid Build Coastguard Worker 34*6777b538SAndroid Build Coastguard Worker namespace base { 35*6777b538SAndroid Build Coastguard Worker TimeValToMicroseconds(const struct timeval & tv)36*6777b538SAndroid Build Coastguard Workerint64_t TimeValToMicroseconds(const struct timeval& tv) { 37*6777b538SAndroid Build Coastguard Worker int64_t ret = tv.tv_sec; // Avoid (int * int) integer overflow. 38*6777b538SAndroid Build Coastguard Worker ret *= Time::kMicrosecondsPerSecond; 39*6777b538SAndroid Build Coastguard Worker ret += tv.tv_usec; 40*6777b538SAndroid Build Coastguard Worker return ret; 41*6777b538SAndroid Build Coastguard Worker } 42*6777b538SAndroid Build Coastguard Worker 43*6777b538SAndroid Build Coastguard Worker #if !BUILDFLAG(IS_FUCHSIA) 44*6777b538SAndroid Build Coastguard Worker 45*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) 46*6777b538SAndroid Build Coastguard Worker static const rlim_t kSystemDefaultMaxFds = 8192; 47*6777b538SAndroid Build Coastguard Worker #elif BUILDFLAG(IS_APPLE) 48*6777b538SAndroid Build Coastguard Worker static const rlim_t kSystemDefaultMaxFds = 256; 49*6777b538SAndroid Build Coastguard Worker #elif BUILDFLAG(IS_SOLARIS) 50*6777b538SAndroid Build Coastguard Worker static const rlim_t kSystemDefaultMaxFds = 8192; 51*6777b538SAndroid Build Coastguard Worker #elif BUILDFLAG(IS_FREEBSD) 52*6777b538SAndroid Build Coastguard Worker static const rlim_t kSystemDefaultMaxFds = 8192; 53*6777b538SAndroid Build Coastguard Worker #elif BUILDFLAG(IS_NETBSD) 54*6777b538SAndroid Build Coastguard Worker static const rlim_t kSystemDefaultMaxFds = 1024; 55*6777b538SAndroid Build Coastguard Worker #elif BUILDFLAG(IS_OPENBSD) 56*6777b538SAndroid Build Coastguard Worker static const rlim_t kSystemDefaultMaxFds = 256; 57*6777b538SAndroid Build Coastguard Worker #elif BUILDFLAG(IS_ANDROID) 58*6777b538SAndroid Build Coastguard Worker static const rlim_t kSystemDefaultMaxFds = 1024; 59*6777b538SAndroid Build Coastguard Worker #elif BUILDFLAG(IS_AIX) 60*6777b538SAndroid Build Coastguard Worker static const rlim_t kSystemDefaultMaxFds = 8192; 61*6777b538SAndroid Build Coastguard Worker #endif 62*6777b538SAndroid Build Coastguard Worker GetMaxFds()63*6777b538SAndroid Build Coastguard Workersize_t GetMaxFds() { 64*6777b538SAndroid Build Coastguard Worker rlim_t max_fds; 65*6777b538SAndroid Build Coastguard Worker struct rlimit nofile; 66*6777b538SAndroid Build Coastguard Worker if (getrlimit(RLIMIT_NOFILE, &nofile)) { 67*6777b538SAndroid Build Coastguard Worker // getrlimit failed. Take a best guess. 68*6777b538SAndroid Build Coastguard Worker max_fds = kSystemDefaultMaxFds; 69*6777b538SAndroid Build Coastguard Worker RAW_LOG(ERROR, "getrlimit(RLIMIT_NOFILE) failed"); 70*6777b538SAndroid Build Coastguard Worker } else { 71*6777b538SAndroid Build Coastguard Worker max_fds = nofile.rlim_cur; 72*6777b538SAndroid Build Coastguard Worker } 73*6777b538SAndroid Build Coastguard Worker 74*6777b538SAndroid Build Coastguard Worker if (max_fds > INT_MAX) 75*6777b538SAndroid Build Coastguard Worker max_fds = INT_MAX; 76*6777b538SAndroid Build Coastguard Worker 77*6777b538SAndroid Build Coastguard Worker return static_cast<size_t>(max_fds); 78*6777b538SAndroid Build Coastguard Worker } 79*6777b538SAndroid Build Coastguard Worker GetHandleLimit()80*6777b538SAndroid Build Coastguard Workersize_t GetHandleLimit() { 81*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_APPLE) 82*6777b538SAndroid Build Coastguard Worker // Taken from a small test that allocated ports in a loop. 83*6777b538SAndroid Build Coastguard Worker return static_cast<size_t>(1 << 18); 84*6777b538SAndroid Build Coastguard Worker #else 85*6777b538SAndroid Build Coastguard Worker return GetMaxFds(); 86*6777b538SAndroid Build Coastguard Worker #endif 87*6777b538SAndroid Build Coastguard Worker } 88*6777b538SAndroid Build Coastguard Worker IncreaseFdLimitTo(unsigned int max_descriptors)89*6777b538SAndroid Build Coastguard Workervoid IncreaseFdLimitTo(unsigned int max_descriptors) { 90*6777b538SAndroid Build Coastguard Worker struct rlimit limits; 91*6777b538SAndroid Build Coastguard Worker if (getrlimit(RLIMIT_NOFILE, &limits) == 0) { 92*6777b538SAndroid Build Coastguard Worker rlim_t new_limit = max_descriptors; 93*6777b538SAndroid Build Coastguard Worker if (max_descriptors <= limits.rlim_cur) 94*6777b538SAndroid Build Coastguard Worker return; 95*6777b538SAndroid Build Coastguard Worker if (limits.rlim_max > 0 && limits.rlim_max < max_descriptors) { 96*6777b538SAndroid Build Coastguard Worker new_limit = limits.rlim_max; 97*6777b538SAndroid Build Coastguard Worker } 98*6777b538SAndroid Build Coastguard Worker limits.rlim_cur = new_limit; 99*6777b538SAndroid Build Coastguard Worker if (setrlimit(RLIMIT_NOFILE, &limits) != 0) { 100*6777b538SAndroid Build Coastguard Worker PLOG(INFO) << "Failed to set file descriptor limit"; 101*6777b538SAndroid Build Coastguard Worker } 102*6777b538SAndroid Build Coastguard Worker } else { 103*6777b538SAndroid Build Coastguard Worker PLOG(INFO) << "Failed to get file descriptor limit"; 104*6777b538SAndroid Build Coastguard Worker } 105*6777b538SAndroid Build Coastguard Worker } 106*6777b538SAndroid Build Coastguard Worker 107*6777b538SAndroid Build Coastguard Worker #endif // !BUILDFLAG(IS_FUCHSIA) 108*6777b538SAndroid Build Coastguard Worker 109*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID) 110*6777b538SAndroid Build Coastguard Worker namespace { 111*6777b538SAndroid Build Coastguard Worker GetMallocUsageMallinfo()112*6777b538SAndroid Build Coastguard Workersize_t GetMallocUsageMallinfo() { 113*6777b538SAndroid Build Coastguard Worker #if defined(__GLIBC__) && defined(__GLIBC_PREREQ) 114*6777b538SAndroid Build Coastguard Worker #if __GLIBC_PREREQ(2, 33) 115*6777b538SAndroid Build Coastguard Worker #define MALLINFO2_FOUND_IN_LIBC 116*6777b538SAndroid Build Coastguard Worker struct mallinfo2 minfo = mallinfo2(); 117*6777b538SAndroid Build Coastguard Worker #endif 118*6777b538SAndroid Build Coastguard Worker #endif // defined(__GLIBC__) && defined(__GLIBC_PREREQ) 119*6777b538SAndroid Build Coastguard Worker #if !defined(MALLINFO2_FOUND_IN_LIBC) 120*6777b538SAndroid Build Coastguard Worker struct mallinfo minfo = mallinfo(); 121*6777b538SAndroid Build Coastguard Worker #endif 122*6777b538SAndroid Build Coastguard Worker #undef MALLINFO2_FOUND_IN_LIBC 123*6777b538SAndroid Build Coastguard Worker return checked_cast<size_t>(minfo.hblkhd + minfo.arena); 124*6777b538SAndroid Build Coastguard Worker } 125*6777b538SAndroid Build Coastguard Worker 126*6777b538SAndroid Build Coastguard Worker } // namespace 127*6777b538SAndroid Build Coastguard Worker #endif // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || 128*6777b538SAndroid Build Coastguard Worker // BUILDFLAG(IS_ANDROID) 129*6777b538SAndroid Build Coastguard Worker GetMallocUsage()130*6777b538SAndroid Build Coastguard Workersize_t ProcessMetrics::GetMallocUsage() { 131*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_APPLE) 132*6777b538SAndroid Build Coastguard Worker malloc_statistics_t stats = {0}; 133*6777b538SAndroid Build Coastguard Worker malloc_zone_statistics(nullptr, &stats); 134*6777b538SAndroid Build Coastguard Worker return stats.size_in_use; 135*6777b538SAndroid Build Coastguard Worker #elif BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID) 136*6777b538SAndroid Build Coastguard Worker return GetMallocUsageMallinfo(); 137*6777b538SAndroid Build Coastguard Worker #elif BUILDFLAG(IS_FUCHSIA) 138*6777b538SAndroid Build Coastguard Worker // TODO(fuchsia): Not currently exposed. https://crbug.com/735087. 139*6777b538SAndroid Build Coastguard Worker return 0; 140*6777b538SAndroid Build Coastguard Worker #endif 141*6777b538SAndroid Build Coastguard Worker } 142*6777b538SAndroid Build Coastguard Worker 143*6777b538SAndroid Build Coastguard Worker } // namespace base 144