blob: 50e5ad4b8519a6282f8abd04f12a79d886c8d6c9 [file] [log] [blame]
// Copyright 2019 The Fuchsia 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 <fuchsia/scheduler/cpp/fidl.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/async-loop/default.h>
#include <lib/fdio/directory.h>
#include <lib/syslog/cpp/macros.h>
#include <lib/trace-provider/provider.h>
#include <filesystem>
#include "src/developer/memory/monitor/monitor.h"
#include "src/lib/fxl/command_line.h"
#include "src/lib/fxl/log_settings_command_line.h"
namespace {
const char kRamDeviceClassPath[] = "/dev/class/aml-ram";
void SetRamDevice(monitor::Monitor* app) {
// Look for optional RAM device that provides bandwidth measurement interface.
fuchsia::hardware::ram::metrics::DevicePtr ram_device;
if (std::filesystem::exists(kRamDeviceClassPath)) {
for (const auto& entry : std::filesystem::directory_iterator(kRamDeviceClassPath)) {
int fd = open(entry.path().c_str(), O_RDWR);
if (fd > -1) {
zx::channel handle;
zx_status_t status = fdio_get_service_handle(fd, handle.reset_and_get_address());
if (status == ZX_OK) {
ram_device.Bind(std::move(handle));
app->SetRamDevice(std::move(ram_device));
FX_LOGS(INFO) << "Will collect memory bandwidth measurements.";
return;
}
break;
}
}
}
FX_LOGS(INFO) << "CANNOT collect memory bandwidth measurements.";
}
const char kNotfiyCrashReporterPath[] = "/config/data/send_critical_pressure_crash_reports";
bool SendCriticalMemoryPressureCrashReports() {
return std::filesystem::exists(kNotfiyCrashReporterPath);
}
} // namespace
int main(int argc, const char** argv) {
auto command_line = fxl::CommandLineFromArgcArgv(argc, argv);
if (!fxl::SetLogSettingsFromCommandLine(command_line, {"memory_monitor"}))
return 1;
FX_VLOGS(2) << argv[0] << ": starting";
async::Loop loop(&kAsyncLoopConfigAttachToCurrentThread);
trace::TraceProviderWithFdio trace_provider(loop.dispatcher(), monitor::Monitor::kTraceName);
std::unique_ptr<sys::ComponentContext> startup_context =
sys::ComponentContext::CreateAndServeOutgoingDirectory();
// Lower the priority.
fuchsia::scheduler::ProfileProviderSyncPtr profile_provider;
startup_context->svc()->Connect<fuchsia::scheduler::ProfileProvider>(
profile_provider.NewRequest());
zx_status_t fidl_status;
zx::profile profile;
auto status = profile_provider->GetProfile(8 /* LOW_PRIORITY */, "memory_monitor.cmx",
&fidl_status, &profile);
FX_CHECK(status == ZX_OK);
FX_CHECK(fidl_status == ZX_OK);
auto set_status = zx_object_set_profile(zx_thread_self(), profile.get(), 0);
FX_CHECK(set_status == ZX_OK);
monitor::Monitor app(std::move(startup_context), command_line, loop.dispatcher(),
true /* send_metrics */, true /* watch_memory_pressure */,
SendCriticalMemoryPressureCrashReports());
SetRamDevice(&app);
loop.Run();
FX_VLOGS(2) << argv[0] << ": exiting";
return 0;
}