ams: prefer construct_at/destroy_at over placement new/explicit destructor

This commit is contained in:
Michael Scire 2021-03-21 20:30:40 -07:00
parent aff0da9427
commit d84dcb653d
49 changed files with 217 additions and 171 deletions

View file

@ -113,7 +113,7 @@ namespace ams::kern {
if (AMS_LIKELY(allocated != nullptr)) {
/* Construct the object. */
new (allocated) T();
std::construct_at(allocated);
/* Update our tracking. */
size_t used = m_used.fetch_add(1) + 1;

View file

@ -216,7 +216,7 @@ namespace ams::kern {
T *Allocate() {
T *obj = reinterpret_cast<T *>(this->AllocateImpl());
if (AMS_LIKELY(obj != nullptr)) {
new (obj) T();
std::construct_at(obj);
}
return obj;
}

View file

@ -23,12 +23,11 @@ namespace ams::kern {
/* Set members. */
m_owner = GetCurrentProcessPointer();
/* Initialize the page group. */
/* Get the owner page table. */
auto &page_table = m_owner->GetPageTable();
new (GetPointer(m_page_group)) KPageGroup(page_table.GetBlockInfoManager());
/* Ensure that our page group's state is valid on exit. */
auto pg_guard = SCOPE_GUARD { GetReference(m_page_group).~KPageGroup(); };
/* Construct the page group, guarding to make sure our state is valid on exit. */
auto pg_guard = util::ConstructAtGuarded(m_page_group, page_table.GetBlockInfoManager());
/* Lock the memory. */
R_TRY(page_table.LockForCodeMemory(GetPointer(m_page_group), addr, size));

View file

@ -37,7 +37,7 @@ namespace ams::kern {
/* Create the new region. */
KMemoryRegion *region = std::addressof(this->region_heap[this->num_regions++]);
new (region) KMemoryRegion(std::forward<Args>(args)...);
std::construct_at(region, std::forward<Args>(args)...);
return region;
}

View file

@ -23,12 +23,11 @@ namespace ams::kern {
/* Set members. */
m_owner = GetCurrentProcessPointer();
/* Initialize the page group. */
/* Get the owner page table. */
auto &page_table = m_owner->GetPageTable();
new (GetPointer(m_page_group)) KPageGroup(page_table.GetBlockInfoManager());
/* Ensure that our page group's state is valid on exit. */
auto pg_guard = SCOPE_GUARD { GetReference(m_page_group).~KPageGroup(); };
/* Construct the page group, guarding to make sure our state is valid on exit. */
auto pg_guard = util::ConstructAtGuarded(m_page_group, page_table.GetBlockInfoManager());
/* Lock the memory. */
R_TRY(page_table.LockForTransferMemory(GetPointer(m_page_group), addr, size, ConvertToKMemoryPermission(own_perm)));

View file

@ -80,7 +80,7 @@ namespace ams::ddsf {
DeviceCodeEntry &Construct(DeviceCode dc, IDevice *dev) {
AMS_ASSERT(!this->IsConstructed());
DeviceCodeEntry *entry = new (GetPointer(this->entry_storage)) DeviceCodeEntry(dc, dev);
DeviceCodeEntry *entry = util::ConstructAt(this->entry_storage, dc, dev);
this->is_constructed = true;
return *entry;
}
@ -91,7 +91,7 @@ namespace ams::ddsf {
void Destroy() {
AMS_ASSERT(this->IsConstructed());
GetReference(this->entry_storage).~DeviceCodeEntry();
util::DestroyAt(this->entry_storage);
this->is_constructed = false;
}

View file

@ -127,7 +127,8 @@ namespace ams::sf::cmif {
if (storage == nullptr) {
return nullptr;
}
return new (storage) Domain(this);
return std::construct_at(static_cast<Domain *>(storage), this);
}
public:
static void DestroyDomainServiceObject(DomainServiceObject *obj) {

View file

@ -732,12 +732,12 @@ namespace ams::sf::impl {
template<size_t Index, typename Interface>
SharedPointer<Interface> *GetOutObjectSharedPointer() {
static_assert(sizeof(SharedPointer<Interface>) == sizeof(SharedPointer<sf::IServiceObject>));
return static_cast<SharedPointer<Interface> *>(static_cast<void *>(&out_shared_pointers[Index]));
return static_cast<SharedPointer<Interface> *>(static_cast<void *>(GetPointer(out_shared_pointers[Index])));
}
template<size_t Index, typename Interface>
Out<SharedPointer<Interface>> GetOutObject() {
auto sp = new (GetOutObjectSharedPointer<Index, Interface>()) SharedPointer<Interface>;
auto sp = std::construct_at(GetOutObjectSharedPointer<Index, Interface>());
return Out<SharedPointer<Interface>>(sp, &this->out_object_ids[Index]);
}

View file

@ -113,7 +113,7 @@ namespace ams::sf {
void DisposeImpl() {
Allocator *a = this->GetAllocator();
this->~Object();
std::destroy_at(this);
operator delete(this, a);
}
public:

View file

@ -36,7 +36,7 @@ namespace ams::ddsf {
R_UNLESS(holder_storage != nullptr, ddsf::ResultOutOfResource());
/* Initialize the new holder. */
auto *holder = new (static_cast<DeviceCodeEntryHolder *>(holder_storage)) DeviceCodeEntryHolder;
auto *holder = std::construct_at(static_cast<DeviceCodeEntryHolder *>(holder_storage));
holder->Construct(device_code, device);
/* Link the new holder. */
@ -60,7 +60,7 @@ namespace ams::ddsf {
if (cur->Get().GetDeviceCode() == device_code) {
/* Destroy and deallocate the holder. */
cur->Destroy();
cur->~DeviceCodeEntryHolder();
std::destroy_at(cur);
this->memory_resource->Deallocate(cur, sizeof(*cur));
erased = true;

View file

@ -88,8 +88,8 @@ namespace ams::fssystem {
if (this->external_attr_info_buffer == nullptr) {
new_info = new AttrInfo(attr.GetLevel(), 1, size);
} else if (0 <= attr.GetLevel() && attr.GetLevel() < this->external_attr_info_count) {
const auto buffer = this->external_attr_info_buffer + attr.GetLevel() * sizeof(AttrInfo);
new_info = new (buffer) AttrInfo(attr.GetLevel(), 1, size);
void *buffer = this->external_attr_info_buffer + attr.GetLevel() * sizeof(AttrInfo);
new_info = std::construct_at(reinterpret_cast<AttrInfo *>(buffer), attr.GetLevel(), 1, size);
}
/* If we failed to make a new attr info, we can't register. */

View file

@ -102,8 +102,8 @@ namespace ams::fssystem {
InitializeExpHeap();
/* Initialize buffer allocator. */
new (GetPointer(g_buffer_allocator)) mem::StandardAllocator(g_buffer_pool, BufferPoolSize);
new (GetPointer(g_allocator)) fssrv::MemoryResourceFromStandardAllocator(GetPointer(g_buffer_allocator));
util::ConstructAt(g_buffer_allocator, g_buffer_pool, BufferPoolSize);
util::ConstructAt(g_allocator, GetPointer(g_buffer_allocator));
/* Set allocators. */
fs::SetAllocator(AllocateForFileSystemProxy, DeallocateForFileSystemProxy);
@ -111,7 +111,7 @@ namespace ams::fssystem {
/* Initialize the buffer manager. */
/* TODO FS-REIMPL: os::AllocateMemoryBlock(...); */
new (GetPointer(g_buffer_manager)) fssystem::FileSystemBufferManager;
util::ConstructAt(g_buffer_manager);
GetReference(g_buffer_manager).Initialize(MaxCacheCount, reinterpret_cast<uintptr_t>(g_buffer_manager_heap), BufferManagerHeapSize, BlockSize);
/* TODO FS-REIMPL: Memory Report Creators, fssrv::SetMemoryReportCreator */
@ -119,9 +119,9 @@ namespace ams::fssystem {
/* TODO FS-REIMPL: Create Pooled Threads, fssystem::RegisterThreadPool. */
/* Initialize fs creators. */
new (GetPointer(g_rom_fs_creator)) fssrv::fscreator::RomFileSystemCreator(GetPointer(g_allocator));
new (GetPointer(g_partition_fs_creator)) fssrv::fscreator::PartitionFileSystemCreator;
new (GetPointer(g_storage_on_nca_creator)) fssrv::fscreator::StorageOnNcaCreator(GetPointer(g_allocator), *GetNcaCryptoConfiguration(is_prod), is_prod, GetPointer(g_buffer_manager));
util::ConstructAt(g_rom_fs_creator, GetPointer(g_allocator));
util::ConstructAt(g_partition_fs_creator);
util::ConstructAt(g_storage_on_nca_creator, GetPointer(g_allocator), *GetNcaCryptoConfiguration(is_prod), is_prod, GetPointer(g_buffer_manager));
/* TODO FS-REIMPL: Initialize other creators. */

View file

@ -38,7 +38,7 @@ namespace ams::gpio::driver::board::nintendo::nx {
AMS_ABORT_UNLESS(driver_storage != nullptr);
/* Construct the new driver. */
g_driver_impl = new (driver_storage) ams::gpio::driver::board::nintendo::nx::impl::DriverImpl(impl::GpioRegistersPhysicalAddress, impl::GpioRegistersSize);
g_driver_impl = std::construct_at(driver_storage, impl::GpioRegistersPhysicalAddress, impl::GpioRegistersSize);
/* Register the driver. */
gpio::driver::RegisterDriver(g_driver_impl);
@ -47,11 +47,11 @@ namespace ams::gpio::driver::board::nintendo::nx {
if (enable_interrupt_handlers) {
for (size_t i = 0; i < util::size(impl::InterruptNameTable); ++i) {
/* Allocate a handler. */
impl::InterruptEventHandler *handler_storage = static_cast<impl::InterruptEventHandler *>(memory_resource->Allocate(sizeof(impl::InterruptEventHandler)));
void *handler_storage = memory_resource->Allocate(sizeof(impl::InterruptEventHandler));
AMS_ABORT_UNLESS(handler_storage != nullptr);
/* Initialize the handler. */
impl::InterruptEventHandler *handler = new (handler_storage) impl::InterruptEventHandler;
auto *handler = std::construct_at(static_cast<impl::InterruptEventHandler *>(handler_storage));
handler->Initialize(g_driver_impl, impl::InterruptNameTable[i], static_cast<int>(i));
/* Register the handler. */
@ -62,11 +62,11 @@ namespace ams::gpio::driver::board::nintendo::nx {
/* Create and register all pads. */
for (const auto &entry : impl::PadMapCombinationList) {
/* Allocate a pad for our device. */
impl::TegraPad *pad_storage = static_cast<impl::TegraPad *>(memory_resource->Allocate(sizeof(impl::TegraPad)));
void *pad_storage = memory_resource->Allocate(sizeof(impl::TegraPad));
AMS_ABORT_UNLESS(pad_storage != nullptr);
/* Create a pad for our device. */
impl::TegraPad *pad = new (pad_storage) impl::TegraPad;
auto *pad = std::construct_at(static_cast<impl::TegraPad *>(pad_storage));
pad->SetParameters(entry.internal_number, impl::PadInfo{entry.wake_event});
/* Register the pad with our driver. */

View file

@ -23,8 +23,8 @@ namespace ams::gpio::driver {
Result OpenSessionImpl(GpioPadSession *out, Pad *pad, ddsf::AccessMode access_mode) {
/* Construct the session. */
auto *session = new (std::addressof(impl::GetPadSessionImpl(*out))) impl::PadSessionImpl;
auto session_guard = SCOPE_GUARD { session->~PadSessionImpl(); };
auto *session = std::construct_at(std::addressof(impl::GetPadSessionImpl(*out)));
auto session_guard = SCOPE_GUARD { std::destroy_at(session); };
/* Open the session. */
R_TRY(session->Open(pad, access_mode));
@ -59,7 +59,7 @@ namespace ams::gpio::driver {
void CloseSession(GpioPadSession *session) {
AMS_ASSERT(session != nullptr);
impl::GetOpenPadSessionImpl(*session).~PadSessionImpl();
std::destroy_at(std::addressof(impl::GetOpenPadSessionImpl(*session)));
}
Result SetDirection(GpioPadSession *session, gpio::Direction direction) {

View file

@ -38,7 +38,7 @@ namespace ams::i2c::driver::board::nintendo::nx::impl {
T *obj = std::addressof(*it);
it = this->list.erase(it);
obj->~T();
std::destroy_at(obj);
this->memory_resource->Deallocate(obj, sizeof(T));
}
}
@ -52,7 +52,7 @@ namespace ams::i2c::driver::board::nintendo::nx::impl {
AMS_ABORT_UNLESS(storage != nullptr);
/* Construct the object. */
T *t = new (static_cast<T *>(storage)) T(std::forward<Args>(args)...);
T *t = std::construct_at(static_cast<T *>(storage), std::forward<Args>(args)...);
/* Link the object into our list. */
this->list.push_back(*t);

View file

@ -26,8 +26,8 @@ namespace ams::i2c::driver {
Result OpenSessionImpl(I2cSession *out, I2cDeviceProperty *device) {
/* Construct the session. */
auto *session = new (std::addressof(impl::GetI2cSessionImpl(*out))) impl::I2cSessionImpl(DefaultRetryCount, DefaultRetryInterval);
auto session_guard = SCOPE_GUARD { session->~I2cSessionImpl(); };
auto *session = std::construct_at(std::addressof(impl::GetI2cSessionImpl(*out)), DefaultRetryCount, DefaultRetryInterval);
auto session_guard = SCOPE_GUARD { std::destroy_at(session); };
/* Open the session. */
R_TRY(session->Open(device, ddsf::AccessMode_ReadWrite));
@ -54,7 +54,7 @@ namespace ams::i2c::driver {
}
void CloseSession(I2cSession &session) {
impl::GetOpenI2cSessionImpl(session).~I2cSessionImpl();
std::destroy_at(std::addressof(impl::GetOpenI2cSessionImpl(session)));
}
Result Send(I2cSession &session, const void *src, size_t src_size, TransactionOption option) {

View file

@ -30,8 +30,8 @@ namespace ams::lmem::impl {
void InitializeHeapHead(HeapHead *out, u32 magic, void *start, void *end, u32 option) {
/* Call member constructors. */
new (&out->list_node) util::IntrusiveListNode;
new (&out->child_list) decltype(out->child_list);
std::construct_at(std::addressof(out->list_node));
std::construct_at(std::addressof(out->child_list));
/* Set fields. */
out->magic = magic;

View file

@ -147,11 +147,10 @@ namespace ams::lmem::impl {
}
inline ExpHeapMemoryBlockHead *InitializeMemoryBlock(const MemoryRegion &region, u16 magic) {
ExpHeapMemoryBlockHead *block = reinterpret_cast<ExpHeapMemoryBlockHead *>(region.start);
/* Ensure all member constructors are called. */
new (block) ExpHeapMemoryBlockHead;
/* Construct the block. */
ExpHeapMemoryBlockHead *block = std::construct_at(reinterpret_cast<ExpHeapMemoryBlockHead *>(region.start));
/* Initialize all members. */
block->magic = magic;
block->attributes = 0;
block->block_size = GetPointerDifference(GetMemoryBlockStart(block), region.end);
@ -175,8 +174,8 @@ namespace ams::lmem::impl {
InitializeHeapHead(heap_head, ExpHeapMagic, GetExpHeapMemoryStart(exp_heap_head), end, option);
/* Call exp heap member constructors. */
new (&exp_heap_head->free_list) ExpHeapMemoryBlockList;
new (&exp_heap_head->used_list) ExpHeapMemoryBlockList;
std::construct_at(std::addressof(exp_heap_head->free_list));
std::construct_at(std::addressof(exp_heap_head->used_list));
/* Set exp heap fields. */
exp_heap_head->group_id = DefaultGroupId;

View file

@ -42,9 +42,9 @@ namespace ams::mem::impl::heap {
this->start = aligned_start;
this->end = aligned_end;
this->option = option;
this->tls_heap_central = new (this->start) TlsHeapCentral;
this->tls_heap_central = std::construct_at(reinterpret_cast<TlsHeapCentral *>(this->start));
if (auto err = this->tls_heap_central->Initialize(this->start, this->end - this->start, false); err != 0) {
this->tls_heap_central->~TlsHeapCentral();
std::destroy_at(this->tls_heap_central);
this->tls_heap_central = nullptr;
AMS_ASSERT(err == 0);
return err;
@ -70,9 +70,9 @@ namespace ams::mem::impl::heap {
if (auto err = AllocatePhysicalMemory(central, sizeof(TlsHeapCentral)); err != 0) {
return err;
}
this->tls_heap_central = new (central) TlsHeapCentral;
this->tls_heap_central = std::construct_at(static_cast<TlsHeapCentral *>(central));
if (auto err = this->tls_heap_central->Initialize(central, size, true); err != 0) {
this->tls_heap_central->~TlsHeapCentral();
std::destroy_at(this->tls_heap_central);
this->tls_heap_central = nullptr;
AMS_ASSERT(err == 0);
return err;
@ -85,7 +85,7 @@ namespace ams::mem::impl::heap {
void CentralHeap::Finalize() {
if (this->tls_heap_central) {
this->tls_heap_central->~TlsHeapCentral();
std::destroy_at(this->tls_heap_central);
}
if (this->use_virtual_memory) {
mem::impl::physical_free(util::AlignUp(static_cast<void *>(this->start), PageSize), this->end - this->start);
@ -249,7 +249,7 @@ namespace ams::mem::impl::heap {
return false;
}
new (tls_heap_cache) TlsHeapCache(this->tls_heap_central, this->option);
std::construct_at(static_cast<TlsHeapCache *>(tls_heap_cache), this->tls_heap_central, this->option);
if (this->tls_heap_central->AddThreadCache(reinterpret_cast<TlsHeapCache *>(tls_heap_cache)) != 0) {
this->tls_heap_central->UncacheSmallMemory(tls_heap_cache);
return false;

View file

@ -68,7 +68,7 @@ namespace ams::mem {
StandardAllocator::StandardAllocator() : initialized(false), enable_thread_cache(false), unused(0) {
static_assert(sizeof(impl::heap::CentralHeap) <= sizeof(this->central_heap_storage));
new (std::addressof(this->central_heap_storage)) impl::heap::CentralHeap;
std::construct_at(GetCentral(this->central_heap_storage));
}
StandardAllocator::StandardAllocator(void *mem, size_t size) : StandardAllocator() {

View file

@ -33,7 +33,7 @@ namespace ams::os::impl {
event->auto_clear = (clear_mode == EventClearMode_AutoClear);
/* Create the waitlist node. */
new (GetPointer(event->waitable_object_list_storage)) impl::WaitableObjectList;
util::ConstructAt(event->waitable_object_list_storage);
/* Set state. */
event->state = InterProcessEventType::State_Initialized;
@ -71,7 +71,7 @@ namespace ams::os::impl {
}
/* Destroy the waitlist. */
GetReference(event->waitable_object_list_storage).~WaitableObjectList();
util::DestroyAt(event->waitable_object_list_storage);
}
void AttachInterProcessEvent(InterProcessEventType *event, Handle read_handle, bool read_handle_managed, Handle write_handle, bool write_handle_managed, EventClearMode clear_mode) {

View file

@ -48,7 +48,7 @@ namespace ams::os::impl {
public:
static ALWAYS_INLINE void InitializeResourceManagerInstance() {
/* Construct the resource manager instance. */
new (GetPointer(s_resource_manager_storage)) OsResourceManager;
util::ConstructAt(s_resource_manager_storage);
}
static ALWAYS_INLINE OsResourceManager &GetResourceManagerInstance() {

View file

@ -24,11 +24,11 @@ namespace ams::os::impl {
void SetupThreadObjectUnsafe(ThreadType *thread, ThreadImpl *thread_impl, ThreadFunction function, void *arg, void *stack, size_t stack_size, s32 priority) {
/* Setup objects. */
new (GetPointer(thread->cs_thread)) impl::InternalCriticalSection;
new (GetPointer(thread->cv_thread)) impl::InternalConditionVariable;
util::ConstructAt(thread->cs_thread);
util::ConstructAt(thread->cv_thread);
new (GetPointer(thread->all_threads_node)) util::IntrusiveListNode;
new (GetPointer(thread->waitlist)) WaitableObjectList;
util::ConstructAt(thread->all_threads_node);
util::ConstructAt(thread->waitlist);
/* Set member variables. */
thread->thread_impl = (thread_impl != nullptr) ? thread_impl : std::addressof(thread->thread_impl_storage);
@ -131,7 +131,7 @@ namespace ams::os::impl {
thread->state = ThreadType::State_NotInitialized;
GetReference(thread->waitlist).~WaitableObjectList();
util::DestroyAt(thread->waitlist);
thread->name_buffer[0] = '\x00';

View file

@ -22,7 +22,7 @@ namespace ams::os {
void InitializeConditionVariable(ConditionVariableType *cv) {
/* Construct object. */
new (GetPointer(cv->_storage)) impl::InternalConditionVariable;
util::ConstructAt(cv->_storage);
/* Mark initialized. */
cv->state = ConditionVariableType::State_Initialized;
@ -35,7 +35,7 @@ namespace ams::os {
cv->state = ConditionVariableType::State_NotInitialized;
/* Destroy objects. */
GetReference(cv->_storage).~InternalConditionVariable();
util::DestroyAt(cv->_storage);
}
void SignalConditionVariable(ConditionVariableType *cv) {

View file

@ -37,11 +37,11 @@ namespace ams::os {
void InitializeEvent(EventType *event, bool signaled, EventClearMode clear_mode) {
/* Initialize internal variables. */
new (GetPointer(event->cs_event)) impl::InternalCriticalSection;
new (GetPointer(event->cv_signaled)) impl::InternalConditionVariable;
util::ConstructAt(event->cs_event);
util::ConstructAt(event->cv_signaled);
/* Initialize the waitable object list. */
new (GetPointer(event->waitable_object_list_storage)) impl::WaitableObjectList();
util::ConstructAt(event->waitable_object_list_storage);
/* Initialize member variables. */
event->signaled = signaled;
@ -61,9 +61,9 @@ namespace ams::os {
event->state = EventType::State_NotInitialized;
/* Destroy objects. */
GetReference(event->waitable_object_list_storage).~WaitableObjectList();
GetReference(event->cv_signaled).~InternalConditionVariable();
GetReference(event->cs_event).~InternalCriticalSection();
util::DestroyAt(event->waitable_object_list_storage);
util::DestroyAt(event->cv_signaled);
util::DestroyAt(event->cs_event);
}
void SignalEvent(EventType *event) {
@ -163,7 +163,7 @@ namespace ams::os {
void InitializeWaitableHolder(WaitableHolderType *waitable_holder, EventType *event) {
AMS_ASSERT(event->state == EventType::State_Initialized);
new (GetPointer(waitable_holder->impl_storage)) impl::WaitableHolderOfEvent(event);
util::ConstructAt(GetReference(waitable_holder->impl_storage).holder_of_event_storage, event);
waitable_holder->user_data = 0;
}

View file

@ -25,7 +25,7 @@ namespace ams::os {
event->clear_mode = static_cast<u8>(clear_mode);
/* Initialize implementation. */
new (GetPointer(event->impl)) impl::InterruptEventImpl(name, clear_mode);
util::ConstructAt(event->impl, name, clear_mode);
/* Mark initialized. */
event->state = InterruptEventType::State_Initialized;
@ -38,7 +38,7 @@ namespace ams::os {
event->state = InterruptEventType::State_NotInitialized;
/* Destroy objects. */
GetReference(event->impl).~InterruptEventImpl();
util::DestroyAt(event->impl);
}
void WaitInterruptEvent(InterruptEventType *event) {
@ -65,7 +65,7 @@ namespace ams::os {
void InitializeWaitableHolder(WaitableHolderType *waitable_holder, InterruptEventType *event) {
AMS_ASSERT(event->state == InterruptEventType::State_Initialized);
new (GetPointer(waitable_holder->impl_storage)) impl::WaitableHolderOfInterruptEvent(event);
util::ConstructAt(GetReference(waitable_holder->impl_storage).holder_of_interrupt_event_storage, event);
waitable_holder->user_data = 0;
}

View file

@ -112,13 +112,13 @@ namespace ams::os {
AMS_ASSERT(count >= 1);
/* Setup objects. */
new (GetPointer(mq->cs_queue)) impl::InternalCriticalSection;
new (GetPointer(mq->cv_not_full)) impl::InternalConditionVariable;
new (GetPointer(mq->cv_not_empty)) impl::InternalConditionVariable;
util::ConstructAt(mq->cs_queue);
util::ConstructAt(mq->cv_not_full);
util::ConstructAt(mq->cv_not_empty);
/* Setup wait lists. */
new (GetPointer(mq->waitlist_not_empty)) impl::WaitableObjectList;
new (GetPointer(mq->waitlist_not_full)) impl::WaitableObjectList;
util::ConstructAt(mq->waitlist_not_empty);
util::ConstructAt(mq->waitlist_not_full);
/* Set member variables. */
mq->buffer = buffer;
@ -140,13 +140,13 @@ namespace ams::os {
mq->state = MessageQueueType::State_NotInitialized;
/* Destroy wait lists. */
GetReference(mq->waitlist_not_empty).~WaitableObjectList();
GetReference(mq->waitlist_not_full).~WaitableObjectList();
util::DestroyAt(mq->waitlist_not_empty);
util::DestroyAt(mq->waitlist_not_full);
/* Destroy objects. */
GetReference(mq->cv_not_empty).~InternalConditionVariable();
GetReference(mq->cv_not_full).~InternalConditionVariable();
GetReference(mq->cs_queue).~InternalCriticalSection();
util::DestroyAt(mq->cv_not_empty);
util::DestroyAt(mq->cv_not_full);
util::DestroyAt(mq->cs_queue);
}
/* Sending (FIFO functionality) */

View file

@ -72,7 +72,7 @@ namespace ams::os {
AMS_ASSERT((lock_level == 0) || (MutexLockLevelMin <= lock_level && lock_level <= MutexLockLevelMax));
/* Create object. */
new (GetPointer(mutex->_storage)) impl::InternalCriticalSection;
util::ConstructAt(mutex->_storage);
/* Set member variables. */
mutex->is_recursive = recursive;
@ -91,7 +91,7 @@ namespace ams::os {
mutex->state = MutexType::State_NotInitialized;
/* Destroy object. */
GetReference(mutex->_storage).~InternalCriticalSection();
util::DestroyAt(mutex->_storage);
}
void LockMutex(MutexType *mutex) {

View file

@ -21,9 +21,9 @@ namespace ams::os {
void InitalizeReadWriteLock(ReadWriteLockType *rw_lock) {
/* Create objects. */
new (GetPointer(impl::GetLockCount(rw_lock).cs_storage)) impl::InternalCriticalSection;
new (GetPointer(rw_lock->cv_read_lock._storage)) impl::InternalConditionVariable;
new (GetPointer(rw_lock->cv_write_lock._storage)) impl::InternalConditionVariable;
util::ConstructAt(impl::GetLockCount(rw_lock).cs_storage);
util::ConstructAt(rw_lock->cv_read_lock._storage);
util::ConstructAt(rw_lock->cv_write_lock._storage);
/* Set member variables. */
impl::ClearReadLockCount(impl::GetLockCount(rw_lock));
@ -48,9 +48,9 @@ namespace ams::os {
rw_lock->state = ReadWriteLockType::State_NotInitialized;
/* Destroy objects. */
GetReference(rw_lock->cv_write_lock._storage).~InternalConditionVariable();
GetReference(rw_lock->cv_read_lock._storage).~InternalConditionVariable();
GetReference(impl::GetLockCount(rw_lock).cs_storage).~InternalCriticalSection();
util::DestroyAt(rw_lock->cv_write_lock._storage);
util::DestroyAt(rw_lock->cv_read_lock._storage);
util::DestroyAt(impl::GetLockCount(rw_lock).cs_storage);
}
void AcquireReadLock(ReadWriteLockType *rw_lock) {

View file

@ -24,11 +24,11 @@ namespace ams::os {
AMS_ASSERT(count >= 0);
/* Setup objects. */
new (GetPointer(sema->cs_sema)) impl::InternalCriticalSection;
new (GetPointer(sema->cv_not_zero)) impl::InternalConditionVariable;
util::ConstructAt(sema->cs_sema);
util::ConstructAt(sema->cv_not_zero);
/* Setup wait lists. */
new (GetPointer(sema->waitlist)) impl::WaitableObjectList;
util::ConstructAt(sema->waitlist);
/* Set member variables. */
sema->count = count;
@ -47,11 +47,11 @@ namespace ams::os {
sema->state = SemaphoreType::State_NotInitialized;
/* Destroy wait lists. */
GetReference(sema->waitlist).~WaitableObjectList();
util::DestroyAt(sema->waitlist);
/* Destroy objects. */
GetReference(sema->cv_not_zero).~InternalConditionVariable();
GetReference(sema->cs_sema).~InternalCriticalSection();
util::DestroyAt(sema->cv_not_zero);
util::DestroyAt(sema->cs_sema);
}
void AcquireSemaphore(SemaphoreType *sema) {

View file

@ -122,10 +122,10 @@ namespace ams::os {
void InitializeWaitableHolder(WaitableHolderType *waitable_holder, SystemEventType *event) {
switch (event->state) {
case SystemEventType::State_InitializedAsInterProcessEvent:
new (GetPointer(waitable_holder->impl_storage)) impl::WaitableHolderOfInterProcessEvent(std::addressof(event->inter_process_event));
util::ConstructAt(GetReference(waitable_holder->impl_storage).holder_of_inter_process_event_storage, std::addressof(event->inter_process_event));
break;
case SystemEventType::State_InitializedAsEvent:
new (GetPointer(waitable_holder->impl_storage)) impl::WaitableHolderOfEvent(std::addressof(event->event));
util::ConstructAt(GetReference(waitable_holder->impl_storage).holder_of_event_storage, std::addressof(event->event));
break;
AMS_UNREACHABLE_DEFAULT_CASE();
}

View file

@ -56,11 +56,11 @@ namespace ams::os {
void InitializeTimerEvent(TimerEventType *event, EventClearMode clear_mode) {
/* Initialize internal variables. */
new (GetPointer(event->cs_timer_event)) impl::InternalCriticalSection;
new (GetPointer(event->cv_signaled)) impl::InternalConditionVariable;
util::ConstructAt(event->cs_timer_event);
util::ConstructAt(event->cv_signaled);
/* Initialize the waitable object list. */
new (GetPointer(event->waitable_object_list_storage)) impl::WaitableObjectList();
util::ConstructAt(event->waitable_object_list_storage);
/* Initialize member variables. */
event->clear_mode = static_cast<u8>(clear_mode);
@ -83,9 +83,9 @@ namespace ams::os {
event->state = TimerEventType::State_NotInitialized;
/* Destroy objects. */
GetReference(event->waitable_object_list_storage).~WaitableObjectList();
GetReference(event->cv_signaled).~InternalConditionVariable();
GetReference(event->cs_timer_event).~InternalCriticalSection();
util::DestroyAt(event->waitable_object_list_storage);
util::DestroyAt(event->cv_signaled);
util::DestroyAt(event->cs_timer_event);
}
void StartOneShotTimerEvent(TimerEventType *event, TimeSpan first_time) {
@ -255,7 +255,7 @@ namespace ams::os {
void InitializeWaitableHolder(WaitableHolderType *waitable_holder, TimerEventType *event) {
AMS_ASSERT(event->state == EventType::State_Initialized);
new (GetPointer(waitable_holder->impl_storage)) impl::WaitableHolderOfTimerEvent(event);
util::ConstructAt(GetReference(waitable_holder->impl_storage).holder_of_timer_event_storage, event);
waitable_holder->user_data = 0;
}

View file

@ -46,7 +46,7 @@ namespace ams::os {
tmem->handle_managed = managed;
/* Create the critical section. */
new (GetPointer(tmem->cs_transfer_memory)) impl::InternalCriticalSection;
util::ConstructAt(tmem->cs_transfer_memory);
}
}
@ -118,7 +118,7 @@ namespace ams::os {
tmem->handle = svc::InvalidHandle;
/* Destroy the critical section. */
GetReference(tmem->cs_transfer_memory).~InternalCriticalSection();
util::DestroyAt(tmem->cs_transfer_memory);
}
Result MapTransferMemory(void **out, TransferMemoryType *tmem, MemoryPermission owner_perm) {

View file

@ -34,7 +34,7 @@ namespace ams::os {
void InitializeWaitableManager(WaitableManagerType *manager) {
/* Initialize storage. */
new (std::addressof(GetWaitableManagerImpl(manager))) impl::WaitableManagerImpl;
util::ConstructAt(manager->impl_storage);
/* Mark initialized. */
manager->state = WaitableManagerType::State_Initialized;
@ -50,7 +50,7 @@ namespace ams::os {
manager->state = WaitableManagerType::State_NotInitialized;
/* Destroy. */
impl.~WaitableManagerImpl();
util::DestroyAt(manager->impl_storage);
}
WaitableHolderType *WaitAny(WaitableManagerType *manager) {
@ -90,7 +90,7 @@ namespace ams::os {
AMS_ASSERT(!holder_base->IsLinkedToManager());
holder_base->~WaitableHolderBase();
std::destroy_at(holder_base);
}
void LinkWaitableHolder(WaitableManagerType *manager, WaitableHolderType *holder) {
@ -143,7 +143,7 @@ namespace ams::os {
void InitializeWaitableHolder(WaitableHolderType *holder, Handle handle) {
AMS_ASSERT(handle != svc::InvalidHandle);
new (GetPointer(holder->impl_storage)) impl::WaitableHolderOfHandle(handle);
util::ConstructAt(GetReference(holder->impl_storage).holder_of_handle_storage, handle);
holder->user_data = 0;
}

View file

@ -22,13 +22,12 @@ namespace ams::pgl::srv {
ShellEventObserver::ShellEventObserver() : message_queue(queue_buffer, QueueCapacity), event(os::EventClearMode_AutoClear, true) {
this->heap_handle = lmem::CreateUnitHeap(this->event_info_data, sizeof(this->event_info_data), sizeof(this->event_info_data[0]), lmem::CreateOption_ThreadSafe, 8, GetPointer(this->heap_head));
new (GetPointer(this->holder)) ShellEventObserverHolder(this);
RegisterShellEventObserver(GetPointer(this->holder));
RegisterShellEventObserver(util::ConstructAt(this->holder, this));
}
ShellEventObserver::~ShellEventObserver() {
UnregisterShellEventObserver(GetPointer(this->holder));
GetReference(this->holder).~ShellEventObserverHolder();
util::DestroyAt(this->holder);
}
Result ShellEventObserver::PopEventInfo(pm::ProcessEventInfo *out) {

View file

@ -38,7 +38,7 @@ namespace ams::powctl {
}
void DestroySession(Session &session) {
GetSessionImpl(session).~SessionImpl();
std::destroy_at(std::addressof(GetSessionImpl(session)));
session.has_session = false;
}
@ -69,11 +69,11 @@ namespace ams::powctl {
DestroySessionIfNecessary(*out);
/* Construct the session. */
new (std::addressof(GetSessionImpl(*out))) impl::SessionImpl;
auto *session = std::construct_at(std::addressof(GetSessionImpl(*out)));
auto guard = SCOPE_GUARD { DestroySessionIfNecessary(*out); };
/* Try to open the session. */
R_TRY(ddsf::OpenSession(device, std::addressof(GetSessionImpl(*out)), access_mode));
R_TRY(ddsf::OpenSession(device, session, access_mode));
/* We opened the session! */
guard.Cancel();

View file

@ -40,7 +40,7 @@ namespace ams::pwm::driver::board::nintendo::nx::impl {
AMS_ABORT_UNLESS(driver_storage != nullptr);
/* Create our driver. */
auto *driver = new (static_cast<PwmDriverImpl *>(driver_storage)) PwmDriverImpl(PwmRegistersPhysicalAddress, PwmRegistersSize, SupportedChannels, util::size(SupportedChannels));
auto *driver = std::construct_at(static_cast<PwmDriverImpl *>(driver_storage), PwmRegistersPhysicalAddress, PwmRegistersSize, SupportedChannels, util::size(SupportedChannels));
/* Register our driver. */
pwm::driver::RegisterDriver(driver);
@ -51,7 +51,7 @@ namespace ams::pwm::driver::board::nintendo::nx::impl {
AMS_ABORT_UNLESS(device_storage != nullptr);
/* Create our driver. */
auto *device = new (static_cast<PwmDeviceImpl *>(device_storage)) PwmDeviceImpl(entry.channel_id);
auto *device = std::construct_at(static_cast<PwmDeviceImpl *>(device_storage), entry.channel_id);
/* Register the device with our driver. */
driver->RegisterDevice(device);

View file

@ -24,8 +24,8 @@ namespace ams::pwm::driver {
Result OpenSessionImpl(ChannelSession *out, IPwmDevice *device) {
/* Construct the session. */
auto *session = new (std::addressof(impl::GetChannelSessionImpl(*out))) impl::ChannelSessionImpl;
auto session_guard = SCOPE_GUARD { session->~ChannelSessionImpl(); };
auto *session = std::construct_at(std::addressof(impl::GetChannelSessionImpl(*out)));
auto session_guard = SCOPE_GUARD { std::destroy_at(session); };
/* Open the session. */
R_TRY(session->Open(device, ddsf::AccessMode_ReadWrite));
@ -52,7 +52,7 @@ namespace ams::pwm::driver {
}
void CloseSession(ChannelSession &session) {
impl::GetOpenChannelSessionImpl(session).~ChannelSessionImpl();
std::destroy_at(std::addressof(impl::GetOpenChannelSessionImpl(session)));
}
void SetPeriod(ChannelSession &session, TimeSpan period) {

View file

@ -33,7 +33,7 @@ namespace ams::sf::cmif {
void ServerDomainManager::Domain::DisposeImpl() {
ServerDomainManager *manager = this->manager;
this->~Domain();
std::destroy_at(this);
manager->FreeDomain(this);
}
@ -110,14 +110,13 @@ namespace ams::sf::cmif {
this->entries = reinterpret_cast<Entry *>(entry_storage);
this->num_entries = entry_count;
for (size_t i = 0; i < this->num_entries; i++) {
Entry *entry = new (this->entries + i) Entry();
this->free_list.push_back(*entry);
this->free_list.push_back(*std::construct_at(this->entries + i));
}
}
ServerDomainManager::EntryManager::~EntryManager() {
for (size_t i = 0; i < this->num_entries; i++) {
this->entries[i].~Entry();
std::destroy_at(this->entries + i);
}
}

View file

@ -58,12 +58,12 @@ namespace ams::sf::hipc::impl {
std::scoped_lock lk(g_query_server_lock);
if (AMS_UNLIKELY(!g_constructed_server)) {
new (GetPointer(g_query_server_storage)) sf::hipc::ServerManager<MaxServers>();
util::ConstructAt(g_query_server_storage);
g_constructed_server = true;
}
/* TODO: Better object factory? */
R_ABORT_UNLESS(GetPointer(g_query_server_storage)->RegisterSession(query_handle, cmif::ServiceObjectHolder(sf::CreateSharedObjectEmplaced<IMitmQueryService, MitmQueryService>(query_func))));
R_ABORT_UNLESS(GetReference(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

@ -70,7 +70,8 @@ namespace ams::sf::hipc {
void ServerSessionManager::DestroySession(ServerSession *session) {
/* Destroy object. */
session->~ServerSession();
std::destroy_at(session);
/* Free object memory. */
this->FreeSession(session);
}
@ -84,10 +85,12 @@ namespace ams::sf::hipc {
Result ServerSessionManager::RegisterSessionImpl(ServerSession *session_memory, Handle session_handle, cmif::ServiceObjectHolder &&obj) {
/* Create session object. */
new (session_memory) ServerSession(session_handle, std::forward<cmif::ServiceObjectHolder>(obj));
std::construct_at(session_memory, session_handle, std::forward<cmif::ServiceObjectHolder>(obj));
/* Assign session resources. */
session_memory->pointer_buffer = this->GetSessionPointerBuffer(session_memory);
session_memory->saved_message = this->GetSessionSavedMessageBuffer(session_memory);
/* Register to wait list. */
this->RegisterSessionToWaitList(session_memory);
return ResultSuccess();
@ -97,27 +100,28 @@ namespace ams::sf::hipc {
/* Create session handle. */
Handle session_handle;
R_TRY(svcAcceptSession(&session_handle, port_handle));
bool succeeded = false;
ON_SCOPE_EXIT {
if (!succeeded) {
R_ABORT_UNLESS(svcCloseHandle(session_handle));
}
};
auto session_guard = SCOPE_GUARD { R_ABORT_UNLESS(svc::CloseHandle(session_handle)); };
/* Register session. */
R_TRY(this->RegisterSessionImpl(session_memory, session_handle, std::forward<cmif::ServiceObjectHolder>(obj)));
succeeded = true;
session_guard.Cancel();
return ResultSuccess();
}
Result ServerSessionManager::RegisterMitmSessionImpl(ServerSession *session_memory, Handle mitm_session_handle, cmif::ServiceObjectHolder &&obj, std::shared_ptr<::Service> &&fsrv) {
/* Create session object. */
new (session_memory) ServerSession(mitm_session_handle, std::forward<cmif::ServiceObjectHolder>(obj), std::forward<std::shared_ptr<::Service>>(fsrv));
std::construct_at(session_memory, mitm_session_handle, std::forward<cmif::ServiceObjectHolder>(obj), std::forward<std::shared_ptr<::Service>>(fsrv));
/* Assign session resources. */
session_memory->pointer_buffer = this->GetSessionPointerBuffer(session_memory);
session_memory->saved_message = this->GetSessionSavedMessageBuffer(session_memory);
/* Validate session pointer buffer. */
AMS_ABORT_UNLESS(session_memory->pointer_buffer.GetSize() >= session_memory->forward_service->pointer_buffer_size);
session_memory->pointer_buffer = cmif::PointerAndSize(session_memory->pointer_buffer.GetAddress(), session_memory->forward_service->pointer_buffer_size);
/* Register to wait list. */
this->RegisterSessionToWaitList(session_memory);
return ResultSuccess();
@ -127,15 +131,13 @@ namespace ams::sf::hipc {
/* Create session handle. */
Handle mitm_session_handle;
R_TRY(svcAcceptSession(&mitm_session_handle, mitm_port_handle));
bool succeeded = false;
ON_SCOPE_EXIT {
if (!succeeded) {
R_ABORT_UNLESS(svcCloseHandle(mitm_session_handle));
}
};
auto session_guard = SCOPE_GUARD { R_ABORT_UNLESS(svc::CloseHandle(mitm_session_handle)); };
/* Register session. */
R_TRY(this->RegisterMitmSessionImpl(session_memory, mitm_session_handle, std::forward<cmif::ServiceObjectHolder>(obj), std::forward<std::shared_ptr<::Service>>(fsrv)));
succeeded = true;
session_guard.Cancel();
return ResultSuccess();
}

View file

@ -29,7 +29,7 @@ namespace ams::util {
private:
ALWAYS_INLINE void FreeEntry(size_t i) {
this->keys[i].reset();
GetReference(this->values[i]).~Value();
DestroyAt(this->values[i]);
}
public:
constexpr BoundedMap() : keys(), values() { /* ... */ }
@ -78,7 +78,7 @@ namespace ams::util {
for (size_t i = 0; i < N; i++) {
if (!this->keys[i]) {
this->keys[i] = key;
new (GetPointer(this->values[i])) Value(std::move(value));
ConstructAt(this->values[i], std::forward<Value>(value));
return true;
}
}
@ -90,7 +90,7 @@ namespace ams::util {
/* Try to find and assign an existing value. */
for (size_t i = 0; i < N; i++) {
if (this->keys[i] && this->keys[i].value() == key) {
GetReference(this->values[i]) = std::move(value);
GetReference(this->values[i]) = std::forward<Value>(value);
return true;
}
}
@ -99,7 +99,7 @@ namespace ams::util {
for (size_t i = 0; i < N; i++) {
if (!this->keys[i]) {
this->keys[i] = key;
new (GetPointer(this->values[i])) Value(std::move(value));
ConstructAt(this->values[i], std::move(value));
return true;
}
}
@ -118,7 +118,7 @@ namespace ams::util {
for (size_t i = 0; i < N; i++) {
if (!this->keys[i]) {
this->keys[i] = key;
new (GetPointer(this->values[i])) Value(std::forward<Args>(args)...);
ConstructAt(this->values[i], std::forward<Args>(args)...);
return true;
}
}

View file

@ -36,6 +36,8 @@ namespace ams::util {
ALWAYS_INLINE ScopeGuard(ScopeGuard&& rhs) : f(std::move(rhs.f)), active(rhs.active) {
rhs.Cancel();
}
ScopeGuard &operator=(ScopeGuard&& rhs) = delete;
};
template<class F>

View file

@ -45,4 +45,46 @@ namespace ams::util {
return *GetPointer(ts);
}
template<typename T, typename... Args>
static constexpr ALWAYS_INLINE T *ConstructAt(TypedStorage<T> &ts, Args &&... args) {
return std::construct_at(GetPointer(ts), std::forward<Args>(args)...);
}
template<typename T>
static constexpr ALWAYS_INLINE void DestroyAt(TypedStorage<T> &ts) {
return std::destroy_at(GetPointer(ts));
}
namespace impl {
template<typename T>
class TypedStorageGuard {
NON_COPYABLE(TypedStorageGuard);
private:
TypedStorage<T> &m_ts;
bool m_active;
public:
template<typename... Args>
constexpr ALWAYS_INLINE TypedStorageGuard(TypedStorage<T> &ts, Args &&... args) : m_ts(ts), m_active(true) {
ConstructAt(m_ts, std::forward<Args>(args)...);
}
ALWAYS_INLINE ~TypedStorageGuard() { if (m_active) { DestroyAt(m_ts); } }
ALWAYS_INLINE void Cancel() { m_active = false; }
ALWAYS_INLINE TypedStorageGuard(TypedStorageGuard&& rhs) : m_ts(rhs.m_ts), m_active(rhs.m_active) {
rhs.Cancel();
}
TypedStorageGuard &operator=(TypedStorageGuard&& rhs) = delete;
};
}
template<typename T, typename... Args>
static constexpr ALWAYS_INLINE impl::TypedStorageGuard<T> ConstructAtGuarded(TypedStorage<T> &ts, Args &&... args) {
return impl::TypedStorageGuard<T>(ts, std::forward<Args>(args)...);
}
}

View file

@ -1085,7 +1085,7 @@ namespace ams::sdmmc::impl {
/* This initializes a lot of globals in pcv, most of which we don't care about. */
/* However, we do care about the Sdmmc1PowerController. */
AMS_ABORT_UNLESS(this->power_controller == nullptr);
this->power_controller = new (GetPointer(this->power_controller_storage)) PowerController;
this->power_controller = util::ConstructAt(this->power_controller_storage);
/* Perform base initialization. */
SdmmcController::Initialize();
@ -1099,8 +1099,8 @@ namespace ams::sdmmc::impl {
/* As with initialize, we mostly don't care about the globals this touches. */
/* However, we do want to finalize the Sdmmc1PowerController. */
AMS_ABORT_UNLESS(this->power_controller != nullptr);
this->power_controller->~PowerController();
this->power_controller = nullptr;
util::DestroyAt(this->power_controller_storage);
/* pinmux::CloseSession(std::addressof(this->pinmux_session)); */
/* This does nothing. */

View file

@ -85,8 +85,8 @@ namespace ams::creport {
this->heap_handle = lmem::CreateExpHeap(this->heap_storage, sizeof(this->heap_storage), lmem::CreateOption_None);
/* Allocate members. */
this->module_list = new (lmem::AllocateFromExpHeap(this->heap_handle, sizeof(ModuleList))) ModuleList;
this->thread_list = new (lmem::AllocateFromExpHeap(this->heap_handle, sizeof(ThreadList))) ThreadList;
this->module_list = std::construct_at(static_cast<ModuleList *>(lmem::AllocateFromExpHeap(this->heap_handle, sizeof(ModuleList))));
this->thread_list = std::construct_at(static_cast<ThreadList *>(lmem::AllocateFromExpHeap(this->heap_handle, sizeof(ThreadList))));
this->dying_message = static_cast<u8 *>(lmem::AllocateFromExpHeap(this->heap_handle, DyingMessageSizeMax));
if (this->dying_message != nullptr) {
std::memset(this->dying_message, 0, DyingMessageSizeMax);
@ -321,8 +321,8 @@ namespace ams::creport {
}
/* Finalize our heap. */
this->module_list->~ModuleList();
this->thread_list->~ThreadList();
std::destroy_at(this->module_list);
std::destroy_at(this->thread_list);
lmem::FreeToExpHeap(this->heap_handle, this->module_list);
lmem::FreeToExpHeap(this->heap_handle, this->thread_list);
if (this->dying_message != nullptr) {

View file

@ -66,13 +66,13 @@ namespace ams::dmnt::cheat::impl {
FrozenAddressMapEntry *AllocateFrozenAddress(u64 address, FrozenAddressValue value) {
FrozenAddressMapEntry *entry = static_cast<FrozenAddressMapEntry *>(lmem::AllocateFromUnitHeap(g_frozen_address_map_heap));
if (entry != nullptr) {
new (entry) FrozenAddressMapEntry(address, value);
std::construct_at(entry, address, value);
}
return entry;
}
void DeallocateFrozenAddress(FrozenAddressMapEntry *entry) {
entry->~FrozenAddressMapEntry();
std::destroy_at(entry);
lmem::FreeToUnitHeap(g_frozen_address_map_heap, entry);
}
@ -1160,7 +1160,7 @@ namespace ams::dmnt::cheat::impl {
g_frozen_address_map_heap = lmem::CreateUnitHeap(g_frozen_address_map_memory, sizeof(g_frozen_address_map_memory), sizeof(FrozenAddressMapEntry), lmem::CreateOption_ThreadSafe);
/* Create the cheat process manager (spawning its threads). */
new (GetPointer(g_cheat_process_manager)) CheatProcessManager;
util::ConstructAt(g_cheat_process_manager);
}
bool GetHasActiveCheatProcess() {

View file

@ -148,7 +148,7 @@ namespace ams::dmnt::cheat::impl {
}
void InitializeDebugEventsManager() {
new (GetPointer(g_events_manager)) DebugEventsManager;
util::ConstructAt(g_events_manager);
}
Result ContinueCheatProcess(Handle cheat_dbg_hnd) {

View file

@ -91,15 +91,20 @@ namespace ams::pm::impl {
std::memset(this->process_info_allocated, 0, sizeof(this->process_info_allocated));
}
void *AllocateProcessInfoStorage() {
template<typename... Args>
ProcessInfo *AllocateProcessInfo(Args &&... args) {
std::scoped_lock lk(this->lock);
for (size_t i = 0; i < MaxProcessInfos; i++) {
if (!this->process_info_allocated[i]) {
this->process_info_allocated[i] = true;
std::memset(&this->process_info_storages[i], 0, sizeof(this->process_info_storages[i]));
return GetPointer(this->process_info_storages[i]);
std::memset(this->process_info_storages + i, 0, sizeof(this->process_info_storages[i]));
return util::ConstructAt(this->process_info_storages[i], std::forward<Args>(args)...);
}
}
return nullptr;
}
@ -110,7 +115,7 @@ namespace ams::pm::impl {
AMS_ABORT_UNLESS(index < MaxProcessInfos);
AMS_ABORT_UNLESS(this->process_info_allocated[index]);
process_info->~ProcessInfo();
util::DestroyAt(this->process_info_storages[index]);
this->process_info_allocated[index] = false;
}
};
@ -251,9 +256,8 @@ namespace ams::pm::impl {
os::ProcessId process_id = os::GetProcessId(process_handle);
/* Make new process info. */
void *process_info_storage = g_process_info_allocator.AllocateProcessInfoStorage();
AMS_ABORT_UNLESS(process_info_storage != nullptr);
ProcessInfo *process_info = new (process_info_storage) ProcessInfo(process_handle, process_id, pin_id, location, override_status);
ProcessInfo *process_info = g_process_info_allocator.AllocateProcessInfo(process_handle, process_id, pin_id, location, override_status);
AMS_ABORT_UNLESS(process_info != nullptr);
/* Link new process info. */
{