Kernel: Annotate all KBuffer and DoubleBuffer with a custom name

This commit is contained in:
Tim Schumacher 2022-04-11 00:08:07 +02:00 committed by Linus Groh
parent d6d1ae667d
commit 3b3af58cf6
19 changed files with 32 additions and 32 deletions

View file

@ -17,9 +17,9 @@ inline void DoubleBuffer::compute_lockfree_metadata()
m_space_for_writing = m_capacity - m_write_buffer->size; m_space_for_writing = m_capacity - m_write_buffer->size;
} }
ErrorOr<NonnullOwnPtr<DoubleBuffer>> DoubleBuffer::try_create(size_t capacity) ErrorOr<NonnullOwnPtr<DoubleBuffer>> DoubleBuffer::try_create(StringView name, size_t capacity)
{ {
auto storage = TRY(KBuffer::try_create_with_size(capacity * 2, Memory::Region::Access::ReadWrite, "DoubleBuffer")); auto storage = TRY(KBuffer::try_create_with_size(name, capacity * 2, Memory::Region::Access::ReadWrite));
return adopt_nonnull_own_or_enomem(new (nothrow) DoubleBuffer(capacity, move(storage))); return adopt_nonnull_own_or_enomem(new (nothrow) DoubleBuffer(capacity, move(storage)));
} }

View file

