libstrat: convert to experimental new (super-accurate) sf allocation semantics

This commit is contained in:
Michael Scire
2021-01-17 07:55:32 -08:00
committed by SciresM
parent 8314d015f3
commit f06de12bea
149 changed files with 2852 additions and 1746 deletions

View File

@@ -24,7 +24,7 @@ namespace ams::capsrv::server {
this->server_manager_holder.emplace();
/* Register the service. */
R_ABORT_UNLESS((this->server_manager_holder->RegisterServer<Interface, Service>(ServiceName, MaxSessions, sf::GetSharedPointerTo<Interface>(*this->service_holder))));
R_ABORT_UNLESS((this->server_manager_holder->RegisterObjectForServer(this->service_holder->GetShared(), ServiceName, MaxSessions)));
/* Initialize the idle event, we're idle initially. */
os::InitializeEvent(std::addressof(this->idle_event), true, os::EventClearMode_ManualClear);

View File

@@ -26,12 +26,12 @@ namespace ams::capsrv::server {
static constexpr inline size_t MaxSessions = 2;
static constexpr inline sm::ServiceName ServiceName = sm::ServiceName::Encode("caps:dc");
using Interface = IDecoderControlService;
using Service = DecoderControlService;
using ServiceHolderType = sf::UnmanagedServiceObject<IDecoderControlService, DecoderControlService>;
using ServerOptions = sf::hipc::DefaultServerManagerOptions;
using ServerManager = sf::hipc::ServerManager<NumServers, ServerOptions, MaxSessions>;
private:
std::optional<Service> service_holder;
std::optional<ServiceHolderType> service_holder;
std::optional<ServerManager> server_manager_holder;
os::EventType idle_event;
public:

View File

@@ -16,17 +16,17 @@
#pragma once
#include <stratosphere.hpp>
#define AMS_CAPSRV_DECODER_CONTROL_SERVICE_INTERFACE_INFO(C, H) \
AMS_SF_METHOD_INFO(C, H, 3001, Result, DecodeJpeg, (const sf::OutNonSecureBuffer &out, const sf::InBuffer &in, u32 width, u32 height, const capsrv::ScreenShotDecodeOption &option), (out, in, width, height, option))
AMS_SF_DEFINE_INTERFACE(ams::capsrv::server, IDecoderControlService, AMS_CAPSRV_DECODER_CONTROL_SERVICE_INTERFACE_INFO)
namespace ams::capsrv::server {
#define AMS_CAPSRV_DECODER_CONTROL_SERVICE_INTERFACE_INFO(C, H) \
AMS_SF_METHOD_INFO(C, H, 3001, Result, DecodeJpeg, (const sf::OutNonSecureBuffer &out, const sf::InBuffer &in, u32 width, u32 height, const ScreenShotDecodeOption &option))
AMS_SF_DEFINE_INTERFACE(IDecoderControlService, AMS_CAPSRV_DECODER_CONTROL_SERVICE_INTERFACE_INFO)
class DecoderControlService final {
public:
Result DecodeJpeg(const sf::OutNonSecureBuffer &out, const sf::InBuffer &in, u32 width, u32 height, const ScreenShotDecodeOption &option);
};
static_assert(IsIDecoderControlService<DecoderControlService>);
}
}

View File

@@ -20,7 +20,7 @@ namespace ams::erpt::srv {
class Attachment;
class AttachmentImpl final {
class AttachmentImpl {
private:
Attachment *attachment;
public:

View File

@@ -18,7 +18,7 @@
namespace ams::erpt::srv {
class ContextImpl final {
class ContextImpl {
public:
Result SubmitContext(const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &data_buffer);
Result CreateReportV0(ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &data_buffer, const ams::sf::InBuffer &meta_buffer);

View File

@@ -24,6 +24,7 @@
namespace ams::erpt::srv {
lmem::HeapHandle g_heap_handle;
ams::sf::ExpHeapAllocator g_sf_allocator;
namespace {
@@ -79,6 +80,8 @@ namespace ams::erpt::srv {
R_ABORT_UNLESS(MountSystemSaveData());
g_sf_allocator.Attach(g_heap_handle);
for (auto i = 0; i < CategoryId_Count; i++) {
Context *ctx = new Context(static_cast<CategoryId>(i), 1);
AMS_ABORT_UNLESS(ctx != nullptr);

View File

@@ -18,7 +18,7 @@
namespace ams::erpt::srv {
class ManagerImpl final : public util::IntrusiveListBaseNode<ManagerImpl> {
class ManagerImpl : public util::IntrusiveListBaseNode<ManagerImpl> {
private:
os::SystemEvent system_event;
public:

View File

@@ -20,7 +20,7 @@ namespace ams::erpt::srv {
class Report;
class ReportImpl final {
class ReportImpl {
private:
Report *report;
public:

View File

@@ -21,6 +21,8 @@
namespace ams::erpt::srv {
extern ams::sf::ExpHeapAllocator g_sf_allocator;
namespace {
struct ErrorReportServerOptions {
@@ -39,26 +41,40 @@ namespace ams::erpt::srv {
alignas(os::ThreadStackAlignment) u8 g_server_thread_stack[16_KB];
enum PortIndex {
PortIndex_Report,
PortIndex_Context,
};
class ErrorReportServiceManager : public ams::sf::hipc::ServerManager<ErrorReportNumServers, ErrorReportServerOptions, ErrorReportMaxSessions> {
private:
os::ThreadType thread;
std::shared_ptr<erpt::sf::IContext> context_session_object;
ams::sf::UnmanagedServiceObject<erpt::sf::IContext, erpt::srv::ContextImpl> context_session_object;
private:
static void ThreadFunction(void *_this) {
reinterpret_cast<ErrorReportServiceManager *>(_this)->SetupAndLoopProcess();
}
void SetupAndLoopProcess();
public:
ErrorReportServiceManager(erpt::srv::ContextImpl *c)
: context_session_object(ams::sf::GetSharedPointerTo<erpt::sf::IContext, erpt::srv::ContextImpl>(c))
{
/* ... */
}
virtual Result OnNeedsToAccept(int port_index, Server *server) override {
switch (port_index) {
case PortIndex_Report:
{
auto intf = ams::sf::ObjectFactory<ams::sf::ExpHeapAllocator::Policy>::CreateSharedEmplaced<erpt::sf::ISession, erpt::srv::SessionImpl>(std::addressof(g_sf_allocator));
AMS_ABORT_UNLESS(intf != nullptr);
return this->AcceptImpl(server, intf);
}
case PortIndex_Context:
return AcceptImpl(server, this->context_session_object.GetShared());
default:
return erpt::ResultNotSupported();
}
}
public:
Result Initialize() {
R_ABORT_UNLESS((this->RegisterServer<erpt::sf::IContext, erpt::srv::ContextImpl>(ErrorReportContextServiceName, ErrorReportContextSessions, this->context_session_object)));
R_ABORT_UNLESS((this->RegisterServer<erpt::sf::ISession, erpt::srv::SessionImpl>(ErrorReportReportServiceName, ErrorReportReportSessions)));
R_ABORT_UNLESS(this->RegisterServer(PortIndex_Context, ErrorReportContextServiceName, ErrorReportContextSessions));
R_ABORT_UNLESS(this->RegisterServer(PortIndex_Report, ErrorReportReportServiceName, ErrorReportReportSessions));
this->ResumeProcessing();
@@ -117,8 +133,7 @@ namespace ams::erpt::srv {
}
}
constinit erpt::srv::ContextImpl g_context_object;
ErrorReportServiceManager g_erpt_server_manager(std::addressof(g_context_object));
ErrorReportServiceManager g_erpt_server_manager;
}

View File

@@ -21,33 +21,32 @@
namespace ams::erpt::srv {
extern ams::sf::ExpHeapAllocator g_sf_allocator;
namespace {
template<typename Interface, typename Impl>
ALWAYS_INLINE Result OpenInterface(ams::sf::Out<std::shared_ptr<Interface>> &out) {
/* Define holder type. */
using Holder = typename Interface::ImplHolder<Impl>;
ALWAYS_INLINE Result OpenInterface(ams::sf::Out<ams::sf::SharedPointer<Interface>> &out) {
/* Create an interface holder. */
auto intf = std::shared_ptr<Holder>(new (std::nothrow) Holder);
auto intf = ams::sf::ObjectFactory<ams::sf::ExpHeapAllocator::Policy>::CreateSharedEmplaced<Interface, Impl>(std::addressof(g_sf_allocator));
R_UNLESS(intf != nullptr, erpt::ResultOutOfMemory());
/* Return it. */
out.SetValue(std::move(intf));
out.SetValue(intf);
return ResultSuccess();
}
}
Result SessionImpl::OpenReport(ams::sf::Out<std::shared_ptr<erpt::sf::IReport>> out) {
Result SessionImpl::OpenReport(ams::sf::Out<ams::sf::SharedPointer<erpt::sf::IReport>> out) {
return OpenInterface<erpt::sf::IReport, ReportImpl>(out);
}
Result SessionImpl::OpenManager(ams::sf::Out<std::shared_ptr<erpt::sf::IManager>> out) {
Result SessionImpl::OpenManager(ams::sf::Out<ams::sf::SharedPointer<erpt::sf::IManager>> out) {
return OpenInterface<erpt::sf::IManager, ManagerImpl>(out);
}
Result SessionImpl::OpenAttachment(ams::sf::Out<std::shared_ptr<erpt::sf::IAttachment>> out) {
Result SessionImpl::OpenAttachment(ams::sf::Out<ams::sf::SharedPointer<erpt::sf::IAttachment>> out) {
return OpenInterface<erpt::sf::IAttachment, AttachmentImpl>(out);
}

View File

@@ -18,11 +18,11 @@
namespace ams::erpt::srv {
class SessionImpl final {
class SessionImpl {
public:
Result OpenReport(ams::sf::Out<std::shared_ptr<erpt::sf::IReport>> out);
Result OpenManager(ams::sf::Out<std::shared_ptr<erpt::sf::IManager>> out);
Result OpenAttachment(ams::sf::Out<std::shared_ptr<erpt::sf::IAttachment>> out);
Result OpenReport(ams::sf::Out<ams::sf::SharedPointer<erpt::sf::IReport>> out);
Result OpenManager(ams::sf::Out<ams::sf::SharedPointer<erpt::sf::IManager>> out);
Result OpenAttachment(ams::sf::Out<ams::sf::SharedPointer<erpt::sf::IAttachment>> out);
};
static_assert(erpt::sf::IsISession<SessionImpl>);

View File

@@ -15,11 +15,12 @@
*/
#include <stratosphere.hpp>
#include <stratosphere/fssrv/fssrv_interface_adapters.hpp>
#include "impl/fssrv_allocator_for_service_framework.hpp"
namespace ams::fssrv::impl {
FileInterfaceAdapter::FileInterfaceAdapter(std::unique_ptr<fs::fsa::IFile> &&file, std::shared_ptr<FileSystemInterfaceAdapter> &&parent, std::unique_lock<fssystem::SemaphoreAdapter> &&sema)
: parent_filesystem(std::move(parent)), base_file(std::move(file)), open_count_semaphore(std::move(sema))
FileInterfaceAdapter::FileInterfaceAdapter(std::unique_ptr<fs::fsa::IFile> &&file, FileSystemInterfaceAdapter *parent, std::unique_lock<fssystem::SemaphoreAdapter> &&sema)
: parent_filesystem(parent, true), base_file(std::move(file)), open_count_semaphore(std::move(sema))
{
/* ... */
}
@@ -88,8 +89,8 @@ namespace ams::fssrv::impl {
return ResultSuccess();
}
DirectoryInterfaceAdapter::DirectoryInterfaceAdapter(std::unique_ptr<fs::fsa::IDirectory> &&dir, std::shared_ptr<FileSystemInterfaceAdapter> &&parent, std::unique_lock<fssystem::SemaphoreAdapter> &&sema)
: parent_filesystem(std::move(parent)), base_dir(std::move(dir)), open_count_semaphore(std::move(sema))
DirectoryInterfaceAdapter::DirectoryInterfaceAdapter(std::unique_ptr<fs::fsa::IDirectory> &&dir, FileSystemInterfaceAdapter *parent, std::unique_lock<fssystem::SemaphoreAdapter> &&sema)
: parent_filesystem(parent, true), base_dir(std::move(dir)), open_count_semaphore(std::move(sema))
{
/* ... */
}
@@ -232,7 +233,7 @@ namespace ams::fssrv::impl {
return this->base_fs->GetEntryType(reinterpret_cast<fs::DirectoryEntryType *>(out.GetPointer()), normalizer.GetPath());
}
Result FileSystemInterfaceAdapter::OpenFile(ams::sf::Out<std::shared_ptr<fssrv::sf::IFile>> out, const fssrv::sf::Path &path, u32 mode) {
Result FileSystemInterfaceAdapter::OpenFile(ams::sf::Out<ams::sf::SharedPointer<fssrv::sf::IFile>> out, const fssrv::sf::Path &path, u32 mode) {
auto read_lock = this->AcquireCacheInvalidationReadLock();
std::unique_lock<fssystem::SemaphoreAdapter> open_count_semaphore;
@@ -253,15 +254,14 @@ namespace ams::fssrv::impl {
/* TODO: N creates an nn::fssystem::AsynchronousAccessFile here. */
std::shared_ptr<FileSystemInterfaceAdapter> shared_this = this->shared_from_this();
auto file_intf = ams::sf::MakeShared<fssrv::sf::IFile, FileInterfaceAdapter>(std::move(file), std::move(shared_this), std::move(open_count_semaphore));
ams::sf::SharedPointer<fssrv::sf::IFile> file_intf = FileSystemObjectFactory::CreateSharedEmplaced<fssrv::sf::IFile, FileInterfaceAdapter>(std::move(file), this, std::move(open_count_semaphore));
R_UNLESS(file_intf != nullptr, fs::ResultAllocationFailureInFileSystemInterfaceAdapter());
out.SetValue(std::move(file_intf), target_object_id);
return ResultSuccess();
}
Result FileSystemInterfaceAdapter::OpenDirectory(ams::sf::Out<std::shared_ptr<fssrv::sf::IDirectory>> out, const fssrv::sf::Path &path, u32 mode) {
Result FileSystemInterfaceAdapter::OpenDirectory(ams::sf::Out<ams::sf::SharedPointer<fssrv::sf::IDirectory>> out, const fssrv::sf::Path &path, u32 mode) {
auto read_lock = this->AcquireCacheInvalidationReadLock();
std::unique_lock<fssystem::SemaphoreAdapter> open_count_semaphore;
@@ -280,8 +280,7 @@ namespace ams::fssrv::impl {
/* TODO: This is a hack to get the mitm API to work. Better solution? */
const auto target_object_id = dir->GetDomainObjectId();
std::shared_ptr<FileSystemInterfaceAdapter> shared_this = this->shared_from_this();
auto dir_intf = ams::sf::MakeShared<fssrv::sf::IDirectory, DirectoryInterfaceAdapter>(std::move(dir), std::move(shared_this), std::move(open_count_semaphore));
ams::sf::SharedPointer<fssrv::sf::IDirectory> dir_intf = FileSystemObjectFactory::CreateSharedEmplaced<fssrv::sf::IDirectory, DirectoryInterfaceAdapter>(std::move(dir), this, std::move(open_count_semaphore));
R_UNLESS(dir_intf != nullptr, fs::ResultAllocationFailureInFileSystemInterfaceAdapter());
out.SetValue(std::move(dir_intf), target_object_id);

View File

@@ -0,0 +1,36 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <stratosphere.hpp>
namespace ams::fssrv::impl {
class AllocatorForServiceFramework {
public:
using Policy = ams::sf::StatelessAllocationPolicy<AllocatorForServiceFramework>;
void *Allocate(size_t size) {
return fs::impl::Allocate(size);
}
void Deallocate(void *ptr, size_t size) {
return fs::impl::Deallocate(ptr, size);
}
};
using FileSystemObjectFactory = ams::sf::ObjectFactory<AllocatorForServiceFramework::Policy>;
}

View File

@@ -23,13 +23,13 @@ namespace ams::gpio {
constinit os::SdkMutex g_init_mutex;
constinit int g_initialize_count = 0;
constinit bool g_remote = false;
std::shared_ptr<sf::IManager> g_manager;
ams::sf::SharedPointer<gpio::sf::IManager> g_manager;
using InternalSession = std::shared_ptr<gpio::sf::IPadSession>;
ams::sf::UnmanagedServiceObject<gpio::sf::IManager, RemoteManagerImpl> g_remote_manager_impl;
InternalSession &GetInterface(GpioPadSession *session) {
gpio::sf::IPadSession *GetInterface(GpioPadSession *session) {
AMS_ASSERT(session->_session != nullptr);
return *static_cast<InternalSession *>(session->_session);
return static_cast<gpio::sf::IPadSession *>(session->_session);
}
}
@@ -39,17 +39,17 @@ namespace ams::gpio {
if ((g_initialize_count++) == 0) {
R_ABORT_UNLESS(::gpioInitialize());
g_manager = ams::sf::MakeShared<sf::IManager, RemoteManagerImpl>();
g_manager = g_remote_manager_impl.GetShared();
g_remote = true;
}
}
void InitializeWith(std::shared_ptr<gpio::sf::IManager> &&sp) {
void InitializeWith(ams::sf::SharedPointer<gpio::sf::IManager> manager) {
std::scoped_lock lk(g_init_mutex);
AMS_ABORT_UNLESS(g_initialize_count == 0);
g_manager = std::move(sp);
g_manager = manager;
g_initialize_count = 1;
}
@@ -59,7 +59,7 @@ namespace ams::gpio {
AMS_ASSERT(g_initialize_count > 0);
if ((--g_initialize_count) == 0) {
g_manager.reset();
g_manager = nullptr;
if (g_remote) {
::gpioExit();
}
@@ -67,28 +67,21 @@ namespace ams::gpio {
}
Result OpenSession(GpioPadSession *out_session, ams::DeviceCode device_code) {
/* Allocate the session. */
InternalSession *internal_session = new (std::nothrow) InternalSession;
AMS_ABORT_UNLESS(internal_session != nullptr);
auto session_guard = SCOPE_GUARD { delete internal_session; };
/* Get the session. */
ams::sf::SharedPointer<gpio::sf::IPadSession> session;
{
ams::sf::cmif::ServiceObjectHolder object_holder;
if (hos::GetVersion() >= hos::Version_7_0_0) {
R_TRY(g_manager->OpenSession2(std::addressof(object_holder), device_code, ddsf::AccessMode_ReadWrite));
R_TRY(g_manager->OpenSession2(std::addressof(session), device_code, ddsf::AccessMode_ReadWrite));
} else {
R_TRY(g_manager->OpenSession(std::addressof(object_holder), ConvertToGpioPadName(device_code)));
R_TRY(g_manager->OpenSession(std::addressof(session), ConvertToGpioPadName(device_code)));
}
*internal_session = object_holder.GetServiceObject<sf::IPadSession>();
}
/* Set output. */
out_session->_session = internal_session;
out_session->_session = session.Detach();
out_session->_event = nullptr;
/* We succeeded. */
session_guard.Cancel();
return ResultSuccess();
}
@@ -101,7 +94,7 @@ namespace ams::gpio {
}
/* Close the session. */
delete std::addressof(GetInterface(session));
ams::sf::ReleaseSharedObject(GetInterface(session));
session->_session = nullptr;
}

View File

@@ -0,0 +1,52 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stratosphere.hpp>
#include "gpio_remote_manager_impl.hpp"
namespace ams::gpio {
namespace {
struct GpioRemoteManagerTag;
using RemoteAllocator = ams::sf::ExpHeapStaticAllocator<16_KB, GpioRemoteManagerTag>;
using RemoteObjectFactory = ams::sf::ObjectFactory<typename RemoteAllocator::Policy>;
class StaticAllocatorInitializer {
public:
StaticAllocatorInitializer() {
RemoteAllocator::Initialize(lmem::CreateOption_None);
}
} g_static_allocator_initializer;
}
Result RemoteManagerImpl::OpenSession(ams::sf::Out<ams::sf::SharedPointer<gpio::sf::IPadSession>> out, gpio::GpioPadName pad_name) {
::GpioPadSession p;
R_TRY(::gpioOpenSession(std::addressof(p), static_cast<::GpioPadName>(static_cast<u32>(pad_name))));
out.SetValue(RemoteObjectFactory::CreateSharedEmplaced<gpio::sf::IPadSession, RemotePadSessionImpl>(p));
return ResultSuccess();
}
Result RemoteManagerImpl::OpenSession2(ams::sf::Out<ams::sf::SharedPointer<gpio::sf::IPadSession>> out, DeviceCode device_code, ddsf::AccessMode access_mode) {
::GpioPadSession p;
R_TRY(::gpioOpenSession2(std::addressof(p), device_code.GetInternalValue(), access_mode));
out.SetValue(RemoteObjectFactory::CreateSharedEmplaced<gpio::sf::IPadSession, RemotePadSessionImpl>(p));
return ResultSuccess();
}
}

View File

@@ -26,20 +26,14 @@ namespace ams::gpio {
~RemoteManagerImpl() { /* ... */ }
public:
/* Actual commands. */
Result OpenSessionForDev(ams::sf::Out<std::shared_ptr<gpio::sf::IPadSession>> out, s32 pad_descriptor) {
Result OpenSessionForDev(ams::sf::Out<ams::sf::SharedPointer<gpio::sf::IPadSession>> out, s32 pad_descriptor) {
/* TODO: libnx bindings */
AMS_ABORT();
}
Result OpenSession(ams::sf::Out<std::shared_ptr<gpio::sf::IPadSession>> out, gpio::GpioPadName pad_name) {
::GpioPadSession p;
R_TRY(::gpioOpenSession(std::addressof(p), static_cast<::GpioPadName>(static_cast<u32>(pad_name))));
Result OpenSession(ams::sf::Out<ams::sf::SharedPointer<gpio::sf::IPadSession>> out, gpio::GpioPadName pad_name);
out.SetValue(ams::sf::MakeShared<gpio::sf::IPadSession, RemotePadSessionImpl>(p));
return ResultSuccess();
}
Result OpenSessionForTest(ams::sf::Out<std::shared_ptr<gpio::sf::IPadSession>> out, gpio::GpioPadName pad_name) {
Result OpenSessionForTest(ams::sf::Out<ams::sf::SharedPointer<gpio::sf::IPadSession>> out, gpio::GpioPadName pad_name) {
/* TODO: libnx bindings */
AMS_ABORT();
}
@@ -63,13 +57,7 @@ namespace ams::gpio {
AMS_ABORT();
}
Result OpenSession2(ams::sf::Out<std::shared_ptr<gpio::sf::IPadSession>> out, DeviceCode device_code, ddsf::AccessMode access_mode) {
::GpioPadSession p;
R_TRY(::gpioOpenSession2(std::addressof(p), device_code.GetInternalValue(), access_mode));
out.SetValue(ams::sf::MakeShared<gpio::sf::IPadSession, RemotePadSessionImpl>(p));
return ResultSuccess();
}
Result OpenSession2(ams::sf::Out<ams::sf::SharedPointer<gpio::sf::IPadSession>> out, DeviceCode device_code, ddsf::AccessMode access_mode);
Result IsWakeEventActive2(ams::sf::Out<bool> out, DeviceCode device_code) {
return ::gpioIsWakeEventActive2(out.GetPointer(), device_code.GetInternalValue());

View File

@@ -20,17 +20,12 @@ namespace ams::gpio::server {
namespace {
ManagerImpl g_manager_impl;
std::shared_ptr<gpio::sf::IManager> GetManagerServiceObject() {
static std::shared_ptr<gpio::sf::IManager> s_sp = ams::sf::GetSharedPointerTo<gpio::sf::IManager>(g_manager_impl);
return s_sp;
}
ams::sf::UnmanagedServiceObject<gpio::sf::IManager, gpio::server::ManagerImpl> g_manager_impl;
}
std::shared_ptr<gpio::sf::IManager> GetServiceObject() {
return GetManagerServiceObject();
ams::sf::SharedPointer<gpio::sf::IManager> GetServiceObject() {
return g_manager_impl.GetShared();
}
}

View File

@@ -18,25 +18,25 @@
namespace ams::gpio::server {
ManagerImpl::ManagerImpl() : pad_session_memory_resource(), pad_allocator(std::addressof(pad_session_memory_resource)) {
ManagerImpl::ManagerImpl() {
this->heap_handle = lmem::CreateExpHeap(this->heap_buffer, sizeof(this->heap_buffer), lmem::CreateOption_None);
this->pad_session_memory_resource.Attach(this->heap_handle);
this->pad_allocator.Attach(this->heap_handle);
}
ManagerImpl::~ManagerImpl() {
lmem::DestroyExpHeap(this->heap_handle);
}
Result ManagerImpl::OpenSessionForDev(ams::sf::Out<std::shared_ptr<gpio::sf::IPadSession>> out, s32 pad_descriptor) {
Result ManagerImpl::OpenSessionForDev(ams::sf::Out<ams::sf::SharedPointer<gpio::sf::IPadSession>> out, s32 pad_descriptor) {
/* TODO */
AMS_ABORT();
}
Result ManagerImpl::OpenSession(ams::sf::Out<std::shared_ptr<gpio::sf::IPadSession>> out, gpio::GpioPadName pad_name) {
Result ManagerImpl::OpenSession(ams::sf::Out<ams::sf::SharedPointer<gpio::sf::IPadSession>> out, gpio::GpioPadName pad_name) {
return this->OpenSession2(out, ConvertToDeviceCode(pad_name), ddsf::AccessMode_ReadWrite);
}
Result ManagerImpl::OpenSessionForTest(ams::sf::Out<std::shared_ptr<gpio::sf::IPadSession>> out, gpio::GpioPadName pad_name) {
Result ManagerImpl::OpenSessionForTest(ams::sf::Out<ams::sf::SharedPointer<gpio::sf::IPadSession>> out, gpio::GpioPadName pad_name) {
/* TODO */
AMS_ABORT();
}
@@ -61,15 +61,15 @@ namespace ams::gpio::server {
AMS_ABORT();
}
Result ManagerImpl::OpenSession2(ams::sf::Out<std::shared_ptr<gpio::sf::IPadSession>> out, DeviceCode device_code, ddsf::AccessMode access_mode) {
Result ManagerImpl::OpenSession2(ams::sf::Out<ams::sf::SharedPointer<gpio::sf::IPadSession>> out, DeviceCode device_code, ddsf::AccessMode access_mode) {
/* Allocate a session. */
auto session = ams::sf::AllocateShared<gpio::sf::IPadSession, PadSessionImpl>(this->pad_allocator, this);
auto session = Factory::CreateSharedEmplaced<gpio::sf::IPadSession, PadSessionImpl>(std::addressof(this->pad_allocator), this);
/* Open the session. */
R_TRY(session->GetImpl().OpenSession(device_code, access_mode));
R_TRY(session.GetImpl().OpenSession(device_code, access_mode));
/* We succeeded. */
out.SetValue(std::move(session));
*out = std::move(session);
return ResultSuccess();
}

View File

@@ -19,11 +19,13 @@
namespace ams::gpio::server {
class ManagerImpl {
class ManagerImpl : public ams::sf::ISharedObject {
private:
using Allocator = ams::sf::ExpHeapAllocator;
using Factory = ams::sf::ObjectFactory<Allocator::Policy>;
private:
lmem::HeapHandle heap_handle;
ams::sf::ExpHeapMemoryResource pad_session_memory_resource;
typename ams::sf::ServiceObjectAllocator<gpio::sf::IPadSession, PadSessionImpl> pad_allocator;
Allocator pad_allocator;
u8 heap_buffer[12_KB];
public:
ManagerImpl();
@@ -31,14 +33,14 @@ namespace ams::gpio::server {
~ManagerImpl();
public:
/* Actual commands. */
Result OpenSessionForDev(ams::sf::Out<std::shared_ptr<gpio::sf::IPadSession>> out, s32 pad_descriptor);
Result OpenSession(ams::sf::Out<std::shared_ptr<gpio::sf::IPadSession>> out, gpio::GpioPadName pad_name);
Result OpenSessionForTest(ams::sf::Out<std::shared_ptr<gpio::sf::IPadSession>> out, gpio::GpioPadName pad_name);
Result OpenSessionForDev(ams::sf::Out<ams::sf::SharedPointer<gpio::sf::IPadSession>> out, s32 pad_descriptor);
Result OpenSession(ams::sf::Out<ams::sf::SharedPointer<gpio::sf::IPadSession>> out, gpio::GpioPadName pad_name);
Result OpenSessionForTest(ams::sf::Out<ams::sf::SharedPointer<gpio::sf::IPadSession>> out, gpio::GpioPadName pad_name);
Result IsWakeEventActive(ams::sf::Out<bool> out, gpio::GpioPadName pad_name);
Result GetWakeEventActiveFlagSet(ams::sf::Out<gpio::WakeBitFlag> out);
Result SetWakeEventActiveFlagSetForDebug(gpio::GpioPadName pad_name, bool is_enabled);
Result SetWakePinDebugMode(s32 mode);
Result OpenSession2(ams::sf::Out<std::shared_ptr<gpio::sf::IPadSession>> out, DeviceCode device_code, ddsf::AccessMode access_mode);
Result OpenSession2(ams::sf::Out<ams::sf::SharedPointer<gpio::sf::IPadSession>> out, DeviceCode device_code, ddsf::AccessMode access_mode);
Result IsWakeEventActive2(ams::sf::Out<bool> out, DeviceCode device_code);
Result SetWakeEventActiveFlagSetForDebug2(DeviceCode device_code, bool is_enabled);
Result SetRetryValues(u32 arg0, u32 arg1);

View File

@@ -23,21 +23,19 @@ namespace ams::i2c {
constinit int g_initialize_count = 0;
constinit os::SdkMutex g_i2c_mutex;
std::shared_ptr<sf::IManager> g_i2c_manager;
ams::sf::SharedPointer<sf::IManager> g_i2c_manager;
constinit int g_i2c_count = 0;
constinit os::SdkMutex g_i2c_pcv_mutex;
std::shared_ptr<sf::IManager> g_i2c_pcv_manager;
ams::sf::SharedPointer<sf::IManager> g_i2c_pcv_manager;
constinit int g_i2c_pcv_count = 0;
using InternalSession = std::shared_ptr<i2c::sf::ISession>;
InternalSession &GetInterface(const I2cSession &session) {
i2c::sf::ISession *GetInterface(const I2cSession &session) {
AMS_ASSERT(session._session != nullptr);
return *static_cast<InternalSession *>(session._session);
return static_cast<i2c::sf::ISession *>(session._session);
}
std::shared_ptr<sf::IManager> GetManager(DeviceCode device_code) {
ams::sf::SharedPointer<sf::IManager> GetManager(DeviceCode device_code) {
if (IsPowerBusDeviceCode(device_code)) {
return g_i2c_pcv_manager;
} else {
@@ -47,7 +45,7 @@ namespace ams::i2c {
}
void InitializeWith(std::shared_ptr<i2c::sf::IManager> &&sp, std::shared_ptr<i2c::sf::IManager> &&sp_pcv) {
void InitializeWith(ams::sf::SharedPointer<i2c::sf::IManager> sp, ams::sf::SharedPointer<i2c::sf::IManager> sp_pcv) {
std::scoped_lock lk(g_init_mutex);
AMS_ABORT_UNLESS(g_initialize_count == 0);
@@ -86,7 +84,7 @@ namespace ams::i2c {
AMS_ASSERT(g_i2c_count > 0);
if (g_i2c_count > 0) {
if ((--g_i2c_count) == 0) {
g_i2c_manager.reset();
g_i2c_manager = nullptr;
}
}
}
@@ -95,7 +93,7 @@ namespace ams::i2c {
AMS_ASSERT(g_i2c_pcv_count > 0);
if (g_i2c_pcv_count > 0) {
if ((--g_i2c_pcv_count) == 0) {
g_i2c_pcv_manager.reset();
g_i2c_manager = nullptr;
}
}
}
@@ -103,36 +101,29 @@ namespace ams::i2c {
}
Result OpenSession(I2cSession *out, DeviceCode device_code) {
/* Allocate the session. */
InternalSession *internal_session = new (std::nothrow) InternalSession;
AMS_ABORT_UNLESS(internal_session != nullptr);
auto session_guard = SCOPE_GUARD { delete internal_session; };
/* Get manager for the device. */
auto manager = GetManager(device_code);
/* Get the session. */
ams::sf::SharedPointer<i2c::sf::ISession> session;
{
ams::sf::cmif::ServiceObjectHolder object_holder;
if (hos::GetVersion() >= hos::Version_6_0_0) {
R_TRY(manager->OpenSession2(std::addressof(object_holder), device_code));
R_TRY(manager->OpenSession2(std::addressof(session), device_code));
} else {
R_TRY(manager->OpenSession(std::addressof(object_holder), ConvertToI2cDevice(device_code)));
R_TRY(manager->OpenSession(std::addressof(session), ConvertToI2cDevice(device_code)));
}
*internal_session = object_holder.GetServiceObject<sf::ISession>();
}
/* Set output. */
out->_session = internal_session;
out->_session = session.Detach();
/* We succeeded. */
session_guard.Cancel();
return ResultSuccess();
}
void CloseSession(I2cSession &session) {
/* Close the session. */
delete std::addressof(GetInterface(session));
ams::sf::ReleaseSharedObject(GetInterface(session));
session._session = nullptr;
}

View File

@@ -20,27 +20,17 @@ namespace ams::i2c::server {
namespace {
ManagerImpl g_manager_impl;
ManagerImpl g_pcv_manager_impl;
std::shared_ptr<i2c::sf::IManager> GetManagerServiceObject() {
static std::shared_ptr<i2c::sf::IManager> s_sp = ams::sf::GetSharedPointerTo<i2c::sf::IManager>(g_manager_impl);
return s_sp;
}
std::shared_ptr<i2c::sf::IManager> GetManagerServiceObjectPowerBus() {
static std::shared_ptr<i2c::sf::IManager> s_sp = ams::sf::GetSharedPointerTo<i2c::sf::IManager>(g_pcv_manager_impl);
return s_sp;
}
ams::sf::UnmanagedServiceObject<i2c::sf::IManager, i2c::server::ManagerImpl> g_manager_impl;
ams::sf::UnmanagedServiceObject<i2c::sf::IManager, i2c::server::ManagerImpl> g_pcv_manager_impl;
}
std::shared_ptr<i2c::sf::IManager> GetServiceObject() {
return GetManagerServiceObject();
ams::sf::SharedPointer<i2c::sf::IManager> GetServiceObject() {
return g_manager_impl.GetShared();
}
std::shared_ptr<i2c::sf::IManager> GetServiceObjectPowerBus() {
return GetManagerServiceObjectPowerBus();
ams::sf::SharedPointer<i2c::sf::IManager> GetServiceObjectPowerBus() {
return g_pcv_manager_impl.GetShared();
}
}

View File

@@ -18,21 +18,21 @@
namespace ams::i2c::server {
ManagerImpl::ManagerImpl() : session_memory_resource(), allocator(std::addressof(session_memory_resource)) {
ManagerImpl::ManagerImpl() {
this->heap_handle = lmem::CreateExpHeap(this->heap_buffer, sizeof(this->heap_buffer), lmem::CreateOption_None);
this->session_memory_resource.Attach(this->heap_handle);
this->allocator.Attach(this->heap_handle);
}
ManagerImpl::~ManagerImpl() {
lmem::DestroyExpHeap(this->heap_handle);
}
Result ManagerImpl::OpenSessionForDev(ams::sf::Out<std::shared_ptr<i2c::sf::ISession>> out, s32 bus_idx, u16 slave_address, i2c::AddressingMode addressing_mode, i2c::SpeedMode speed_mode) {
Result ManagerImpl::OpenSessionForDev(ams::sf::Out<ams::sf::SharedPointer<i2c::sf::ISession>> out, s32 bus_idx, u16 slave_address, i2c::AddressingMode addressing_mode, i2c::SpeedMode speed_mode) {
/* TODO */
AMS_ABORT();
}
Result ManagerImpl::OpenSession(ams::sf::Out<std::shared_ptr<i2c::sf::ISession>> out, i2c::I2cDevice device) {
Result ManagerImpl::OpenSession(ams::sf::Out<ams::sf::SharedPointer<i2c::sf::ISession>> out, i2c::I2cDevice device) {
return this->OpenSession2(out, ConvertToDeviceCode(device));
}
@@ -46,15 +46,15 @@ namespace ams::i2c::server {
AMS_ABORT();
}
Result ManagerImpl::OpenSession2(ams::sf::Out<std::shared_ptr<i2c::sf::ISession>> out, DeviceCode device_code) {
Result ManagerImpl::OpenSession2(ams::sf::Out<ams::sf::SharedPointer<i2c::sf::ISession>> out, DeviceCode device_code) {
/* Allocate a session. */
auto session = ams::sf::AllocateShared<i2c::sf::ISession, SessionImpl>(this->allocator, this);
auto session = Factory::CreateSharedEmplaced<i2c::sf::ISession, SessionImpl>(std::addressof(this->allocator), this);
/* Open the session. */
R_TRY(session->GetImpl().OpenSession(device_code));
R_TRY(session.GetImpl().OpenSession(device_code));
/* We succeeded. */
out.SetValue(std::move(session));
*out = std::move(session);
return ResultSuccess();
}

View File

@@ -20,10 +20,12 @@
namespace ams::i2c::server {
class ManagerImpl {
private:
using Allocator = ams::sf::ExpHeapAllocator;
using Factory = ams::sf::ObjectFactory<Allocator::Policy>;
private:
lmem::HeapHandle heap_handle;
ams::sf::ExpHeapMemoryResource session_memory_resource;
typename ams::sf::ServiceObjectAllocator<i2c::sf::ISession, SessionImpl> allocator;
Allocator allocator;
u8 heap_buffer[4_KB];
public:
ManagerImpl();
@@ -31,11 +33,11 @@ namespace ams::i2c::server {
~ManagerImpl();
public:
/* Actual commands. */
Result OpenSessionForDev(ams::sf::Out<std::shared_ptr<i2c::sf::ISession>> out, s32 bus_idx, u16 slave_address, i2c::AddressingMode addressing_mode, i2c::SpeedMode speed_mode);
Result OpenSession(ams::sf::Out<std::shared_ptr<i2c::sf::ISession>> out, i2c::I2cDevice device);
Result OpenSessionForDev(ams::sf::Out<ams::sf::SharedPointer<i2c::sf::ISession>> out, s32 bus_idx, u16 slave_address, i2c::AddressingMode addressing_mode, i2c::SpeedMode speed_mode);
Result OpenSession(ams::sf::Out<ams::sf::SharedPointer<i2c::sf::ISession>> out, i2c::I2cDevice device);
Result HasDevice(ams::sf::Out<bool> out, i2c::I2cDevice device);
Result HasDeviceForDev(ams::sf::Out<bool> out, i2c::I2cDevice device);
Result OpenSession2(ams::sf::Out<std::shared_ptr<i2c::sf::ISession>> out, DeviceCode device_code);
Result OpenSession2(ams::sf::Out<ams::sf::SharedPointer<i2c::sf::ISession>> out, DeviceCode device_code);
};
static_assert(i2c::sf::IsIManager<ManagerImpl>);

View File

@@ -23,6 +23,18 @@ namespace ams::lr {
bool g_initialized;
/* TODO: This belongs inside lr_location_resolver_manager_factory */
struct LocationResolverManagerAllocatorTag;
using LocationResolverManagerAllocator = sf::ExpHeapStaticAllocator<1_KB, LocationResolverManagerAllocatorTag>;
using LocationResolverManagerFactory = sf::ObjectFactory<typename LocationResolverManagerAllocator::Policy>;
class StaticAllocatorInitializer {
public:
StaticAllocatorInitializer() {
LocationResolverManagerAllocator::Initialize(lmem::CreateOption_None);
}
} g_static_allocator_initializer;
}
void Initialize() {
@@ -42,7 +54,7 @@ namespace ams::lr {
LrLocationResolver lr;
R_TRY(lrOpenLocationResolver(static_cast<NcmStorageId>(storage_id), std::addressof(lr)));
*out = LocationResolver(sf::MakeShared<ILocationResolver, RemoteLocationResolverImpl>(lr));
*out = LocationResolver(LocationResolverManagerFactory::CreateSharedEmplaced<ILocationResolver, RemoteLocationResolverImpl>(lr));
return ResultSuccess();
}
@@ -50,7 +62,7 @@ namespace ams::lr {
LrRegisteredLocationResolver lr;
R_TRY(lrOpenRegisteredLocationResolver(std::addressof(lr)));
*out = RegisteredLocationResolver(sf::MakeShared<IRegisteredLocationResolver, RemoteRegisteredLocationResolverImpl>(lr));
*out = RegisteredLocationResolver(LocationResolverManagerFactory::CreateSharedEmplaced<IRegisteredLocationResolver, RemoteRegisteredLocationResolverImpl>(lr));
return ResultSuccess();
}

View File

@@ -22,7 +22,14 @@
namespace ams::lr {
Result LocationResolverManagerImpl::OpenLocationResolver(sf::Out<std::shared_ptr<ILocationResolver>> out, ncm::StorageId storage_id) {
namespace {
using ContentLocationResolverFactory = sf::ObjectFactory<sf::StdAllocationPolicy<std::allocator>>;
using RedirectOnlyLocationResolverFactory = sf::ObjectFactory<sf::StdAllocationPolicy<std::allocator>>;
}
Result LocationResolverManagerImpl::OpenLocationResolver(sf::Out<sf::SharedPointer<ILocationResolver>> out, ncm::StorageId storage_id) {
std::scoped_lock lk(this->mutex);
/* Find an existing resolver. */
auto resolver = this->location_resolvers.Find(storage_id);
@@ -30,10 +37,10 @@ namespace ams::lr {
/* No existing resolver is present, create one. */
if (!resolver) {
if (storage_id == ncm::StorageId::Host) {
AMS_ABORT_UNLESS(this->location_resolvers.Insert(storage_id, sf::MakeShared<ILocationResolver, RedirectOnlyLocationResolverImpl>()));
AMS_ABORT_UNLESS(this->location_resolvers.Insert(storage_id, RedirectOnlyLocationResolverFactory::CreateSharedEmplaced<ILocationResolver, RedirectOnlyLocationResolverImpl>()));
} else {
auto content_resolver = sf::MakeShared<ILocationResolver, ContentLocationResolverImpl>(storage_id);
R_TRY(content_resolver->GetImpl().Refresh());
auto content_resolver = ContentLocationResolverFactory::CreateSharedEmplaced<ILocationResolver, ContentLocationResolverImpl>(storage_id);
R_TRY(content_resolver->Refresh());
AMS_ABORT_UNLESS(this->location_resolvers.Insert(storage_id, std::move(content_resolver)));
}
@@ -42,20 +49,20 @@ namespace ams::lr {
}
/* Copy the output interface. */
out.SetValue(std::shared_ptr<ILocationResolver>(*resolver));
*out = *resolver;
return ResultSuccess();
}
Result LocationResolverManagerImpl::OpenRegisteredLocationResolver(sf::Out<std::shared_ptr<IRegisteredLocationResolver>> out) {
Result LocationResolverManagerImpl::OpenRegisteredLocationResolver(sf::Out<sf::SharedPointer<IRegisteredLocationResolver>> out) {
std::scoped_lock lk(this->mutex);
/* No existing resolver is present, create one. */
if (!this->registered_location_resolver) {
this->registered_location_resolver = sf::MakeShared<IRegisteredLocationResolver, RegisteredLocationResolverImpl>();
this->registered_location_resolver = ContentLocationResolverFactory::CreateSharedEmplaced<IRegisteredLocationResolver, RegisteredLocationResolverImpl>();
}
/* Copy the output interface. */
out.SetValue(std::shared_ptr<IRegisteredLocationResolver>(this->registered_location_resolver));
*out = this->registered_location_resolver;
return ResultSuccess();
}
@@ -74,16 +81,16 @@ namespace ams::lr {
return ResultSuccess();
}
Result LocationResolverManagerImpl::OpenAddOnContentLocationResolver(sf::Out<std::shared_ptr<IAddOnContentLocationResolver>> out) {
Result LocationResolverManagerImpl::OpenAddOnContentLocationResolver(sf::Out<sf::SharedPointer<IAddOnContentLocationResolver>> out) {
std::scoped_lock lk(this->mutex);
/* No existing resolver is present, create one. */
if (!this->add_on_content_location_resolver) {
this->add_on_content_location_resolver = sf::MakeShared<IAddOnContentLocationResolver, AddOnContentLocationResolverImpl>();
this->add_on_content_location_resolver = ContentLocationResolverFactory::CreateSharedEmplaced<IAddOnContentLocationResolver, AddOnContentLocationResolverImpl>();
}
/* Copy the output interface. */
out.SetValue(std::shared_ptr<IAddOnContentLocationResolver>(this->add_on_content_location_resolver));
*out = this->add_on_content_location_resolver;
return ResultSuccess();
}

View File

@@ -20,23 +20,25 @@ namespace ams::ncm {
namespace {
std::shared_ptr<IContentManager> g_content_manager;
sf::SharedPointer<IContentManager> g_content_manager;
sf::UnmanagedServiceObject<IContentManager, RemoteContentManagerImpl> g_remote_manager_impl;
}
void Initialize() {
AMS_ASSERT(g_content_manager == nullptr);
R_ABORT_UNLESS(ncmInitialize());
g_content_manager = sf::MakeShared<IContentManager, RemoteContentManagerImpl>();
g_content_manager = g_remote_manager_impl.GetShared();
}
void Finalize() {
AMS_ASSERT(g_content_manager != nullptr);
g_content_manager.reset();
g_content_manager.Reset();
ncmExit();
}
void InitializeWithObject(std::shared_ptr<IContentManager> manager_object) {
void InitializeWithObject(sf::SharedPointer<IContentManager> manager_object) {
AMS_ASSERT(g_content_manager == nullptr);
g_content_manager = manager_object;
AMS_ASSERT(g_content_manager != nullptr);
@@ -60,18 +62,18 @@ namespace ams::ncm {
}
Result OpenContentStorage(ContentStorage *out, StorageId storage_id) {
sf::cmif::ServiceObjectHolder object_holder;
R_TRY(g_content_manager->OpenContentStorage(std::addressof(object_holder), storage_id));
sf::SharedPointer<IContentStorage> content_storage;
R_TRY(g_content_manager->OpenContentStorage(std::addressof(content_storage), storage_id));
*out = ContentStorage(object_holder.GetServiceObject<IContentStorage>());
*out = ContentStorage(std::move(content_storage));
return ResultSuccess();
}
Result OpenContentMetaDatabase(ContentMetaDatabase *out, StorageId storage_id) {
sf::cmif::ServiceObjectHolder object_holder;
R_TRY(g_content_manager->OpenContentMetaDatabase(std::addressof(object_holder), storage_id));
sf::SharedPointer<IContentMetaDatabase> content_db;
R_TRY(g_content_manager->OpenContentMetaDatabase(std::addressof(content_db), storage_id));
*out = ContentMetaDatabase(object_holder.GetServiceObject<IContentMetaDatabase>());
*out = ContentMetaDatabase(std::move(content_db));
return ResultSuccess();
}

View File

@@ -465,7 +465,7 @@ namespace ams::ncm {
return ResultSuccess();
}
Result ContentManagerImpl::OpenContentStorage(sf::Out<std::shared_ptr<IContentStorage>> out, StorageId storage_id) {
Result ContentManagerImpl::OpenContentStorage(sf::Out<sf::SharedPointer<IContentStorage>> out, StorageId storage_id) {
std::scoped_lock lk(this->mutex);
/* Obtain the content storage root. */
@@ -482,11 +482,11 @@ namespace ams::ncm {
}
}
out.SetValue(std::shared_ptr<IContentStorage>(root->content_storage));
*out = root->content_storage;
return ResultSuccess();
}
Result ContentManagerImpl::OpenContentMetaDatabase(sf::Out<std::shared_ptr<IContentMetaDatabase>> out, StorageId storage_id) {
Result ContentManagerImpl::OpenContentMetaDatabase(sf::Out<sf::SharedPointer<IContentMetaDatabase>> out, StorageId storage_id) {
std::scoped_lock lk(this->mutex);
/* Obtain the content meta database root. */
@@ -503,7 +503,7 @@ namespace ams::ncm {
}
}
out.SetValue(std::shared_ptr<IContentMetaDatabase>(root->content_meta_database));
*out = root->content_meta_database;
return ResultSuccess();
}
@@ -553,23 +553,23 @@ namespace ams::ncm {
if (storage_id == StorageId::GameCard) {
/* Game card content storage is read only. */
auto content_storage = sf::MakeShared<IContentStorage, ReadOnlyContentStorageImpl>();
R_TRY(content_storage->GetImpl().Initialize(root->path, MakeFlatContentFilePath));
auto content_storage = sf::CreateSharedObjectEmplaced<IContentStorage, ReadOnlyContentStorageImpl>();
R_TRY(content_storage.GetImpl().Initialize(root->path, MakeFlatContentFilePath));
root->content_storage = std::move(content_storage);
} else {
/* Create a content storage. */
auto content_storage = sf::MakeShared<IContentStorage, ContentStorageImpl>();
auto content_storage = sf::CreateSharedObjectEmplaced<IContentStorage, ContentStorageImpl>();
/* Initialize content storage with an appropriate path function. */
switch (storage_id) {
case StorageId::BuiltInSystem:
R_TRY(content_storage->GetImpl().Initialize(root->path, MakeFlatContentFilePath, MakeFlatPlaceHolderFilePath, false, std::addressof(this->rights_id_cache)));
R_TRY(content_storage.GetImpl().Initialize(root->path, MakeFlatContentFilePath, MakeFlatPlaceHolderFilePath, false, std::addressof(this->rights_id_cache)));
break;
case StorageId::SdCard:
R_TRY(content_storage->GetImpl().Initialize(root->path, MakeSha256HierarchicalContentFilePath_ForFat16KCluster, MakeSha256HierarchicalPlaceHolderFilePath_ForFat16KCluster, true, std::addressof(this->rights_id_cache)));
R_TRY(content_storage.GetImpl().Initialize(root->path, MakeSha256HierarchicalContentFilePath_ForFat16KCluster, MakeSha256HierarchicalPlaceHolderFilePath_ForFat16KCluster, true, std::addressof(this->rights_id_cache)));
break;
default:
R_TRY(content_storage->GetImpl().Initialize(root->path, MakeSha256HierarchicalContentFilePath_ForFat16KCluster, MakeSha256HierarchicalPlaceHolderFilePath_ForFat16KCluster, false, std::addressof(this->rights_id_cache)));
R_TRY(content_storage.GetImpl().Initialize(root->path, MakeSha256HierarchicalContentFilePath_ForFat16KCluster, MakeSha256HierarchicalPlaceHolderFilePath_ForFat16KCluster, false, std::addressof(this->rights_id_cache)));
break;
}
@@ -589,7 +589,7 @@ namespace ams::ncm {
R_TRY(this->GetContentStorageRoot(std::addressof(root), storage_id));
/* Disable and unmount the content storage, if present. */
if (root->content_storage) {
if (root->content_storage != nullptr) {
/* N doesn't bother checking the result of this */
root->content_storage->DisableForcibly();
root->content_storage = nullptr;
@@ -617,7 +617,7 @@ namespace ams::ncm {
R_TRY(root->kvs->Initialize(root->max_content_metas, root->memory_resource));
/* Create an on memory content meta database for game cards. */
root->content_meta_database = sf::MakeShared<IContentMetaDatabase, OnMemoryContentMetaDatabaseImpl>(std::addressof(*root->kvs));
root->content_meta_database = sf::CreateSharedObjectEmplaced<IContentMetaDatabase, OnMemoryContentMetaDatabaseImpl>(std::addressof(*root->kvs));
} else {
/* Mount save data for this root. */
R_TRY(fs::MountSystemSaveData(root->mount_name, root->info.space_id, root->info.id));
@@ -630,7 +630,7 @@ namespace ams::ncm {
R_TRY(root->kvs->Load());
/* Create the content meta database. */
root->content_meta_database = sf::MakeShared<IContentMetaDatabase, ContentMetaDatabaseImpl>(std::addressof(*root->kvs), root->mount_name);
root->content_meta_database = sf::CreateSharedObjectEmplaced<IContentMetaDatabase, ContentMetaDatabaseImpl>(std::addressof(*root->kvs), root->mount_name);
mount_guard.Cancel();
}
@@ -645,7 +645,7 @@ namespace ams::ncm {
R_TRY(this->GetContentMetaDatabaseRoot(&root, storage_id));
/* Disable the content meta database, if present. */
if (root->content_meta_database) {
if (root->content_meta_database != nullptr) {
/* N doesn't bother checking the result of this */
root->content_meta_database->DisableForcibly();
root->content_meta_database = nullptr;

View File

@@ -49,12 +49,12 @@ namespace ams::ncm {
return ResultSuccess();
}
Result ContentMetaDatabaseImpl::Set(const ContentMetaKey &key, sf::InBuffer value) {
Result ContentMetaDatabaseImpl::Set(const ContentMetaKey &key, const sf::InBuffer &value) {
R_TRY(this->EnsureEnabled());
return this->kvs->Set(key, value.GetPointer(), value.GetSize());
}
Result ContentMetaDatabaseImpl::Get(sf::Out<u64> out_size, const ContentMetaKey &key, sf::OutBuffer out_value) {
Result ContentMetaDatabaseImpl::Get(sf::Out<u64> out_size, const ContentMetaKey &key, const sf::OutBuffer &out_value) {
R_TRY(this->EnsureEnabled());
/* Get the entry from our key-value store. */

View File

@@ -28,8 +28,8 @@ namespace ams::ncm {
Result GetContentIdImpl(ContentId *out, const ContentMetaKey &key, ContentType type, std::optional<u8> id_offset) const;
public:
/* Actual commands. */
virtual Result Set(const ContentMetaKey &key, sf::InBuffer value) override;
virtual Result Get(sf::Out<u64> out_size, const ContentMetaKey &key, sf::OutBuffer out_value) override;
virtual Result Set(const ContentMetaKey &key, const sf::InBuffer &value) override;
virtual Result Get(sf::Out<u64> out_size, const ContentMetaKey &key, const sf::OutBuffer &out_value) override;
virtual Result Remove(const ContentMetaKey &key) override;
virtual Result GetContentIdByType(sf::Out<ContentId> out_content_id, const ContentMetaKey &key, ContentType type) override;
virtual Result ListContentInfo(sf::Out<s32> out_entries_written, const sf::OutArray<ContentInfo> &out_info, const ContentMetaKey &key, s32 offset) override;

View File

@@ -54,8 +54,8 @@ namespace ams::ncm {
}
public:
/* Actual commands. */
virtual Result Set(const ContentMetaKey &key, sf::InBuffer value) = 0;
virtual Result Get(sf::Out<u64> out_size, const ContentMetaKey &key, sf::OutBuffer out_value) = 0;
virtual Result Set(const ContentMetaKey &key, const sf::InBuffer &value) = 0;
virtual Result Get(sf::Out<u64> out_size, const ContentMetaKey &key, const sf::OutBuffer &out_value) = 0;
virtual Result Remove(const ContentMetaKey &key) = 0;
virtual Result GetContentIdByType(sf::Out<ContentId> out_content_id, const ContentMetaKey &key, ContentType type) = 0;
virtual Result ListContentInfo(sf::Out<s32> out_entries_written, const sf::OutArray<ContentInfo> &out_info, const ContentMetaKey &key, s32 offset) = 0;

View File

@@ -292,7 +292,7 @@ namespace ams::ncm {
return ResultSuccess();
}
Result ContentStorageImpl::WritePlaceHolder(PlaceHolderId placeholder_id, s64 offset, sf::InBuffer data) {
Result ContentStorageImpl::WritePlaceHolder(PlaceHolderId placeholder_id, s64 offset, const sf::InBuffer &data) {
/* Ensure offset is valid. */
R_UNLESS(offset >= 0, ncm::ResultInvalidOffset());
R_TRY(this->EnsureEnabled());
@@ -551,7 +551,7 @@ namespace ams::ncm {
return this->placeholder_accessor.SetPlaceHolderFileSize(placeholder_id, size);
}
Result ContentStorageImpl::ReadContentIdFile(sf::OutBuffer buf, ContentId content_id, s64 offset) {
Result ContentStorageImpl::ReadContentIdFile(const sf::OutBuffer &buf, ContentId content_id, s64 offset) {
/* Ensure offset is valid. */
R_UNLESS(offset >= 0, ncm::ResultInvalidOffset());
R_TRY(this->EnsureEnabled());
@@ -621,7 +621,7 @@ namespace ams::ncm {
return ResultSuccess();
}
Result ContentStorageImpl::WriteContentForDebug(ContentId content_id, s64 offset, sf::InBuffer data) {
Result ContentStorageImpl::WriteContentForDebug(ContentId content_id, s64 offset, const sf::InBuffer &data) {
/* Ensure offset is valid. */
R_UNLESS(offset >= 0, ncm::ResultInvalidOffset());
R_TRY(this->EnsureEnabled());

View File

@@ -45,7 +45,7 @@ namespace ams::ncm {
virtual Result CreatePlaceHolder(PlaceHolderId placeholder_id, ContentId content_id, s64 size) override;
virtual Result DeletePlaceHolder(PlaceHolderId placeholder_id) override;
virtual Result HasPlaceHolder(sf::Out<bool> out, PlaceHolderId placeholder_id) override;
virtual Result WritePlaceHolder(PlaceHolderId placeholder_id, s64 offset, sf::InBuffer data) override;
virtual Result WritePlaceHolder(PlaceHolderId placeholder_id, s64 offset, const sf::InBuffer &data) override;
virtual Result Register(PlaceHolderId placeholder_id, ContentId content_id) override;
virtual Result Delete(ContentId content_id) override;
virtual Result Has(sf::Out<bool> out, ContentId content_id) override;
@@ -59,12 +59,12 @@ namespace ams::ncm {
virtual Result DisableForcibly() override;
virtual Result RevertToPlaceHolder(PlaceHolderId placeholder_id, ContentId old_content_id, ContentId new_content_id) override;
virtual Result SetPlaceHolderSize(PlaceHolderId placeholder_id, s64 size) override;
virtual Result ReadContentIdFile(sf::OutBuffer buf, ContentId content_id, s64 offset) override;
virtual Result ReadContentIdFile(const sf::OutBuffer &buf, ContentId content_id, s64 offset) override;
virtual Result GetRightsIdFromPlaceHolderIdDeprecated(sf::Out<ams::fs::RightsId> out_rights_id, PlaceHolderId placeholder_id) override;
virtual Result GetRightsIdFromPlaceHolderId(sf::Out<ncm::RightsId> out_rights_id, PlaceHolderId placeholder_id) override;
virtual Result GetRightsIdFromContentIdDeprecated(sf::Out<ams::fs::RightsId> out_rights_id, ContentId content_id) override;
virtual Result GetRightsIdFromContentId(sf::Out<ncm::RightsId> out_rights_id, ContentId content_id) override;
virtual Result WriteContentForDebug(ContentId content_id, s64 offset, sf::InBuffer data) override;
virtual Result WriteContentForDebug(ContentId content_id, s64 offset, const sf::InBuffer &data) override;
virtual Result GetFreeSpaceSize(sf::Out<s64> out_size) override;
virtual Result GetTotalSpaceSize(sf::Out<s64> out_size) override;
virtual Result FlushPlaceHolder() override;

View File

@@ -49,7 +49,7 @@ namespace ams::ncm {
virtual Result CreatePlaceHolder(PlaceHolderId placeholder_id, ContentId content_id, s64 size) = 0;
virtual Result DeletePlaceHolder(PlaceHolderId placeholder_id) = 0;
virtual Result HasPlaceHolder(sf::Out<bool> out, PlaceHolderId placeholder_id) = 0;
virtual Result WritePlaceHolder(PlaceHolderId placeholder_id, s64 offset, sf::InBuffer data) = 0;
virtual Result WritePlaceHolder(PlaceHolderId placeholder_id, s64 offset, const sf::InBuffer &data) = 0;
virtual Result Register(PlaceHolderId placeholder_id, ContentId content_id) = 0;
virtual Result Delete(ContentId content_id) = 0;
virtual Result Has(sf::Out<bool> out, ContentId content_id) = 0;
@@ -63,12 +63,12 @@ namespace ams::ncm {
virtual Result DisableForcibly() = 0;
virtual Result RevertToPlaceHolder(PlaceHolderId placeholder_id, ContentId old_content_id, ContentId new_content_id) = 0;
virtual Result SetPlaceHolderSize(PlaceHolderId placeholder_id, s64 size) = 0;
virtual Result ReadContentIdFile(sf::OutBuffer buf, ContentId content_id, s64 offset) = 0;
virtual Result ReadContentIdFile(const sf::OutBuffer &buf, ContentId content_id, s64 offset) = 0;
virtual Result GetRightsIdFromPlaceHolderIdDeprecated(sf::Out<ams::fs::RightsId> out_rights_id, PlaceHolderId placeholder_id) = 0;
virtual Result GetRightsIdFromPlaceHolderId(sf::Out<ncm::RightsId> out_rights_id, PlaceHolderId placeholder_id) = 0;
virtual Result GetRightsIdFromContentIdDeprecated(sf::Out<ams::fs::RightsId> out_rights_id, ContentId content_id) = 0;
virtual Result GetRightsIdFromContentId(sf::Out<ncm::RightsId> out_rights_id, ContentId content_id) = 0;
virtual Result WriteContentForDebug(ContentId content_id, s64 offset, sf::InBuffer data) = 0;
virtual Result WriteContentForDebug(ContentId content_id, s64 offset, const sf::InBuffer &data) = 0;
virtual Result GetFreeSpaceSize(sf::Out<s64> out_size) = 0;
virtual Result GetTotalSpaceSize(sf::Out<s64> out_size) = 0;
virtual Result FlushPlaceHolder() = 0;

View File

@@ -76,7 +76,7 @@ namespace ams::ncm {
return ncm::ResultWriteToReadOnlyContentStorage();
}
Result ReadOnlyContentStorageImpl::WritePlaceHolder(PlaceHolderId placeholder_id, s64 offset, sf::InBuffer data) {
Result ReadOnlyContentStorageImpl::WritePlaceHolder(PlaceHolderId placeholder_id, s64 offset, const sf::InBuffer &data) {
return ncm::ResultWriteToReadOnlyContentStorage();
}
@@ -182,7 +182,7 @@ namespace ams::ncm {
return ncm::ResultWriteToReadOnlyContentStorage();
}
Result ReadOnlyContentStorageImpl::ReadContentIdFile(sf::OutBuffer buf, ContentId content_id, s64 offset) {
Result ReadOnlyContentStorageImpl::ReadContentIdFile(const sf::OutBuffer &buf, ContentId content_id, s64 offset) {
/* Ensure offset is valid. */
R_UNLESS(offset >= 0, ncm::ResultInvalidOffset());
R_TRY(this->EnsureEnabled());
@@ -231,7 +231,7 @@ namespace ams::ncm {
return ResultSuccess();
}
Result ReadOnlyContentStorageImpl::WriteContentForDebug(ContentId content_id, s64 offset, sf::InBuffer data) {
Result ReadOnlyContentStorageImpl::WriteContentForDebug(ContentId content_id, s64 offset, const sf::InBuffer &data) {
return ncm::ResultWriteToReadOnlyContentStorage();
}

View File

@@ -28,7 +28,7 @@ namespace ams::ncm {
virtual Result CreatePlaceHolder(PlaceHolderId placeholder_id, ContentId content_id, s64 size) override;
virtual Result DeletePlaceHolder(PlaceHolderId placeholder_id) override;
virtual Result HasPlaceHolder(sf::Out<bool> out, PlaceHolderId placeholder_id) override;
virtual Result WritePlaceHolder(PlaceHolderId placeholder_id, s64 offset, sf::InBuffer data) override;
virtual Result WritePlaceHolder(PlaceHolderId placeholder_id, s64 offset, const sf::InBuffer &data) override;
virtual Result Register(PlaceHolderId placeholder_id, ContentId content_id) override;
virtual Result Delete(ContentId content_id) override;
virtual Result Has(sf::Out<bool> out, ContentId content_id) override;
@@ -42,12 +42,12 @@ namespace ams::ncm {
virtual Result DisableForcibly() override;
virtual Result RevertToPlaceHolder(PlaceHolderId placeholder_id, ContentId old_content_id, ContentId new_content_id) override;
virtual Result SetPlaceHolderSize(PlaceHolderId placeholder_id, s64 size) override;
virtual Result ReadContentIdFile(sf::OutBuffer buf, ContentId content_id, s64 offset) override;
virtual Result ReadContentIdFile(const sf::OutBuffer &buf, ContentId content_id, s64 offset) override;
virtual Result GetRightsIdFromPlaceHolderIdDeprecated(sf::Out<ams::fs::RightsId> out_rights_id, PlaceHolderId placeholder_id) override;
virtual Result GetRightsIdFromPlaceHolderId(sf::Out<ncm::RightsId> out_rights_id, PlaceHolderId placeholder_id) override;
virtual Result GetRightsIdFromContentIdDeprecated(sf::Out<ams::fs::RightsId> out_rights_id, ContentId content_id) override;
virtual Result GetRightsIdFromContentId(sf::Out<ncm::RightsId> out_rights_id, ContentId content_id) override;
virtual Result WriteContentForDebug(ContentId content_id, s64 offset, sf::InBuffer data) override;
virtual Result WriteContentForDebug(ContentId content_id, s64 offset, const sf::InBuffer &data) override;
virtual Result GetFreeSpaceSize(sf::Out<s64> out_size) override;
virtual Result GetTotalSpaceSize(sf::Out<s64> out_size) override;
virtual Result FlushPlaceHolder() override;

View File

@@ -20,7 +20,10 @@
namespace ams::ncm {
class RemoteContentManagerImpl final {
class RemoteContentManagerImpl {
private:
/* TODO: sf::ProxyObjectAllocator */
using ObjectFactory = sf::ObjectFactory<sf::StdAllocationPolicy<std::allocator>>;
public:
RemoteContentManagerImpl() { /* ... */ }
@@ -42,19 +45,19 @@ namespace ams::ncm {
return ::ncmVerifyContentMetaDatabase(static_cast<NcmStorageId>(storage_id));
}
Result OpenContentStorage(sf::Out<std::shared_ptr<IContentStorage>> out, StorageId storage_id) {
Result OpenContentStorage(sf::Out<sf::SharedPointer<IContentStorage>> out, StorageId storage_id) {
NcmContentStorage cs;
R_TRY(::ncmOpenContentStorage(std::addressof(cs), static_cast<NcmStorageId>(storage_id)));
out.SetValue(sf::MakeShared<IContentStorage, RemoteContentStorageImpl>(cs));
out.SetValue(ObjectFactory::CreateSharedEmplaced<IContentStorage, RemoteContentStorageImpl>(cs));
return ResultSuccess();
}
Result OpenContentMetaDatabase(sf::Out<std::shared_ptr<IContentMetaDatabase>> out, StorageId storage_id) {
Result OpenContentMetaDatabase(sf::Out<sf::SharedPointer<IContentMetaDatabase>> out, StorageId storage_id) {
NcmContentMetaDatabase db;
R_TRY(::ncmOpenContentMetaDatabase(std::addressof(db), static_cast<NcmStorageId>(storage_id)));
out.SetValue(sf::MakeShared<IContentMetaDatabase, RemoteContentMetaDatabaseImpl>(db));
out.SetValue(ObjectFactory::CreateSharedEmplaced<IContentMetaDatabase, RemoteContentMetaDatabaseImpl>(db));
return ResultSuccess();
}

View File

@@ -18,7 +18,7 @@
namespace ams::ncm {
class RemoteContentMetaDatabaseImpl final {
class RemoteContentMetaDatabaseImpl {
private:
::NcmContentMetaDatabase srv;
public:
@@ -71,11 +71,11 @@ namespace ams::ncm {
return reinterpret_cast<const ::NcmContentId *>(std::addressof(c));
}
public:
Result Set(const ContentMetaKey &key, sf::InBuffer value) {
Result Set(const ContentMetaKey &key, const sf::InBuffer &value) {
return ncmContentMetaDatabaseSet(std::addressof(this->srv), Convert(key), value.GetPointer(), value.GetSize());
}
Result Get(sf::Out<u64> out_size, const ContentMetaKey &key, sf::OutBuffer out_value) {
Result Get(sf::Out<u64> out_size, const ContentMetaKey &key, const sf::OutBuffer &out_value) {
return ncmContentMetaDatabaseGet(std::addressof(this->srv), Convert(key), out_size.GetPointer(), out_value.GetPointer(), out_value.GetSize());
}

View File

@@ -18,7 +18,7 @@
namespace ams::ncm {
class RemoteContentStorageImpl final {
class RemoteContentStorageImpl {
private:
::NcmContentStorage srv;
public:
@@ -63,7 +63,7 @@ namespace ams::ncm {
return ncmContentStorageHasPlaceHolder(std::addressof(this->srv), out.GetPointer(), Convert(placeholder_id));
}
Result WritePlaceHolder(PlaceHolderId placeholder_id, s64 offset, sf::InBuffer data) {
Result WritePlaceHolder(PlaceHolderId placeholder_id, s64 offset, const sf::InBuffer &data) {
return ncmContentStorageWritePlaceHolder(std::addressof(this->srv), Convert(placeholder_id), offset, data.GetPointer(), data.GetSize());
}
@@ -120,7 +120,7 @@ namespace ams::ncm {
return ncmContentStorageSetPlaceHolderSize(std::addressof(this->srv), Convert(placeholder_id), size);
}
Result ReadContentIdFile(sf::OutBuffer buf, ContentId content_id, s64 offset) {
Result ReadContentIdFile(const sf::OutBuffer &buf, ContentId content_id, s64 offset) {
return ncmContentStorageReadContentIdFile(std::addressof(this->srv), buf.GetPointer(), buf.GetSize(), Convert(content_id), offset);
}
@@ -160,7 +160,7 @@ namespace ams::ncm {
return ResultSuccess();
}
Result WriteContentForDebug(ContentId content_id, s64 offset, sf::InBuffer data) {
Result WriteContentForDebug(ContentId content_id, s64 offset, const sf::InBuffer &data) {
return ncmContentStorageWriteContentForDebug(std::addressof(this->srv), Convert(content_id), offset, data.GetPointer(), data.GetSize());
}

View File

@@ -18,7 +18,7 @@
namespace ams::pgl {
class RemoteEventObserver final {
class RemoteEventObserver {
NON_COPYABLE(RemoteEventObserver);
NON_MOVEABLE(RemoteEventObserver);
private:

View File

@@ -79,10 +79,11 @@ namespace ams::pgl {
::PglEventObserver obs;
R_TRY(::pglGetEventObserver(std::addressof(obs)));
auto remote_observer = ams::sf::MakeShared<pgl::sf::IEventObserver, RemoteEventObserver>(obs);
AMS_ABORT_UNLESS(remote_observer != nullptr);
/* TODO: Real allocator */
auto remote_observer = ams::sf::CreateSharedObjectEmplaced<pgl::sf::IEventObserver, RemoteEventObserver>(obs);
R_UNLESS(remote_observer != nullptr, pgl::ResultOutOfMemory());
*out = pgl::EventObserver(remote_observer);
*out = pgl::EventObserver(std::move(remote_observer));
return ResultSuccess();
}

View File

@@ -34,7 +34,7 @@ namespace ams::pgl::srv {
}
};
class ShellEventObserver final : public IShellEventObserver {
class ShellEventObserver : public IShellEventObserver {
private:
static constexpr size_t QueueCapacity = 0x20;
private:

View File

@@ -20,6 +20,12 @@
namespace ams::pgl::srv {
namespace {
using ShellEventObjectFactory = ams::sf::ObjectFactory<ams::sf::MemoryResourceAllocationPolicy>;
}
Result ShellInterface::LaunchProgram(ams::sf::Out<os::ProcessId> out, const ncm::ProgramLocation &loc, u32 pm_flags, u8 pgl_flags) {
return pgl::srv::LaunchProgram(out.GetPointer(), loc, pm_flags, pgl_flags);
}
@@ -68,24 +74,12 @@ namespace ams::pgl::srv {
return pgl::srv::TriggerApplicationSnapShotDumper(dump_type, reinterpret_cast<const char *>(arg.GetPointer()));
}
Result ShellInterface::GetShellEventObserver(ams::sf::Out<std::shared_ptr<pgl::sf::IEventObserver>> out) {
using Interface = typename pgl::sf::IEventObserver::ImplHolder<ShellEventObserver>;
Result ShellInterface::GetShellEventObserver(ams::sf::Out<ams::sf::SharedPointer<pgl::sf::IEventObserver>> out) {
/* Allocate a new interface. */
auto *observer_memory = this->memory_resource->Allocate(sizeof(Interface), alignof(Interface));
AMS_ABORT_UNLESS(observer_memory != nullptr);
auto session = ShellEventObjectFactory::CreateSharedEmplaced<pgl::sf::IEventObserver, ShellEventObserver>(this->memory_resource);
R_UNLESS(session != nullptr, pgl::ResultOutOfMemory());
/* Create the interface object. */
new (observer_memory) Interface;
/* Set the output. */
out.SetValue(std::shared_ptr<pgl::sf::IEventObserver>(reinterpret_cast<Interface *>(observer_memory), [&](Interface *obj) {
/* Destroy the object. */
obj->~Interface();
/* Custom deleter: use the memory resource to free. */
this->memory_resource->Deallocate(obj, sizeof(Interface), alignof(Interface));
}));
*out = std::move(session);
return ResultSuccess();
}

View File

@@ -34,7 +34,8 @@ namespace ams::psc {
::PscPmModule module;
R_TRY(::pscmGetPmModule(std::addressof(module), static_cast<::PscPmModuleId>(mid), reinterpret_cast<const u16 *>(dependencies), dependency_count, clear_mode == os::EventClearMode_AutoClear));
this->intf = ams::sf::MakeShared<psc::sf::IPmModule, RemotePmModule>(module);
/* TODO: Proper allocator */
this->intf = ams::sf::CreateSharedObjectEmplaced<psc::sf::IPmModule, RemotePmModule>(module);
this->system_event.AttachReadableHandle(module.event.revent, false, clear_mode);
this->initialized = true;
return ResultSuccess();

View File

@@ -18,7 +18,7 @@
namespace ams::psc {
class RemotePmModule final {
class RemotePmModule {
NON_COPYABLE(RemotePmModule);
NON_MOVEABLE(RemotePmModule);
private:

View File

@@ -22,22 +22,20 @@ namespace ams::pwm {
constinit os::SdkMutex g_init_mutex;
constinit int g_initialize_count = 0;
std::shared_ptr<sf::IManager> g_pwm_manager;
ams::sf::SharedPointer<pwm::sf::IManager> g_pwm_manager;
using InternalSession = std::shared_ptr<pwm::sf::IChannelSession>;
InternalSession &GetInterface(const ChannelSession &session) {
pwm::sf::IChannelSession *GetInterface(const ChannelSession &session) {
AMS_ASSERT(session._session != nullptr);
return *static_cast<InternalSession *>(session._session);
return static_cast<pwm::sf::IChannelSession *>(session._session);
}
}
void InitializeWith(std::shared_ptr<pwm::sf::IManager> &&sp) {
void InitializeWith(ams::sf::SharedPointer<pwm::sf::IManager> sp) {
std::scoped_lock lk(g_init_mutex);
AMS_ABORT_UNLESS(g_initialize_count == 0);
g_pwm_manager = std::move(sp);
g_pwm_manager = sp;
g_initialize_count = 1;
}
@@ -48,38 +46,31 @@ namespace ams::pwm {
AMS_ASSERT(g_initialize_count > 0);
if ((--g_initialize_count) == 0) {
g_pwm_manager.reset();
g_pwm_manager.Reset();
}
}
Result OpenSession(ChannelSession *out, DeviceCode device_code) {
/* Allocate the session. */
InternalSession *internal_session = new (std::nothrow) InternalSession;
AMS_ABORT_UNLESS(internal_session != nullptr);
auto session_guard = SCOPE_GUARD { delete internal_session; };
/* Get the session. */
ams::sf::SharedPointer<pwm::sf::IChannelSession> session;
{
ams::sf::cmif::ServiceObjectHolder object_holder;
if (hos::GetVersion() >= hos::Version_6_0_0) {
R_TRY(g_pwm_manager->OpenSession2(std::addressof(object_holder), device_code));
R_TRY(g_pwm_manager->OpenSession2(std::addressof(session), device_code));
} else {
R_TRY(g_pwm_manager->OpenSession(std::addressof(object_holder), ConvertToChannelName(device_code)));
R_TRY(g_pwm_manager->OpenSession(std::addressof(session), ConvertToChannelName(device_code)));
}
*internal_session = object_holder.GetServiceObject<sf::IChannelSession>();
}
/* Set output. */
out->_session = internal_session;
out->_session = session.Detach();
/* We succeeded. */
session_guard.Cancel();
return ResultSuccess();
}
void CloseSession(ChannelSession &session) {
/* Close the session. */
delete std::addressof(GetInterface(session));
ams::sf::ReleaseSharedObject(GetInterface(session));
session._session = nullptr;
}

View File

@@ -20,17 +20,12 @@ namespace ams::pwm::server {
namespace {
ManagerImpl g_manager_impl;
std::shared_ptr<pwm::sf::IManager> GetManagerServiceObject() {
static std::shared_ptr<pwm::sf::IManager> s_sp = ams::sf::GetSharedPointerTo<pwm::sf::IManager>(g_manager_impl);
return s_sp;
}
ams::sf::UnmanagedServiceObject<pwm::sf::IManager, pwm::server::ManagerImpl> g_manager_impl;
}
std::shared_ptr<pwm::sf::IManager> GetServiceObject() {
return GetManagerServiceObject();
ams::sf::SharedPointer<pwm::sf::IManager> GetServiceObject() {
return g_manager_impl.GetShared();
}
}

View File

@@ -18,33 +18,33 @@
namespace ams::pwm::server {
ManagerImpl::ManagerImpl() : session_memory_resource(), allocator(std::addressof(session_memory_resource)) {
ManagerImpl::ManagerImpl() {
this->heap_handle = lmem::CreateExpHeap(this->heap_buffer, sizeof(this->heap_buffer), lmem::CreateOption_None);
this->session_memory_resource.Attach(this->heap_handle);
this->allocator.Attach(this->heap_handle);
}
ManagerImpl::~ManagerImpl() {
lmem::DestroyExpHeap(this->heap_handle);
}
Result ManagerImpl::OpenSessionForDev(ams::sf::Out<std::shared_ptr<pwm::sf::IChannelSession>> out, int channel) {
Result ManagerImpl::OpenSessionForDev(ams::sf::Out<ams::sf::SharedPointer<pwm::sf::IChannelSession>> out, int channel) {
/* TODO */
AMS_ABORT();
}
Result ManagerImpl::OpenSession(ams::sf::Out<std::shared_ptr<pwm::sf::IChannelSession>> out, pwm::ChannelName channel_name) {
Result ManagerImpl::OpenSession(ams::sf::Out<ams::sf::SharedPointer<pwm::sf::IChannelSession>> out, pwm::ChannelName channel_name) {
return this->OpenSession2(out, ConvertToDeviceCode(channel_name));
}
Result ManagerImpl::OpenSession2(ams::sf::Out<std::shared_ptr<pwm::sf::IChannelSession>> out, DeviceCode device_code) {
Result ManagerImpl::OpenSession2(ams::sf::Out<ams::sf::SharedPointer<pwm::sf::IChannelSession>> out, DeviceCode device_code) {
/* Allocate a session. */
auto session = ams::sf::AllocateShared<pwm::sf::IChannelSession, ChannelSessionImpl>(this->allocator, this);
auto session = Factory::CreateSharedEmplaced<pwm::sf::IChannelSession, ChannelSessionImpl>(std::addressof(this->allocator), this);
/* Open the session. */
R_TRY(session->GetImpl().OpenSession(device_code));
R_TRY(session.GetImpl().OpenSession(device_code));
/* We succeeded. */
out.SetValue(std::move(session));
*out = std::move(session);
return ResultSuccess();
}

View File

@@ -20,10 +20,12 @@
namespace ams::pwm::server {
class ManagerImpl {
private:
using Allocator = ams::sf::ExpHeapAllocator;
using Factory = ams::sf::ObjectFactory<Allocator::Policy>;
private:
lmem::HeapHandle heap_handle;
ams::sf::ExpHeapMemoryResource session_memory_resource;
typename ams::sf::ServiceObjectAllocator<pwm::sf::IChannelSession, ChannelSessionImpl> allocator;
Allocator allocator;
u8 heap_buffer[4_KB];
public:
ManagerImpl();
@@ -31,9 +33,9 @@ namespace ams::pwm::server {
~ManagerImpl();
public:
/* Actual commands. */
Result OpenSessionForDev(ams::sf::Out<std::shared_ptr<pwm::sf::IChannelSession>> out, int channel);
Result OpenSession(ams::sf::Out<std::shared_ptr<pwm::sf::IChannelSession>> out, pwm::ChannelName channel_name);
Result OpenSession2(ams::sf::Out<std::shared_ptr<pwm::sf::IChannelSession>> out, DeviceCode device_code);
Result OpenSessionForDev(ams::sf::Out<ams::sf::SharedPointer<pwm::sf::IChannelSession>> out, int channel);
Result OpenSession(ams::sf::Out<ams::sf::SharedPointer<pwm::sf::IChannelSession>> out, pwm::ChannelName channel_name);
Result OpenSession2(ams::sf::Out<ams::sf::SharedPointer<pwm::sf::IChannelSession>> out, DeviceCode device_code);
};
static_assert(pwm::sf::IsIManager<ManagerImpl>);

View File

@@ -31,7 +31,7 @@ namespace ams::sf::cmif {
}
}
void ServerDomainManager::Domain::DestroySelf() {
void ServerDomainManager::Domain::DisposeImpl() {
ServerDomainManager *manager = this->manager;
this->~Domain();
manager->FreeDomain(this);

View File

@@ -16,16 +16,15 @@
#include <stratosphere.hpp>
#include "sf_hipc_mitm_query_api.hpp"
#define AMS_SF_HIPC_IMPL_I_MITM_QUERY_SERVICE_INTERFACE_INFO(C, H) \
AMS_SF_METHOD_INFO(C, H, 65000, void, ShouldMitm, (sf::Out<bool> out, const sm::MitmProcessInfo &client_info), (out, client_info))
AMS_SF_DEFINE_INTERFACE(ams::sf::hipc::impl, IMitmQueryService, AMS_SF_HIPC_IMPL_I_MITM_QUERY_SERVICE_INTERFACE_INFO)
namespace ams::sf::hipc::impl {
namespace {
#define AMS_SF_HIPC_IMPL_I_MITM_QUERY_SERVICE_INTERFACE_INFO(C, H) \
AMS_SF_METHOD_INFO(C, H, 65000, void, ShouldMitm, (sf::Out<bool> out, const sm::MitmProcessInfo &client_info))
AMS_SF_DEFINE_INTERFACE(IMitmQueryService, AMS_SF_HIPC_IMPL_I_MITM_QUERY_SERVICE_INTERFACE_INFO)
class MitmQueryService {
private:
ServerManagerBase::MitmQueryFunction query_function;
@@ -33,23 +32,22 @@ namespace ams::sf::hipc::impl {
MitmQueryService(ServerManagerBase::MitmQueryFunction qf) : query_function(qf) { /* ... */ }
void ShouldMitm(sf::Out<bool> out, const sm::MitmProcessInfo &client_info) {
out.SetValue(this->query_function(client_info));
*out = this->query_function(client_info);
}
};
static_assert(IsIMitmQueryService<MitmQueryService>);
/* Globals. */
os::Mutex g_query_server_lock(false);
bool g_constructed_server = false;
bool g_registered_any = false;
constinit os::SdkMutex g_query_server_lock;
constinit bool g_constructed_server = false;
constinit bool g_registered_any = false;
void QueryServerProcessThreadMain(void *query_server) {
reinterpret_cast<ServerManagerBase *>(query_server)->LoopProcess();
}
constexpr size_t QueryServerProcessThreadStackSize = 0x4000;
alignas(os::ThreadStackAlignment) u8 g_server_process_thread_stack[QueryServerProcessThreadStackSize];
os::ThreadType g_query_server_process_thread;
alignas(os::ThreadStackAlignment) constinit u8 g_server_process_thread_stack[16_KB];
constinit os::ThreadType g_query_server_process_thread;
constexpr size_t MaxServers = 0;
TYPED_STORAGE(sf::hipc::ServerManager<MaxServers>) g_query_server_storage;
@@ -59,13 +57,13 @@ namespace ams::sf::hipc::impl {
void RegisterMitmQueryHandle(Handle query_handle, ServerManagerBase::MitmQueryFunction query_func) {
std::scoped_lock lk(g_query_server_lock);
if (AMS_UNLIKELY(!g_constructed_server)) {
new (GetPointer(g_query_server_storage)) sf::hipc::ServerManager<MaxServers>();
g_constructed_server = true;
}
R_ABORT_UNLESS(GetPointer(g_query_server_storage)->RegisterSession(query_handle, cmif::ServiceObjectHolder(sf::MakeShared<IMitmQueryService, MitmQueryService>(query_func))));
/* TODO: Better object factory? */
R_ABORT_UNLESS(GetPointer(g_query_server_storage)->RegisterSession(query_handle, cmif::ServiceObjectHolder(sf::CreateSharedObjectEmplaced<IMitmQueryService, MitmQueryService>(query_func))));
if (AMS_UNLIKELY(!g_registered_any)) {
R_ABORT_UNLESS(os::CreateThread(std::addressof(g_query_server_process_thread), &QueryServerProcessThreadMain, GetPointer(g_query_server_storage), g_server_process_thread_stack, sizeof(g_server_process_thread_stack), AMS_GET_SYSTEM_THREAD_PRIORITY(mitm_sf, QueryServerProcessThread)));

View File

@@ -15,20 +15,20 @@
*/
#include <stratosphere.hpp>
#define AMS_SF_HIPC_IMPL_I_HIPC_MANAGER_INTERFACE_INFO(C, H) \
AMS_SF_METHOD_INFO(C, H, 0, Result, ConvertCurrentObjectToDomain, (ams::sf::Out<ams::sf::cmif::DomainObjectId> out), (out)) \
AMS_SF_METHOD_INFO(C, H, 1, Result, CopyFromCurrentDomain, (ams::sf::OutMoveHandle out, ams::sf::cmif::DomainObjectId object_id), (out, object_id)) \
AMS_SF_METHOD_INFO(C, H, 2, Result, CloneCurrentObject, (ams::sf::OutMoveHandle out), (out)) \
AMS_SF_METHOD_INFO(C, H, 3, void, QueryPointerBufferSize, (ams::sf::Out<u16> out), (out)) \
AMS_SF_METHOD_INFO(C, H, 4, Result, CloneCurrentObjectEx, (ams::sf::OutMoveHandle out, u32 tag), (out, tag))
AMS_SF_DEFINE_INTERFACE(ams::sf::hipc::impl, IHipcManager, AMS_SF_HIPC_IMPL_I_HIPC_MANAGER_INTERFACE_INFO)
namespace ams::sf::hipc {
namespace impl {
#define AMS_SF_HIPC_IMPL_I_HIPC_MANAGER_INTERFACE_INFO(C, H) \
AMS_SF_METHOD_INFO(C, H, 0, Result, ConvertCurrentObjectToDomain, (ams::sf::Out<ams::sf::cmif::DomainObjectId> out)) \
AMS_SF_METHOD_INFO(C, H, 1, Result, CopyFromCurrentDomain, (ams::sf::OutMoveHandle out, ams::sf::cmif::DomainObjectId object_id)) \
AMS_SF_METHOD_INFO(C, H, 2, Result, CloneCurrentObject, (ams::sf::OutMoveHandle out)) \
AMS_SF_METHOD_INFO(C, H, 3, void, QueryPointerBufferSize, (ams::sf::Out<u16> out)) \
AMS_SF_METHOD_INFO(C, H, 4, Result, CloneCurrentObjectEx, (ams::sf::OutMoveHandle out, u32 tag))
AMS_SF_DEFINE_INTERFACE(IHipcManager, AMS_SF_HIPC_IMPL_I_HIPC_MANAGER_INTERFACE_INFO)
class HipcManager final {
class HipcManagerImpl {
private:
ServerDomainSessionManager *manager;
ServerSession *session;
@@ -56,7 +56,7 @@ namespace ams::sf::hipc {
return ResultSuccess();
}
public:
explicit HipcManager(ServerDomainSessionManager *m, ServerSession *s) : manager(m), session(s), is_mitm_session(s->forward_service != nullptr) {
explicit HipcManagerImpl(ServerDomainSessionManager *m, ServerSession *s) : manager(m), session(s), is_mitm_session(s->forward_service != nullptr) {
/* ... */
}
@@ -64,14 +64,14 @@ namespace ams::sf::hipc {
/* Allocate a domain. */
auto domain = this->manager->AllocateDomainServiceObject();
R_UNLESS(domain, sf::hipc::ResultOutOfDomains());
auto domain_guard = SCOPE_GUARD { cmif::ServerDomainManager::DestroyDomainServiceObject(static_cast<cmif::DomainServiceObject *>(domain)); };
/* Set up the new domain object. */
cmif::DomainObjectId object_id = cmif::InvalidDomainObjectId;
cmif::ServiceObjectHolder new_holder;
if (this->is_mitm_session) {
/* If we're a mitm session, we need to convert the remote session to domain. */
/* Make a new shared pointer to manage the allocated domain. */
SharedPointer<cmif::MitmDomainServiceObject> cmif_domain(static_cast<cmif::MitmDomainServiceObject *>(domain), false);
/* Convert the remote session to domain. */
AMS_ABORT_UNLESS(session->forward_service->own_handle);
R_TRY(serviceConvertToDomain(session->forward_service.get()));
@@ -79,27 +79,28 @@ namespace ams::sf::hipc {
object_id = cmif::DomainObjectId{session->forward_service->object_id};
domain->ReserveSpecificIds(&object_id, 1);
/* Create new object. */
cmif::MitmDomainServiceObject *domain_ptr = static_cast<cmif::MitmDomainServiceObject *>(domain);
new_holder = cmif::ServiceObjectHolder(std::move(std::shared_ptr<cmif::MitmDomainServiceObject>(domain_ptr, cmif::ServerDomainManager::DestroyDomainServiceObject)));
/* Register the object. */
domain->RegisterObject(object_id, std::move(session->srv_obj_holder));
/* Set the new object holder. */
session->srv_obj_holder = cmif::ServiceObjectHolder(std::move(cmif_domain));
} else {
/* We're not a mitm session. Reserve a new object in the domain. */
/* Make a new shared pointer to manage the allocated domain. */
SharedPointer<cmif::DomainServiceObject> cmif_domain(domain, false);
/* Reserve a new object in the domain. */
R_TRY(domain->ReserveIds(&object_id, 1));
/* Create new object. */
cmif::DomainServiceObject *domain_ptr = static_cast<cmif::DomainServiceObject *>(domain);
new_holder = cmif::ServiceObjectHolder(std::move(std::shared_ptr<cmif::DomainServiceObject>(domain_ptr, cmif::ServerDomainManager::DestroyDomainServiceObject)));
/* Register the object. */
domain->RegisterObject(object_id, std::move(session->srv_obj_holder));
/* Set the new object holder. */
session->srv_obj_holder = cmif::ServiceObjectHolder(std::move(cmif_domain));
}
/* Return the allocated id. */
AMS_ABORT_UNLESS(object_id != cmif::InvalidDomainObjectId);
AMS_ABORT_UNLESS(static_cast<bool>(new_holder));
/* We succeeded! */
domain_guard.Cancel();
domain->RegisterObject(object_id, std::move(session->srv_obj_holder));
session->srv_obj_holder = std::move(new_holder);
out.SetValue(object_id);
*out = object_id;
return ResultSuccess();
}
@@ -152,7 +153,7 @@ namespace ams::sf::hipc {
return this->CloneCurrentObjectImpl(out.GetHandlePointer(), this->manager->GetSessionManagerByTag(tag));
}
};
static_assert(IsIHipcManager<HipcManager>);
static_assert(IsIHipcManager<HipcManagerImpl>);
}
@@ -160,8 +161,8 @@ namespace ams::sf::hipc {
/* Make a stack object, and pass a shared pointer to it to DispatchRequest. */
/* Note: This is safe, as no additional references to the hipc manager can ever be stored. */
/* The shared pointer to stack object is definitely gross, though. */
impl::HipcManager hipc_manager(this, session);
return this->DispatchRequest(cmif::ServiceObjectHolder(sf::GetSharedPointerTo<impl::IHipcManager>(hipc_manager)), session, in_message, out_message);
UnmanagedServiceObject<impl::IHipcManager, impl::HipcManagerImpl> hipc_manager(this, session);
return this->DispatchRequest(cmif::ServiceObjectHolder(hipc_manager.GetShared()), session, in_message, out_message);
}
}

View File

@@ -18,8 +18,6 @@
namespace ams::sf::hipc {
ServerManagerBase::ServerBase::~ServerBase() { /* Pure virtual destructor, to prevent linker errors. */ }
Result ServerManagerBase::InstallMitmServerImpl(Handle *out_port_handle, sm::ServiceName service_name, ServerManagerBase::MitmQueryFunction query_func) {
/* Install the Mitm. */
Handle query_handle;
@@ -89,37 +87,25 @@ namespace ams::sf::hipc {
Result ServerManagerBase::ProcessForServer(os::WaitableHolderType *holder) {
AMS_ABORT_UNLESS(static_cast<UserDataTag>(os::GetWaitableHolderUserData(holder)) == UserDataTag::Server);
ServerBase *server = static_cast<ServerBase *>(holder);
Server *server = static_cast<Server *>(holder);
ON_SCOPE_EXIT { this->RegisterToWaitList(server); };
/* Create resources for new session. */
cmif::ServiceObjectHolder obj;
std::shared_ptr<::Service> fsrv;
server->CreateSessionObjectHolder(&obj, &fsrv);
/* Not a mitm server, so we must have no forward service. */
AMS_ABORT_UNLESS(fsrv == nullptr);
/* Try to accept. */
return this->AcceptSession(server->port_handle, std::move(obj));
/* Create new session. */
if (server->static_object) {
return this->AcceptSession(server->port_handle, server->static_object.Clone());
} else {
return this->OnNeedsToAccept(server->index, server);
}
}
Result ServerManagerBase::ProcessForMitmServer(os::WaitableHolderType *holder) {
AMS_ABORT_UNLESS(static_cast<UserDataTag>(os::GetWaitableHolderUserData(holder)) == UserDataTag::MitmServer);
ServerBase *server = static_cast<ServerBase *>(holder);
Server *server = static_cast<Server *>(holder);
ON_SCOPE_EXIT { this->RegisterToWaitList(server); };
/* Create resources for new session. */
cmif::ServiceObjectHolder obj;
std::shared_ptr<::Service> fsrv;
server->CreateSessionObjectHolder(&obj, &fsrv);
/* Mitm server, so we must have forward service. */
AMS_ABORT_UNLESS(fsrv != nullptr);
/* Try to accept. */
return this->AcceptMitmSession(server->port_handle, std::move(obj), std::move(fsrv));
return this->OnNeedsToAccept(server->index, server);
}
Result ServerManagerBase::ProcessForSession(os::WaitableHolderType *holder) {

View File

@@ -0,0 +1,161 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stratosphere.hpp>
namespace ams::sf {
namespace {
struct DefaultAllocatorImpl {
os::SdkMutexType tls_lock;
std::atomic_bool tls_allocated;
os::TlsSlot current_mr_tls_slot;
MemoryResource *default_mr;
void EnsureCurrentMemoryResourceTlsSlotInitialized() {
if (!tls_allocated.load(std::memory_order_acquire)) {
os::LockSdkMutex(std::addressof(tls_lock));
if (!tls_allocated.load(std::memory_order_relaxed)) {
R_ABORT_UNLESS(os::SdkAllocateTlsSlot(std::addressof(current_mr_tls_slot), nullptr));
tls_allocated.store(true, std::memory_order_release);
}
os::UnlockSdkMutex(std::addressof(tls_lock));
}
}
MemoryResource *GetDefaultMemoryResource() {
return default_mr;
}
MemoryResource *SetDefaultMemoryResource(MemoryResource *mr) {
return util::Exchange(std::addressof(default_mr), mr);
}
MemoryResource *GetCurrentMemoryResource() {
EnsureCurrentMemoryResourceTlsSlotInitialized();
return reinterpret_cast<MemoryResource *>(os::GetTlsValue(current_mr_tls_slot));
}
MemoryResource *SetCurrentMemoryResource(MemoryResource *mr) {
EnsureCurrentMemoryResourceTlsSlotInitialized();
auto ret = reinterpret_cast<MemoryResource *>(os::GetTlsValue(current_mr_tls_slot));
os::SetTlsValue(current_mr_tls_slot, reinterpret_cast<uintptr_t>(mr));
return ret;
}
MemoryResource *GetCurrentEffectiveMemoryResourceImpl() {
if (auto mr = GetCurrentMemoryResource(); mr != nullptr) {
return mr;
}
if (auto mr = GetGlobalDefaultMemoryResource(); mr != nullptr) {
return mr;
}
return nullptr;
}
};
constinit DefaultAllocatorImpl g_default_allocator_impl = {};
inline void *DefaultAllocate(size_t size, size_t align) {
return ::operator new(size, std::nothrow);
}
inline void DefaultDeallocate(void *ptr, size_t size, size_t align) {
return ::operator delete(ptr, std::nothrow);
}
class NewDeleteMemoryResource final : public MemoryResource {
private:
virtual void *AllocateImpl(size_t size, size_t alignment) override {
return DefaultAllocate(size, alignment);
}
virtual void DeallocateImpl(void *buffer, size_t size, size_t alignment) override {
return DefaultDeallocate(buffer, size, alignment);
}
virtual bool IsEqualImpl(const MemoryResource &resource) const {
return this == std::addressof(resource);
}
};
constinit NewDeleteMemoryResource g_new_delete_memory_resource;
}
namespace impl {
void *DefaultAllocateImpl(size_t size, size_t align, size_t offset) {
auto mr = g_default_allocator_impl.GetCurrentEffectiveMemoryResourceImpl();
auto h = mr != nullptr ? mr->allocate(size, align) : DefaultAllocate(size, align);
if (h == nullptr) {
return nullptr;
}
*static_cast<MemoryResource **>(h) = mr;
return static_cast<u8 *>(h) + offset;
}
void DefaultDeallocateImpl(void *ptr, size_t size, size_t align, size_t offset) {
if (ptr == nullptr) {
return;
}
auto h = static_cast<u8 *>(ptr) - offset;
if (auto mr = *reinterpret_cast<MemoryResource **>(h); mr != nullptr) {
return mr->deallocate(h, size, align);
} else {
return DefaultDeallocate(h, size, align);
}
}
}
MemoryResource *GetGlobalDefaultMemoryResource() {
return g_default_allocator_impl.GetDefaultMemoryResource();
}
MemoryResource *GetCurrentEffectiveMemoryResource() {
if (auto mr = g_default_allocator_impl.GetCurrentEffectiveMemoryResourceImpl(); mr != nullptr) {
return mr;
}
return GetNewDeleteMemoryResource();
}
MemoryResource *GetCurrentMemoryResource() {
return g_default_allocator_impl.GetCurrentMemoryResource();
}
MemoryResource *GetNewDeleteMemoryResource() {
return std::addressof(g_new_delete_memory_resource);
}
MemoryResource *SetGlobalDefaultMemoryResource(MemoryResource *mr) {
return g_default_allocator_impl.SetDefaultMemoryResource(mr);
}
MemoryResource *SetCurrentMemoryResource(MemoryResource *mr) {
return g_default_allocator_impl.SetCurrentMemoryResource(mr);
}
ScopedCurrentMemoryResourceSetter::ScopedCurrentMemoryResourceSetter(MemoryResource *mr) : m_prev(g_default_allocator_impl.GetCurrentMemoryResource()) {
os::SetTlsValue(g_default_allocator_impl.current_mr_tls_slot, reinterpret_cast<uintptr_t>(mr));
}
ScopedCurrentMemoryResourceSetter::~ScopedCurrentMemoryResourceSetter() {
os::SetTlsValue(g_default_allocator_impl.current_mr_tls_slot, reinterpret_cast<uintptr_t>(m_prev));
}
}