#include "base/process/memory.h"
#include <stddef.h>
#include <new>
#include "base/allocator/buildflags.h"
#include "base/allocator/partition_allocator/shim/allocator_shim.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/logging.h"
#include "base/process/internal_linux.h"
#include "base/strings/string_number_conversions.h"
#include "base/threading/thread_restrictions.h"
#include "build/build_config.h"
namespace base {
namespace {
void ReleaseReservationOrTerminate() {
if (internal::ReleaseAddressSpaceReservation())
return;
TerminateBecauseOutOfMemory(0);
}
}
void EnableTerminationOnHeapCorruption() {
}
void EnableTerminationOnOutOfMemory() {
std::set_new_handler(&ReleaseReservationOrTerminate);
#if BUILDFLAG(USE_ALLOCATOR_SHIM)
allocator_shim::SetCallNewHandlerOnMallocFailure(true);
#endif
}
class AdjustOOMScoreHelper {
public:
AdjustOOMScoreHelper() = delete;
AdjustOOMScoreHelper(const AdjustOOMScoreHelper&) = delete;
AdjustOOMScoreHelper& operator=(const AdjustOOMScoreHelper&) = delete;
static bool AdjustOOMScore(ProcessId process, int score);
};
bool AdjustOOMScoreHelper::AdjustOOMScore(ProcessId process, int score) {
if (score < 0 || score > kMaxOomScore)
return false;
FilePath oom_path(internal::GetProcPidDir(process));
base::ScopedAllowBlocking allow_blocking;
FilePath oom_file = oom_path.AppendASCII("oom_score_adj");
if (PathExists(oom_file)) {
std::string score_str = NumberToString(score);
DVLOG(1) << "Adjusting oom_score_adj of " << process << " to "
<< score_str;
int score_len = static_cast<int>(score_str.length());
return (score_len == WriteFile(oom_file, score_str.c_str(), score_len));
}
oom_file = oom_path.AppendASCII("oom_adj");
if (PathExists(oom_file)) {
const int kMaxOldOomScore = 15;
int converted_score = score * kMaxOldOomScore / kMaxOomScore;
std::string score_str = NumberToString(converted_score);
DVLOG(1) << "Adjusting oom_adj of " << process << " to " << score_str;
int score_len = static_cast<int>(score_str.length());
return (score_len == WriteFile(oom_file, score_str.c_str(), score_len));
}
return false;
}
bool AdjustOOMScore(ProcessId process, int score) {
return AdjustOOMScoreHelper::AdjustOOMScore(process, score);
}
bool UncheckedMalloc(size_t size, void** result) {
#if BUILDFLAG(USE_ALLOCATOR_SHIM)
*result = allocator_shim::UncheckedAlloc(size);
#elif defined(MEMORY_TOOL_REPLACES_ALLOCATOR) || !defined(LIBC_GLIBC)
*result = malloc(size);
#elif defined(LIBC_GLIBC)
*result = __libc_malloc(size);
#endif
return *result != nullptr;
}
void UncheckedFree(void* ptr) {
#if BUILDFLAG(USE_ALLOCATOR_SHIM)
allocator_shim::UncheckedFree(ptr);
#elif defined(MEMORY_TOOL_REPLACES_ALLOCATOR) || !defined(LIBC_GLIBC)
free(ptr);
#elif defined(LIBC_GLIBC)
__libc_free(ptr);
#endif
}
}