blob: ed3adba9a80236f4c307fcadf8ebfbd276c6f030 [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 "src/media/playback/mediaplayer/graph/thread_priority.h"
#include <fuchsia/scheduler/cpp/fidl.h>
#include <lib/fdio/directory.h>
#include <lib/fit/result.h>
#include <lib/syslog/cpp/macros.h>
#include <lib/zx/channel.h>
namespace media_player {
namespace {
constexpr uint32_t kHighPriority = 23;
constexpr char kServicePathPrefix[] = "/svc/";
constexpr char kProfileName[] = "src/media/playback/mediaplayer";
fit::result<zx::unowned_profile, zx_status_t> GetHighPriorityProfile() {
static zx::profile profile;
static zx_status_t status = []() {
zx::channel server_channel, client_channel;
zx_status_t status = zx::channel::create(0u, &server_channel, &client_channel);
if (status != ZX_OK) {
FX_PLOGS(ERROR, status) << "Failed to create a channel pair";
return status;
}
status = fdio_service_connect(
(std::string(kServicePathPrefix) + fuchsia::scheduler::ProfileProvider::Name_).c_str(),
server_channel.release());
if (status != ZX_OK) {
FX_PLOGS(ERROR, status) << "Failed to connect to fuchsia.scheduler.ProfileProvider";
return status;
}
fuchsia::scheduler::ProfileProvider_SyncProxy provider(std::move(client_channel));
zx_status_t get_profile_result_status;
status = provider.GetProfile(kHighPriority, kProfileName, &get_profile_result_status, &profile);
if (status != ZX_OK) {
FX_PLOGS(WARNING, status) << "Failed to call fuchsia.scheduler.GetProfile (normal in tests)";
return status;
}
if (get_profile_result_status != ZX_OK) {
FX_PLOGS(ERROR, get_profile_result_status) << "fuchsia.scheduler.GetProfile returned error";
return get_profile_result_status;
}
return ZX_OK;
}();
if (status != ZX_OK) {
return fit::error(status);
}
return fit::ok<zx::unowned_profile>(zx::unowned_profile{profile});
}
} // namespace
// static
zx_status_t ThreadPriority::SetToHigh(zx::thread* thread) {
auto result = GetHighPriorityProfile();
if (result.is_error()) {
return result.error();
}
zx_status_t status = thread ? thread->set_profile(*result.value(), 0)
: zx::thread::self()->set_profile(*result.value(), 0);
if (status != ZX_OK) {
FX_PLOGS(ERROR, status) << "Failed to set thread profile";
}
return status;
}
} // namespace media_player