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