@ -16,7 +16,7 @@ namespace Kernel {
class DoubleBuffer { class DoubleBuffer {
public: public:
static ErrorOr<NonnullOwnPtr<DoubleBuffer>> try_create(size_t capacity = 65536); static ErrorOr<NonnullOwnPtr<DoubleBuffer>> try_create(StringView name, size_t capacity = 65536);
ErrorOr<size_t> write(UserOrKernelBuffer const&, size_t); ErrorOr<size_t> write(UserOrKernelBuffer const&, size_t);
ErrorOr<size_t> write(u8 const* data, size_t size) ErrorOr<size_t> write(u8 const* data, size_t size)
{ {

View file

@ -119,8 +119,8 @@ BlockBasedFileSystem::~BlockBasedFileSystem() = default;
ErrorOr<void> BlockBasedFileSystem::initialize() ErrorOr<void> BlockBasedFileSystem::initialize()
{ {
VERIFY(block_size() != 0); VERIFY(block_size() != 0);
auto cached_block_data = TRY(KBuffer::try_create_with_size(DiskCache::EntryCount * block_size())); auto cached_block_data = TRY(KBuffer::try_create_with_size("BlockBasedFS: Cache blocks"sv, DiskCache::EntryCount * block_size()));
auto entries_data = TRY(KBuffer::try_create_with_size(DiskCache::EntryCount * sizeof(CacheEntry))); auto entries_data = TRY(KBuffer::try_create_with_size("BlockBasedFS: Cache entries"sv, DiskCache::EntryCount * sizeof(CacheEntry)));
auto disk_cache = TRY(adopt_nonnull_own_or_enomem(new (nothrow) DiskCache(*this, move(cached_block_data), move(entries_data)))); auto disk_cache = TRY(adopt_nonnull_own_or_enomem(new (nothrow) DiskCache(*this, move(cached_block_data), move(entries_data))));
m_cache.with_exclusive([&](auto& cache) { m_cache.with_exclusive([&](auto& cache) {

View file

@ -122,7 +122,7 @@ ErrorOr<void> Ext2FS::initialize()
auto blocks_to_read = ceil_div(m_block_group_count * sizeof(ext2_group_desc), block_size()); auto blocks_to_read = ceil_div(m_block_group_count * sizeof(ext2_group_desc), block_size());
BlockIndex first_block_of_bgdt = block_size() == 1024 ? 2 : 1; BlockIndex first_block_of_bgdt = block_size() == 1024 ? 2 : 1;
m_cached_group_descriptor_table = TRY(KBuffer::try_create_with_size(block_size() * blocks_to_read, Memory::Region::Access::ReadWrite, "Ext2FS: Block group descriptors")); m_cached_group_descriptor_table = TRY(KBuffer::try_create_with_size("Ext2FS: Block group descriptors"sv, block_size() * blocks_to_read, Memory::Region::Access::ReadWrite));
auto buffer = UserOrKernelBuffer::for_kernel_buffer(m_cached_group_descriptor_table->data()); auto buffer = UserOrKernelBuffer::for_kernel_buffer(m_cached_group_descriptor_table->data());
TRY(read_blocks(first_block_of_bgdt, blocks_to_read, buffer)); TRY(read_blocks(first_block_of_bgdt, blocks_to_read, buffer));
@ -1415,7 +1415,7 @@ ErrorOr<Ext2FS::CachedBitmap*> Ext2FS::get_bitmap_block(BlockIndex bitmap_block_
return cached_bitmap.ptr(); return cached_bitmap.ptr();
} }
auto block = TRY(KBuffer::try_create_with_size(block_size(), Memory::Region::Access::ReadWrite, "Ext2FS: Cached bitmap block")); auto block = TRY(KBuffer::try_create_with_size("Ext2FS: Cached bitmap block"sv, block_size(), Memory::Region::Access::ReadWrite));
auto buffer = UserOrKernelBuffer::for_kernel_buffer(block->data()); auto buffer = UserOrKernelBuffer::for_kernel_buffer(block->data());
TRY(read_block(bitmap_block_index, &buffer, block_size())); TRY(read_block(bitmap_block_index, &buffer, block_size()));
auto new_bitmap = TRY(adopt_nonnull_own_or_enomem(new (nothrow) CachedBitmap(bitmap_block_index, move(block)))); auto new_bitmap = TRY(adopt_nonnull_own_or_enomem(new (nothrow) CachedBitmap(bitmap_block_index, move(block))));

View file

@ -18,7 +18,7 @@ static Atomic<int> s_next_fifo_id = 1;
ErrorOr<NonnullRefPtr<FIFO>> FIFO::try_create(UserID uid) ErrorOr<NonnullRefPtr<FIFO>> FIFO::try_create(UserID uid)
{ {
auto buffer = TRY(DoubleBuffer::try_create()); auto buffer = TRY(DoubleBuffer::try_create("FIFO: Buffer"sv));
return adopt_nonnull_ref_or_enomem(new (nothrow) FIFO(uid, move(buffer))); return adopt_nonnull_ref_or_enomem(new (nothrow) FIFO(uid, move(buffer)));
} }

View file

@ -227,7 +227,7 @@ ErrorOr<void> ISO9660FS::parse_volume_set()
{ {
VERIFY(!m_primary_volume); VERIFY(!m_primary_volume);
auto block = TRY(KBuffer::try_create_with_size(m_logical_block_size, Memory::Region::Access::Read | Memory::Region::Access::Write, "ISO9660FS: Temporary volume descriptor storage")); auto block = TRY(KBuffer::try_create_with_size("ISO9660FS: Temporary volume descriptor storage"sv, m_logical_block_size, Memory::Region::Access::Read | Memory::Region::Access::Write));
auto block_buffer = UserOrKernelBuffer::for_kernel_buffer(block->data()); auto block_buffer = UserOrKernelBuffer::for_kernel_buffer(block->data());
auto current_block_index = first_data_area_block; auto current_block_index = first_data_area_block;
@ -383,7 +383,7 @@ ErrorOr<NonnullRefPtr<ISO9660FS::DirectoryEntry>> ISO9660FS::directory_entry_for
return EIO; return EIO;
} }
auto blocks = TRY(KBuffer::try_create_with_size(data_length, Memory::Region::Access::Read | Memory::Region::Access::Write, "ISO9660FS: Directory traversal buffer")); auto blocks = TRY(KBuffer::try_create_with_size("ISO9660FS: Directory traversal buffer"sv, data_length, Memory::Region::Access::Read | Memory::Region::Access::Write));
auto blocks_buffer = UserOrKernelBuffer::for_kernel_buffer(blocks->data()); auto blocks_buffer = UserOrKernelBuffer::for_kernel_buffer(blocks->data());
TRY(raw_read_blocks(BlockBasedFileSystem::BlockIndex { extent_location }, data_length / logical_block_size(), blocks_buffer)); TRY(raw_read_blocks(BlockBasedFileSystem::BlockIndex { extent_location }, data_length / logical_block_size(), blocks_buffer));
auto entry = TRY(DirectoryEntry::try_create(extent_location, data_length, move(blocks))); auto entry = TRY(DirectoryEntry::try_create(extent_location, data_length, move(blocks)));
@ -408,7 +408,7 @@ ErrorOr<size_t> ISO9660Inode::read_bytes(off_t offset, size_t size, UserOrKernel
if (static_cast<u64>(offset) >= data_length) if (static_cast<u64>(offset) >= data_length)
return 0; return 0;
auto block = TRY(KBuffer::try_create_with_size(fs().m_logical_block_size)); auto block = TRY(KBuffer::try_create_with_size("ISO9660FS: Inode read buffer"sv, fs().m_logical_block_size));
auto block_buffer = UserOrKernelBuffer::for_kernel_buffer(block->data()); auto block_buffer = UserOrKernelBuffer::for_kernel_buffer(block->data());
size_t total_bytes = min(size, data_length - offset); size_t total_bytes = min(size, data_length - offset);

View file

@ -551,7 +551,7 @@ ErrorOr<void> Plan9FS::read_and_dispatch_one_message()
Header header; Header header;
TRY(do_read(reinterpret_cast<u8*>(&header), sizeof(header))); TRY(do_read(reinterpret_cast<u8*>(&header), sizeof(header)));
auto buffer = TRY(KBuffer::try_create_with_size(header.size, Memory::Region::Access::ReadWrite)); auto buffer = TRY(KBuffer::try_create_with_size("Plan9FS: Message read buffer"sv, header.size, Memory::Region::Access::ReadWrite));
// Copy the already read header into the buffer. // Copy the already read header into the buffer.
memcpy(buffer->data(), &header, sizeof(header)); memcpy(buffer->data(), &header, sizeof(header));
TRY(do_read(buffer->data() + sizeof(header), header.size - sizeof(header))); TRY(do_read(buffer->data() + sizeof(header), header.size - sizeof(header)));

View file

@ -90,6 +90,6 @@ ErrorOr<NonnullOwnPtr<KBuffer>> PCIDeviceAttributeSysFSComponent::try_to_generat
VERIFY_NOT_REACHED(); VERIFY_NOT_REACHED();
} }
return KBuffer::try_create_with_bytes(value->view().bytes()); return KBuffer::try_create_with_bytes("PCIDeviceAttributeSysFSComponent: Device address"sv, value->view().bytes());
} }
} }

View file

@ -56,6 +56,6 @@ StringView BIOSSysFSComponent::name() const
ErrorOr<NonnullOwnPtr<KBuffer>> BIOSSysFSComponent::try_to_generate_buffer() const ErrorOr<NonnullOwnPtr<KBuffer>> BIOSSysFSComponent::try_to_generate_buffer() const
{ {
auto blob = TRY(Memory::map_typed<u8>((m_blob_paddr), m_blob_length)); auto blob = TRY(Memory::map_typed<u8>((m_blob_paddr), m_blob_length));
return KBuffer::try_create_with_bytes(Span<u8> { blob.ptr(), m_blob_length }); return KBuffer::try_create_with_bytes("BIOSSysFSComponent: Blob"sv, Span<u8> { blob.ptr(), m_blob_length });
} }
} }

View file

@ -133,7 +133,7 @@ ErrorOr<size_t> TmpFSInode::write_bytes(off_t offset, size_t size, UserOrKernelB
// FIXME: Fix this so that no memcpy() is necessary, and we can just grow the // FIXME: Fix this so that no memcpy() is necessary, and we can just grow the
// KBuffer and it will add physical pages as needed while keeping the // KBuffer and it will add physical pages as needed while keeping the
// existing ones. // existing ones.
auto tmp = TRY(KBuffer::try_create_with_size(new_size * 2)); auto tmp = TRY(KBuffer::try_create_with_size("TmpFSInode: Content"sv, new_size * 2));
tmp->set_size(new_size); tmp->set_size(new_size);
if (m_content) if (m_content)
memcpy(tmp->data(), m_content->data(), old_size); memcpy(tmp->data(), m_content->data(), old_size);
@ -285,7 +285,7 @@ ErrorOr<void> TmpFSInode::truncate(u64 size)
if (size == 0) if (size == 0)
m_content.clear(); m_content.clear();
else if (!m_content) { else if (!m_content) {
m_content = TRY(KBuffer::try_create_with_size(size)); m_content = TRY(KBuffer::try_create_with_size("TmpFSInode: Content"sv, size));
} else if (static_cast<size_t>(size) < m_content->capacity()) { } else if (static_cast<size_t>(size) < m_content->capacity()) {
size_t prev_size = m_metadata.size; size_t prev_size = m_metadata.size;
m_content->set_size(size); m_content->set_size(size);
@ -293,7 +293,7 @@ ErrorOr<void> TmpFSInode::truncate(u64 size)
memset(m_content->data() + prev_size, 0, size - prev_size); memset(m_content->data() + prev_size, 0, size - prev_size);
} else { } else {
size_t prev_size = m_metadata.size; size_t prev_size = m_metadata.size;
auto tmp = TRY(KBuffer::try_create_with_size(size)); auto tmp = TRY(KBuffer::try_create_with_size("TmpFSInode: Content"sv, size));
memcpy(tmp->data(), m_content->data(), prev_size); memcpy(tmp->data(), m_content->data(), prev_size);
m_content = move(tmp); m_content = move(tmp);
} }

View file

@ -57,7 +57,7 @@ ErrorOr<size_t> ACPISysFSComponent::read_bytes(off_t offset, size_t count, UserO
ErrorOr<NonnullOwnPtr<KBuffer>> ACPISysFSComponent::try_to_generate_buffer() const ErrorOr<NonnullOwnPtr<KBuffer>> ACPISysFSComponent::try_to_generate_buffer() const
{ {
auto acpi_blob = TRY(Memory::map_typed<u8>((m_paddr), m_length)); auto acpi_blob = TRY(Memory::map_typed<u8>((m_paddr), m_length));
return KBuffer::try_create_with_bytes(Span<u8> { acpi_blob.ptr(), m_length }); return KBuffer::try_create_with_bytes("ACPISysFSComponent: Blob"sv, Span<u8> { acpi_blob.ptr(), m_length });
} }
UNMAP_AFTER_INIT ACPISysFSComponent::ACPISysFSComponent(NonnullOwnPtr<KString> table_name, PhysicalAddress paddr, size_t table_size) UNMAP_AFTER_INIT ACPISysFSComponent::ACPISysFSComponent(NonnullOwnPtr<KString> table_name, PhysicalAddress paddr, size_t table_size)

View file

@ -24,16 +24,16 @@ namespace Kernel {
class [[nodiscard]] KBuffer { class [[nodiscard]] KBuffer {
public: public:
static ErrorOr<NonnullOwnPtr<KBuffer>> try_create_with_size(size_t size, Memory::Region::Access access = Memory::Region::Access::ReadWrite, StringView name = "KBuffer", AllocationStrategy strategy = AllocationStrategy::Reserve) static ErrorOr<NonnullOwnPtr<KBuffer>> try_create_with_size(StringView name, size_t size, Memory::Region::Access access = Memory::Region::Access::ReadWrite, AllocationStrategy strategy = AllocationStrategy::Reserve)
{ {
auto rounded_size = TRY(Memory::page_round_up(size)); auto rounded_size = TRY(Memory::page_round_up(size));
auto region = TRY(MM.allocate_kernel_region(rounded_size, name, access, strategy)); auto region = TRY(MM.allocate_kernel_region(rounded_size, name, access, strategy));
return TRY(adopt_nonnull_own_or_enomem(new (nothrow) KBuffer { size, move(region) })); return TRY(adopt_nonnull_own_or_enomem(new (nothrow) KBuffer { size, move(region) }));
} }
static ErrorOr<NonnullOwnPtr<KBuffer>> try_create_with_bytes(ReadonlyBytes bytes, Memory::Region::Access access = Memory::Region::Access::ReadWrite, StringView name = "KBuffer", AllocationStrategy strategy = AllocationStrategy::Reserve) static ErrorOr<NonnullOwnPtr<KBuffer>> try_create_with_bytes(StringView name, ReadonlyBytes bytes, Memory::Region::Access access = Memory::Region::Access::ReadWrite, AllocationStrategy strategy = AllocationStrategy::Reserve)
{ {
auto buffer = TRY(try_create_with_size(bytes.size(), access, name, strategy)); auto buffer = TRY(try_create_with_size(name, bytes.size(), access, strategy));
memcpy(buffer->data(), bytes.data(), bytes.size()); memcpy(buffer->data(), bytes.data(), bytes.size());
return buffer; return buffer;
} }

View file

@ -24,7 +24,7 @@ inline bool KBufferBuilder::check_expand(size_t size)
if (rounded_new_buffer_size_or_error.is_error()) { if (rounded_new_buffer_size_or_error.is_error()) {
return false; return false;
} }
auto new_buffer_or_error = KBuffer::try_create_with_size(rounded_new_buffer_size_or_error.value()); auto new_buffer_or_error = KBuffer::try_create_with_size("KBufferBuilder"sv, rounded_new_buffer_size_or_error.value());
if (new_buffer_or_error.is_error()) if (new_buffer_or_error.is_error())
return false; return false;
auto new_buffer = new_buffer_or_error.release_value(); auto new_buffer = new_buffer_or_error.release_value();
@ -51,7 +51,7 @@ OwnPtr<KBuffer> KBufferBuilder::build()
ErrorOr<KBufferBuilder> KBufferBuilder::try_create() ErrorOr<KBufferBuilder> KBufferBuilder::try_create()
{ {
auto buffer = TRY(KBuffer::try_create_with_size(4 * MiB, Memory::Region::Access::ReadWrite)); auto buffer = TRY(KBuffer::try_create_with_size("KBufferBuilder"sv, 4 * MiB, Memory::Region::Access::ReadWrite));
return KBufferBuilder { move(buffer) }; return KBufferBuilder { move(buffer) };
} }

View file

@ -37,7 +37,7 @@ MutexProtected<IPv4Socket::List>& IPv4Socket::all_sockets()
ErrorOr<NonnullOwnPtr<DoubleBuffer>> IPv4Socket::try_create_receive_buffer() ErrorOr<NonnullOwnPtr<DoubleBuffer>> IPv4Socket::try_create_receive_buffer()
{ {
return DoubleBuffer::try_create(256 * KiB); return DoubleBuffer::try_create("IPv4Socket: Receive buffer"sv, 256 * KiB);
} }
ErrorOr<NonnullRefPtr<Socket>> IPv4Socket::create(int type, int protocol) ErrorOr<NonnullRefPtr<Socket>> IPv4Socket::create(int type, int protocol)
@ -444,7 +444,7 @@ bool IPv4Socket::did_receive(IPv4Address const& source_address, u16 source_port,
dbgln("IPv4Socket({}): did_receive refusing packet since queue is full.", this); dbgln("IPv4Socket({}): did_receive refusing packet since queue is full.", this);
return false; return false;
} }
auto data_or_error = KBuffer::try_create_with_bytes(packet); auto data_or_error = KBuffer::try_create_with_bytes("IPv4Socket: Packet buffer"sv, packet);
if (data_or_error.is_error()) { if (data_or_error.is_error()) {
dbgln("IPv4Socket: did_receive unable to allocate storage for incoming packet."); dbgln("IPv4Socket: did_receive unable to allocate storage for incoming packet.");
return false; return false;

View file

@ -45,8 +45,8 @@ ErrorOr<void> LocalSocket::try_for_each(Function<ErrorOr<void>(LocalSocket const
ErrorOr<NonnullRefPtr<LocalSocket>> LocalSocket::try_create(int type) ErrorOr<NonnullRefPtr<LocalSocket>> LocalSocket::try_create(int type)
{ {
auto client_buffer = TRY(DoubleBuffer::try_create()); auto client_buffer = TRY(DoubleBuffer::try_create("LocalSocket: Client buffer"sv));
auto server_buffer = TRY(DoubleBuffer::try_create()); auto server_buffer = TRY(DoubleBuffer::try_create("LocalSocket: Server buffer"sv));
return adopt_nonnull_ref_or_enomem(new (nothrow) LocalSocket(type, move(client_buffer), move(server_buffer))); return adopt_nonnull_ref_or_enomem(new (nothrow) LocalSocket(type, move(client_buffer), move(server_buffer)));
} }

View file

@ -115,7 +115,7 @@ RefPtr<PacketWithTimestamp> NetworkAdapter::acquire_packet_buffer(size_t size)
{ {
InterruptDisabler disabler; InterruptDisabler disabler;
if (m_unused_packets.is_empty()) { if (m_unused_packets.is_empty()) {
auto buffer_or_error = KBuffer::try_create_with_size(size, Memory::Region::Access::ReadWrite, "Packet Buffer", AllocationStrategy::AllocateNow); auto buffer_or_error = KBuffer::try_create_with_size("NetworkAdapter: Packet buffer"sv, size, Memory::Region::Access::ReadWrite, AllocationStrategy::AllocateNow);
if (buffer_or_error.is_error()) if (buffer_or_error.is_error())
return {}; return {};
auto buffer = buffer_or_error.release_value(); auto buffer = buffer_or_error.release_value();
@ -133,7 +133,7 @@ RefPtr<PacketWithTimestamp> NetworkAdapter::acquire_packet_buffer(size_t size)
return packet; return packet;
} }
auto buffer_or_error = KBuffer::try_create_with_size(size, Memory::Region::Access::ReadWrite, "Packet Buffer", AllocationStrategy::AllocateNow); auto buffer_or_error = KBuffer::try_create_with_size("NetworkAdapter: Packet buffer"sv, size, Memory::Region::Access::ReadWrite, AllocationStrategy::AllocateNow);
if (buffer_or_error.is_error()) if (buffer_or_error.is_error())
return {}; return {};
packet = adopt_ref_if_nonnull(new (nothrow) PacketWithTimestamp { buffer_or_error.release_value(), kgettimeofday() }); packet = adopt_ref_if_nonnull(new (nothrow) PacketWithTimestamp { buffer_or_error.release_value(), kgettimeofday() });

View file

@ -178,7 +178,7 @@ TCPSocket::~TCPSocket()
ErrorOr<NonnullRefPtr<TCPSocket>> TCPSocket::try_create(int protocol, NonnullOwnPtr<DoubleBuffer> receive_buffer) ErrorOr<NonnullRefPtr<TCPSocket>> TCPSocket::try_create(int protocol, NonnullOwnPtr<DoubleBuffer> receive_buffer)
{ {
// Note: Scratch buffer is only used for SOCK_STREAM sockets. // Note: Scratch buffer is only used for SOCK_STREAM sockets.
auto scratch_buffer = TRY(KBuffer::try_create_with_size(65536)); auto scratch_buffer = TRY(KBuffer::try_create_with_size("TCPSocket: Scratch buffer"sv, 65536));
return adopt_nonnull_ref_or_enomem(new (nothrow) TCPSocket(protocol, move(receive_buffer), move(scratch_buffer))); return adopt_nonnull_ref_or_enomem(new (nothrow) TCPSocket(protocol, move(receive_buffer), move(scratch_buffer)));
} }

View file

@ -325,7 +325,7 @@ ErrorOr<void> PerformanceEventBuffer::to_json(KBufferBuilder& builder) const
OwnPtr<PerformanceEventBuffer> PerformanceEventBuffer::try_create_with_size(size_t buffer_size) OwnPtr<PerformanceEventBuffer> PerformanceEventBuffer::try_create_with_size(size_t buffer_size)
{ {
auto buffer_or_error = KBuffer::try_create_with_size(buffer_size, Memory::Region::Access::ReadWrite, "Performance events", AllocationStrategy::AllocateNow); auto buffer_or_error = KBuffer::try_create_with_size("Performance events"sv, buffer_size, Memory::Region::Access::ReadWrite, AllocationStrategy::AllocateNow);
if (buffer_or_error.is_error()) if (buffer_or_error.is_error())
return {}; return {};
return adopt_own_if_nonnull(new (nothrow) PerformanceEventBuffer(buffer_or_error.release_value())); return adopt_own_if_nonnull(new (nothrow) PerformanceEventBuffer(buffer_or_error.release_value()));

View file

@ -18,7 +18,7 @@ namespace Kernel {
ErrorOr<NonnullRefPtr<MasterPTY>> MasterPTY::try_create(unsigned int index) ErrorOr<NonnullRefPtr<MasterPTY>> MasterPTY::try_create(unsigned int index)
{ {
auto buffer = TRY(DoubleBuffer::try_create()); auto buffer = TRY(DoubleBuffer::try_create("MasterPTY: Buffer"sv));
auto master_pty = TRY(adopt_nonnull_ref_or_enomem(new (nothrow) MasterPTY(index, move(buffer)))); auto master_pty = TRY(adopt_nonnull_ref_or_enomem(new (nothrow) MasterPTY(index, move(buffer))));
auto slave_pty = TRY(adopt_nonnull_ref_or_enomem(new (nothrow) SlavePTY(*master_pty, index))); auto slave_pty = TRY(adopt_nonnull_ref_or_enomem(new (nothrow) SlavePTY(*master_pty, index)));
master_pty->m_slave = slave_pty; master_pty->m_slave = slave_pty;