summaryrefslogtreecommitdiff
path: root/chromium/base/process/process_metrics_posix.cc
blob: 9d12c427bb30ab820aa0e6eaecd4e22cfe0e535b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/process/process_metrics.h"

#include <limits.h>
#include <stddef.h>
#include <stdint.h>
#include <sys/time.h>
#include <unistd.h>

#include "base/allocator/buildflags.h"
#include "base/logging.h"
#include "build/build_config.h"

#if !defined(OS_FUCHSIA)
#include <sys/resource.h>
#endif

#if defined(OS_APPLE)
#include <malloc/malloc.h>
#else
#include <malloc.h>
#endif

namespace base {

int64_t TimeValToMicroseconds(const struct timeval& tv) {
  int64_t ret = tv.tv_sec;  // Avoid (int * int) integer overflow.
  ret *= Time::kMicrosecondsPerSecond;
  ret += tv.tv_usec;
  return ret;
}

ProcessMetrics::~ProcessMetrics() = default;

#if !defined(OS_FUCHSIA)

#if defined(OS_LINUX) || defined(OS_CHROMEOS)
static const rlim_t kSystemDefaultMaxFds = 8192;
#elif defined(OS_APPLE)
static const rlim_t kSystemDefaultMaxFds = 256;
#elif defined(OS_SOLARIS)
static const rlim_t kSystemDefaultMaxFds = 8192;
#elif defined(OS_FREEBSD)
static const rlim_t kSystemDefaultMaxFds = 8192;
#elif defined(OS_NETBSD)
static const rlim_t kSystemDefaultMaxFds = 1024;
#elif defined(OS_OPENBSD)
static const rlim_t kSystemDefaultMaxFds = 256;
#elif defined(OS_ANDROID)
static const rlim_t kSystemDefaultMaxFds = 1024;
#elif defined(OS_AIX)
static const rlim_t kSystemDefaultMaxFds = 8192;
#endif

size_t GetMaxFds() {
  rlim_t max_fds;
  struct rlimit nofile;
  if (getrlimit(RLIMIT_NOFILE, &nofile)) {
    // getrlimit failed. Take a best guess.
    max_fds = kSystemDefaultMaxFds;
    RAW_LOG(ERROR, "getrlimit(RLIMIT_NOFILE) failed");
  } else {
    max_fds = nofile.rlim_cur;
  }

  if (max_fds > INT_MAX)
    max_fds = INT_MAX;

  return static_cast<size_t>(max_fds);
}

size_t GetHandleLimit() {
#if defined(OS_APPLE)
  // Taken from a small test that allocated ports in a loop.
  return static_cast<size_t>(1 << 18);
#else
  return GetMaxFds();
#endif
}

void IncreaseFdLimitTo(unsigned int max_descriptors) {
  struct rlimit limits;
  if (getrlimit(RLIMIT_NOFILE, &limits) == 0) {
    unsigned int new_limit = max_descriptors;
    if (max_descriptors <= limits.rlim_cur)
      return;
    if (limits.rlim_max > 0 && limits.rlim_max < max_descriptors) {
      new_limit = limits.rlim_max;
    }
    limits.rlim_cur = new_limit;
    if (setrlimit(RLIMIT_NOFILE, &limits) != 0) {
      PLOG(INFO) << "Failed to set file descriptor limit";
    }
  } else {
    PLOG(INFO) << "Failed to get file descriptor limit";
  }
}

#endif  // !defined(OS_FUCHSIA)

size_t GetPageSize() {
  static const size_t pagesize = []() -> size_t {
  // For more information see getpagesize(2). Portable applications should use
  // sysconf(_SC_PAGESIZE) rather than getpagesize() if it's available.
#if defined(_SC_PAGESIZE)
    return sysconf(_SC_PAGESIZE);
#else
    return getpagesize();
#endif
  }();
  return pagesize;
}

size_t ProcessMetrics::GetMallocUsage() {
#if defined(OS_APPLE)
  malloc_statistics_t stats = {0};
  malloc_zone_statistics(nullptr, &stats);
  return stats.size_in_use;
#elif defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID)
  struct mallinfo minfo = mallinfo();
#if BUILDFLAG(USE_TCMALLOC)
  return minfo.uordblks;
#else
  return minfo.hblkhd + minfo.arena;
#endif
#elif defined(OS_FUCHSIA)
  // TODO(fuchsia): Not currently exposed. https://crbug.com/735087.
  return 0;
#endif
}

}  // namespace base