21b20696aca32e74f44f830d603290467c365fa1
[platform/framework/web/chromium-efl.git] / base / process / memory_linux.cc
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
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/memory.h"
6
7 #include <stddef.h>
8
9 #include <new>
10
11 #include "base/allocator/allocator_shim.h"
12 #include "base/allocator/buildflags.h"
13 #include "base/files/file_path.h"
14 #include "base/files/file_util.h"
15 #include "base/logging.h"
16 #include "base/process/internal_linux.h"
17 #include "base/strings/string_number_conversions.h"
18 #include "build/build_config.h"
19
20 #if defined(USE_TCMALLOC)
21 #include "third_party/tcmalloc/chromium/src/config.h"
22 #include "third_party/tcmalloc/chromium/src/gperftools/tcmalloc.h"
23 #endif
24
25 namespace base {
26
27 size_t g_oom_size = 0U;
28
29 namespace {
30
31 void OnNoMemorySize(size_t size) {
32   g_oom_size = size;
33
34   if (size != 0)
35     LOG(FATAL) << "Out of memory, size = " << size;
36   LOG(FATAL) << "Out of memory.";
37 }
38
39 void OnNoMemory() {
40   OnNoMemorySize(0);
41 }
42
43 }  // namespace
44
45 void EnableTerminationOnHeapCorruption() {
46   // On Linux, there nothing to do AFAIK.
47 }
48
49 void EnableTerminationOnOutOfMemory() {
50   // Set the new-out of memory handler.
51   std::set_new_handler(&OnNoMemory);
52   // If we're using glibc's allocator, the above functions will override
53   // malloc and friends and make them die on out of memory.
54
55 #if BUILDFLAG(USE_ALLOCATOR_SHIM)
56   allocator::SetCallNewHandlerOnMallocFailure(true);
57 #elif defined(USE_TCMALLOC)
58   // For tcmalloc, we need to tell it to behave like new.
59   tc_set_new_mode(1);
60 #endif
61 }
62
63 // NOTE: This is not the only version of this function in the source:
64 // the setuid sandbox (in process_util_linux.c, in the sandbox source)
65 // also has its own C version.
66 bool AdjustOOMScore(ProcessId process, int score) {
67   if (score < 0 || score > kMaxOomScore)
68     return false;
69
70   FilePath oom_path(internal::GetProcPidDir(process));
71
72   // Attempt to write the newer oom_score_adj file first.
73   FilePath oom_file = oom_path.AppendASCII("oom_score_adj");
74   if (PathExists(oom_file)) {
75     std::string score_str = IntToString(score);
76     DVLOG(1) << "Adjusting oom_score_adj of " << process << " to "
77              << score_str;
78     int score_len = static_cast<int>(score_str.length());
79     return (score_len == WriteFile(oom_file, score_str.c_str(), score_len));
80   }
81
82   // If the oom_score_adj file doesn't exist, then we write the old
83   // style file and translate the oom_adj score to the range 0-15.
84   oom_file = oom_path.AppendASCII("oom_adj");
85   if (PathExists(oom_file)) {
86     // Max score for the old oom_adj range.  Used for conversion of new
87     // values to old values.
88     const int kMaxOldOomScore = 15;
89
90     int converted_score = score * kMaxOldOomScore / kMaxOomScore;
91     std::string score_str = IntToString(converted_score);
92     DVLOG(1) << "Adjusting oom_adj of " << process << " to " << score_str;
93     int score_len = static_cast<int>(score_str.length());
94     return (score_len == WriteFile(oom_file, score_str.c_str(), score_len));
95   }
96
97   return false;
98 }
99
100 bool UncheckedMalloc(size_t size, void** result) {
101 #if BUILDFLAG(USE_ALLOCATOR_SHIM)
102   *result = allocator::UncheckedAlloc(size);
103 #elif defined(MEMORY_TOOL_REPLACES_ALLOCATOR) || \
104     (!defined(LIBC_GLIBC) && !defined(USE_TCMALLOC))
105   *result = malloc(size);
106 #elif defined(LIBC_GLIBC) && !defined(USE_TCMALLOC)
107   *result = __libc_malloc(size);
108 #elif defined(USE_TCMALLOC)
109   *result = tc_malloc_skip_new_handler(size);
110 #endif
111   return *result != nullptr;
112 }
113
114 }  // namespace base