mirror of
				https://git.suyu.dev/suyu/suyu
				synced 2025-11-04 00:49:02 -06:00 
			
		
		
		
	core: hle: kernel: k_handle_table: Refresh.
This commit is contained in:
		@@ -5,14 +5,11 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace Kernel {
 | 
					namespace Kernel {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
KHandleTable::KHandleTable(KernelCore& kernel_) : kernel{kernel_} {}
 | 
					 | 
				
			||||||
KHandleTable::~KHandleTable() = default;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Result KHandleTable::Finalize() {
 | 
					Result KHandleTable::Finalize() {
 | 
				
			||||||
    // Get the table and clear our record of it.
 | 
					    // Get the table and clear our record of it.
 | 
				
			||||||
    u16 saved_table_size = 0;
 | 
					    u16 saved_table_size = 0;
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        KScopedDisableDispatch dd(kernel);
 | 
					        KScopedDisableDispatch dd{m_kernel};
 | 
				
			||||||
        KScopedSpinLock lk(m_lock);
 | 
					        KScopedSpinLock lk(m_lock);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        std::swap(m_table_size, saved_table_size);
 | 
					        std::swap(m_table_size, saved_table_size);
 | 
				
			||||||
@@ -25,28 +22,28 @@ Result KHandleTable::Finalize() {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return ResultSuccess;
 | 
					    R_SUCCEED();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool KHandleTable::Remove(Handle handle) {
 | 
					bool KHandleTable::Remove(Handle handle) {
 | 
				
			||||||
    // Don't allow removal of a pseudo-handle.
 | 
					    // Don't allow removal of a pseudo-handle.
 | 
				
			||||||
    if (Svc::IsPseudoHandle(handle)) {
 | 
					    if (Svc::IsPseudoHandle(handle)) [[unlikely]] {
 | 
				
			||||||
        return false;
 | 
					        return false;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Handles must not have reserved bits set.
 | 
					    // Handles must not have reserved bits set.
 | 
				
			||||||
    const auto handle_pack = HandlePack(handle);
 | 
					    const auto handle_pack = HandlePack(handle);
 | 
				
			||||||
    if (handle_pack.reserved != 0) {
 | 
					    if (handle_pack.reserved != 0) [[unlikely]] {
 | 
				
			||||||
        return false;
 | 
					        return false;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Find the object and free the entry.
 | 
					    // Find the object and free the entry.
 | 
				
			||||||
    KAutoObject* obj = nullptr;
 | 
					    KAutoObject* obj = nullptr;
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        KScopedDisableDispatch dd(kernel);
 | 
					        KScopedDisableDispatch dd{m_kernel};
 | 
				
			||||||
        KScopedSpinLock lk(m_lock);
 | 
					        KScopedSpinLock lk(m_lock);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (this->IsValidHandle(handle)) {
 | 
					        if (this->IsValidHandle(handle)) [[likely]] {
 | 
				
			||||||
            const auto index = handle_pack.index;
 | 
					            const auto index = handle_pack.index;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            obj = m_objects[index];
 | 
					            obj = m_objects[index];
 | 
				
			||||||
@@ -57,13 +54,13 @@ bool KHandleTable::Remove(Handle handle) {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Close the object.
 | 
					    // Close the object.
 | 
				
			||||||
    kernel.UnregisterInUseObject(obj);
 | 
					    m_kernel.UnregisterInUseObject(obj);
 | 
				
			||||||
    obj->Close();
 | 
					    obj->Close();
 | 
				
			||||||
    return true;
 | 
					    return true;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Result KHandleTable::Add(Handle* out_handle, KAutoObject* obj) {
 | 
					Result KHandleTable::Add(Handle* out_handle, KAutoObject* obj) {
 | 
				
			||||||
    KScopedDisableDispatch dd(kernel);
 | 
					    KScopedDisableDispatch dd{m_kernel};
 | 
				
			||||||
    KScopedSpinLock lk(m_lock);
 | 
					    KScopedSpinLock lk(m_lock);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Never exceed our capacity.
 | 
					    // Never exceed our capacity.
 | 
				
			||||||
@@ -82,22 +79,22 @@ Result KHandleTable::Add(Handle* out_handle, KAutoObject* obj) {
 | 
				
			|||||||
        *out_handle = EncodeHandle(static_cast<u16>(index), linear_id);
 | 
					        *out_handle = EncodeHandle(static_cast<u16>(index), linear_id);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return ResultSuccess;
 | 
					    R_SUCCEED();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Result KHandleTable::Reserve(Handle* out_handle) {
 | 
					Result KHandleTable::Reserve(Handle* out_handle) {
 | 
				
			||||||
    KScopedDisableDispatch dd(kernel);
 | 
					    KScopedDisableDispatch dd{m_kernel};
 | 
				
			||||||
    KScopedSpinLock lk(m_lock);
 | 
					    KScopedSpinLock lk(m_lock);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Never exceed our capacity.
 | 
					    // Never exceed our capacity.
 | 
				
			||||||
    R_UNLESS(m_count < m_table_size, ResultOutOfHandles);
 | 
					    R_UNLESS(m_count < m_table_size, ResultOutOfHandles);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    *out_handle = EncodeHandle(static_cast<u16>(this->AllocateEntry()), this->AllocateLinearId());
 | 
					    *out_handle = EncodeHandle(static_cast<u16>(this->AllocateEntry()), this->AllocateLinearId());
 | 
				
			||||||
    return ResultSuccess;
 | 
					    R_SUCCEED();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void KHandleTable::Unreserve(Handle handle) {
 | 
					void KHandleTable::Unreserve(Handle handle) {
 | 
				
			||||||
    KScopedDisableDispatch dd(kernel);
 | 
					    KScopedDisableDispatch dd{m_kernel};
 | 
				
			||||||
    KScopedSpinLock lk(m_lock);
 | 
					    KScopedSpinLock lk(m_lock);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Unpack the handle.
 | 
					    // Unpack the handle.
 | 
				
			||||||
@@ -108,7 +105,7 @@ void KHandleTable::Unreserve(Handle handle) {
 | 
				
			|||||||
    ASSERT(reserved == 0);
 | 
					    ASSERT(reserved == 0);
 | 
				
			||||||
    ASSERT(linear_id != 0);
 | 
					    ASSERT(linear_id != 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (index < m_table_size) {
 | 
					    if (index < m_table_size) [[likely]] {
 | 
				
			||||||
        // NOTE: This code does not check the linear id.
 | 
					        // NOTE: This code does not check the linear id.
 | 
				
			||||||
        ASSERT(m_objects[index] == nullptr);
 | 
					        ASSERT(m_objects[index] == nullptr);
 | 
				
			||||||
        this->FreeEntry(index);
 | 
					        this->FreeEntry(index);
 | 
				
			||||||
@@ -116,7 +113,7 @@ void KHandleTable::Unreserve(Handle handle) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void KHandleTable::Register(Handle handle, KAutoObject* obj) {
 | 
					void KHandleTable::Register(Handle handle, KAutoObject* obj) {
 | 
				
			||||||
    KScopedDisableDispatch dd(kernel);
 | 
					    KScopedDisableDispatch dd{m_kernel};
 | 
				
			||||||
    KScopedSpinLock lk(m_lock);
 | 
					    KScopedSpinLock lk(m_lock);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Unpack the handle.
 | 
					    // Unpack the handle.
 | 
				
			||||||
@@ -127,7 +124,7 @@ void KHandleTable::Register(Handle handle, KAutoObject* obj) {
 | 
				
			|||||||
    ASSERT(reserved == 0);
 | 
					    ASSERT(reserved == 0);
 | 
				
			||||||
    ASSERT(linear_id != 0);
 | 
					    ASSERT(linear_id != 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (index < m_table_size) {
 | 
					    if (index < m_table_size) [[likely]] {
 | 
				
			||||||
        // Set the entry.
 | 
					        // Set the entry.
 | 
				
			||||||
        ASSERT(m_objects[index] == nullptr);
 | 
					        ASSERT(m_objects[index] == nullptr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -21,33 +21,38 @@ namespace Kernel {
 | 
				
			|||||||
class KernelCore;
 | 
					class KernelCore;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class KHandleTable {
 | 
					class KHandleTable {
 | 
				
			||||||
public:
 | 
					 | 
				
			||||||
    YUZU_NON_COPYABLE(KHandleTable);
 | 
					    YUZU_NON_COPYABLE(KHandleTable);
 | 
				
			||||||
    YUZU_NON_MOVEABLE(KHandleTable);
 | 
					    YUZU_NON_MOVEABLE(KHandleTable);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
    static constexpr size_t MaxTableSize = 1024;
 | 
					    static constexpr size_t MaxTableSize = 1024;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    explicit KHandleTable(KernelCore& kernel_);
 | 
					public:
 | 
				
			||||||
    ~KHandleTable();
 | 
					    explicit KHandleTable(KernelCore& kernel) : m_kernel(kernel) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Result Initialize(s32 size) {
 | 
					    Result Initialize(s32 size) {
 | 
				
			||||||
 | 
					        // Check that the table size is valid.
 | 
				
			||||||
        R_UNLESS(size <= static_cast<s32>(MaxTableSize), ResultOutOfMemory);
 | 
					        R_UNLESS(size <= static_cast<s32>(MaxTableSize), ResultOutOfMemory);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Lock.
 | 
				
			||||||
 | 
					        KScopedDisableDispatch dd{m_kernel};
 | 
				
			||||||
 | 
					        KScopedSpinLock lk(m_lock);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Initialize all fields.
 | 
					        // Initialize all fields.
 | 
				
			||||||
        m_max_count = 0;
 | 
					        m_max_count = 0;
 | 
				
			||||||
        m_table_size = static_cast<u16>((size <= 0) ? MaxTableSize : size);
 | 
					        m_table_size = static_cast<s16>((size <= 0) ? MaxTableSize : size);
 | 
				
			||||||
        m_next_linear_id = MinLinearId;
 | 
					        m_next_linear_id = MinLinearId;
 | 
				
			||||||
        m_count = 0;
 | 
					        m_count = 0;
 | 
				
			||||||
        m_free_head_index = -1;
 | 
					        m_free_head_index = -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Free all entries.
 | 
					        // Free all entries.
 | 
				
			||||||
        for (s16 i = 0; i < static_cast<s16>(m_table_size); ++i) {
 | 
					        for (s32 i = 0; i < static_cast<s32>(m_table_size); ++i) {
 | 
				
			||||||
            m_objects[i] = nullptr;
 | 
					            m_objects[i] = nullptr;
 | 
				
			||||||
            m_entry_infos[i].next_free_index = i - 1;
 | 
					            m_entry_infos[i].next_free_index = static_cast<s16>(i - 1);
 | 
				
			||||||
            m_free_head_index = i;
 | 
					            m_free_head_index = i;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return ResultSuccess;
 | 
					        R_SUCCEED();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    size_t GetTableSize() const {
 | 
					    size_t GetTableSize() const {
 | 
				
			||||||
@@ -66,13 +71,13 @@ public:
 | 
				
			|||||||
    template <typename T = KAutoObject>
 | 
					    template <typename T = KAutoObject>
 | 
				
			||||||
    KScopedAutoObject<T> GetObjectWithoutPseudoHandle(Handle handle) const {
 | 
					    KScopedAutoObject<T> GetObjectWithoutPseudoHandle(Handle handle) const {
 | 
				
			||||||
        // Lock and look up in table.
 | 
					        // Lock and look up in table.
 | 
				
			||||||
        KScopedDisableDispatch dd(kernel);
 | 
					        KScopedDisableDispatch dd{m_kernel};
 | 
				
			||||||
        KScopedSpinLock lk(m_lock);
 | 
					        KScopedSpinLock lk(m_lock);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if constexpr (std::is_same_v<T, KAutoObject>) {
 | 
					        if constexpr (std::is_same<T, KAutoObject>::value) {
 | 
				
			||||||
            return this->GetObjectImpl(handle);
 | 
					            return this->GetObjectImpl(handle);
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            if (auto* obj = this->GetObjectImpl(handle); obj != nullptr) {
 | 
					            if (auto* obj = this->GetObjectImpl(handle); obj != nullptr) [[likely]] {
 | 
				
			||||||
                return obj->DynamicCast<T*>();
 | 
					                return obj->DynamicCast<T*>();
 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
                return nullptr;
 | 
					                return nullptr;
 | 
				
			||||||
@@ -85,13 +90,13 @@ public:
 | 
				
			|||||||
        // Handle pseudo-handles.
 | 
					        // Handle pseudo-handles.
 | 
				
			||||||
        if constexpr (std::derived_from<KProcess, T>) {
 | 
					        if constexpr (std::derived_from<KProcess, T>) {
 | 
				
			||||||
            if (handle == Svc::PseudoHandle::CurrentProcess) {
 | 
					            if (handle == Svc::PseudoHandle::CurrentProcess) {
 | 
				
			||||||
                auto* const cur_process = kernel.CurrentProcess();
 | 
					                auto* const cur_process = m_kernel.CurrentProcess();
 | 
				
			||||||
                ASSERT(cur_process != nullptr);
 | 
					                ASSERT(cur_process != nullptr);
 | 
				
			||||||
                return cur_process;
 | 
					                return cur_process;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        } else if constexpr (std::derived_from<KThread, T>) {
 | 
					        } else if constexpr (std::derived_from<KThread, T>) {
 | 
				
			||||||
            if (handle == Svc::PseudoHandle::CurrentThread) {
 | 
					            if (handle == Svc::PseudoHandle::CurrentThread) {
 | 
				
			||||||
                auto* const cur_thread = GetCurrentThreadPointer(kernel);
 | 
					                auto* const cur_thread = GetCurrentThreadPointer(m_kernel);
 | 
				
			||||||
                ASSERT(cur_thread != nullptr);
 | 
					                ASSERT(cur_thread != nullptr);
 | 
				
			||||||
                return cur_thread;
 | 
					                return cur_thread;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
@@ -100,6 +105,37 @@ public:
 | 
				
			|||||||
        return this->template GetObjectWithoutPseudoHandle<T>(handle);
 | 
					        return this->template GetObjectWithoutPseudoHandle<T>(handle);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    KScopedAutoObject<KAutoObject> GetObjectForIpcWithoutPseudoHandle(Handle handle) const {
 | 
				
			||||||
 | 
					        // Lock and look up in table.
 | 
				
			||||||
 | 
					        KScopedDisableDispatch dd{m_kernel};
 | 
				
			||||||
 | 
					        KScopedSpinLock lk(m_lock);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return this->GetObjectImpl(handle);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    KScopedAutoObject<KAutoObject> GetObjectForIpc(Handle handle, KThread* cur_thread) const {
 | 
				
			||||||
 | 
					        // Handle pseudo-handles.
 | 
				
			||||||
 | 
					        ASSERT(cur_thread != nullptr);
 | 
				
			||||||
 | 
					        if (handle == Svc::PseudoHandle::CurrentProcess) {
 | 
				
			||||||
 | 
					            auto* const cur_process =
 | 
				
			||||||
 | 
					                static_cast<KAutoObject*>(static_cast<void*>(cur_thread->GetOwnerProcess()));
 | 
				
			||||||
 | 
					            ASSERT(cur_process != nullptr);
 | 
				
			||||||
 | 
					            return cur_process;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (handle == Svc::PseudoHandle::CurrentThread) {
 | 
				
			||||||
 | 
					            return static_cast<KAutoObject*>(cur_thread);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return GetObjectForIpcWithoutPseudoHandle(handle);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    KScopedAutoObject<KAutoObject> GetObjectByIndex(Handle* out_handle, size_t index) const {
 | 
				
			||||||
 | 
					        KScopedDisableDispatch dd{m_kernel};
 | 
				
			||||||
 | 
					        KScopedSpinLock lk(m_lock);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return this->GetObjectByIndexImpl(out_handle, index);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Result Reserve(Handle* out_handle);
 | 
					    Result Reserve(Handle* out_handle);
 | 
				
			||||||
    void Unreserve(Handle handle);
 | 
					    void Unreserve(Handle handle);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -112,7 +148,7 @@ public:
 | 
				
			|||||||
        size_t num_opened;
 | 
					        size_t num_opened;
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            // Lock the table.
 | 
					            // Lock the table.
 | 
				
			||||||
            KScopedDisableDispatch dd(kernel);
 | 
					            KScopedDisableDispatch dd{m_kernel};
 | 
				
			||||||
            KScopedSpinLock lk(m_lock);
 | 
					            KScopedSpinLock lk(m_lock);
 | 
				
			||||||
            for (num_opened = 0; num_opened < num_handles; num_opened++) {
 | 
					            for (num_opened = 0; num_opened < num_handles; num_opened++) {
 | 
				
			||||||
                // Get the current handle.
 | 
					                // Get the current handle.
 | 
				
			||||||
@@ -120,13 +156,13 @@ public:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                // Get the object for the current handle.
 | 
					                // Get the object for the current handle.
 | 
				
			||||||
                KAutoObject* cur_object = this->GetObjectImpl(cur_handle);
 | 
					                KAutoObject* cur_object = this->GetObjectImpl(cur_handle);
 | 
				
			||||||
                if (cur_object == nullptr) {
 | 
					                if (cur_object == nullptr) [[unlikely]] {
 | 
				
			||||||
                    break;
 | 
					                    break;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                // Cast the current object to the desired type.
 | 
					                // Cast the current object to the desired type.
 | 
				
			||||||
                T* cur_t = cur_object->DynamicCast<T*>();
 | 
					                T* cur_t = cur_object->DynamicCast<T*>();
 | 
				
			||||||
                if (cur_t == nullptr) {
 | 
					                if (cur_t == nullptr) [[unlikely]] {
 | 
				
			||||||
                    break;
 | 
					                    break;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -137,7 +173,7 @@ public:
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // If we converted every object, succeed.
 | 
					        // If we converted every object, succeed.
 | 
				
			||||||
        if (num_opened == num_handles) {
 | 
					        if (num_opened == num_handles) [[likely]] {
 | 
				
			||||||
            return true;
 | 
					            return true;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -191,21 +227,21 @@ private:
 | 
				
			|||||||
        ASSERT(reserved == 0);
 | 
					        ASSERT(reserved == 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Validate our indexing information.
 | 
					        // Validate our indexing information.
 | 
				
			||||||
        if (raw_value == 0) {
 | 
					        if (raw_value == 0) [[unlikely]] {
 | 
				
			||||||
            return false;
 | 
					            return false;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        if (linear_id == 0) {
 | 
					        if (linear_id == 0) [[unlikely]] {
 | 
				
			||||||
            return false;
 | 
					            return false;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        if (index >= m_table_size) {
 | 
					        if (index >= m_table_size) [[unlikely]] {
 | 
				
			||||||
            return false;
 | 
					            return false;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Check that there's an object, and our serial id is correct.
 | 
					        // Check that there's an object, and our serial id is correct.
 | 
				
			||||||
        if (m_objects[index] == nullptr) {
 | 
					        if (m_objects[index] == nullptr) [[unlikely]] {
 | 
				
			||||||
            return false;
 | 
					            return false;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        if (m_entry_infos[index].GetLinearId() != linear_id) {
 | 
					        if (m_entry_infos[index].GetLinearId() != linear_id) [[unlikely]] {
 | 
				
			||||||
            return false;
 | 
					            return false;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -215,11 +251,11 @@ private:
 | 
				
			|||||||
    KAutoObject* GetObjectImpl(Handle handle) const {
 | 
					    KAutoObject* GetObjectImpl(Handle handle) const {
 | 
				
			||||||
        // Handles must not have reserved bits set.
 | 
					        // Handles must not have reserved bits set.
 | 
				
			||||||
        const auto handle_pack = HandlePack(handle);
 | 
					        const auto handle_pack = HandlePack(handle);
 | 
				
			||||||
        if (handle_pack.reserved != 0) {
 | 
					        if (handle_pack.reserved != 0) [[unlikely]] {
 | 
				
			||||||
            return nullptr;
 | 
					            return nullptr;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (this->IsValidHandle(handle)) {
 | 
					        if (this->IsValidHandle(handle)) [[likely]] {
 | 
				
			||||||
            return m_objects[handle_pack.index];
 | 
					            return m_objects[handle_pack.index];
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            return nullptr;
 | 
					            return nullptr;
 | 
				
			||||||
@@ -227,9 +263,8 @@ private:
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    KAutoObject* GetObjectByIndexImpl(Handle* out_handle, size_t index) const {
 | 
					    KAutoObject* GetObjectByIndexImpl(Handle* out_handle, size_t index) const {
 | 
				
			||||||
 | 
					 | 
				
			||||||
        // Index must be in bounds.
 | 
					        // Index must be in bounds.
 | 
				
			||||||
        if (index >= m_table_size) {
 | 
					        if (index >= m_table_size) [[unlikely]] {
 | 
				
			||||||
            return nullptr;
 | 
					            return nullptr;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -244,18 +279,15 @@ private:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
    union HandlePack {
 | 
					    union HandlePack {
 | 
				
			||||||
        HandlePack() = default;
 | 
					        constexpr HandlePack() = default;
 | 
				
			||||||
        HandlePack(Handle handle) : raw{static_cast<u32>(handle)} {}
 | 
					        constexpr HandlePack(Handle handle) : raw{static_cast<u32>(handle)} {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        u32 raw;
 | 
					        u32 raw{};
 | 
				
			||||||
        BitField<0, 15, u32> index;
 | 
					        BitField<0, 15, u32> index;
 | 
				
			||||||
        BitField<15, 15, u32> linear_id;
 | 
					        BitField<15, 15, u32> linear_id;
 | 
				
			||||||
        BitField<30, 2, u32> reserved;
 | 
					        BitField<30, 2, u32> reserved;
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    static constexpr u16 MinLinearId = 1;
 | 
					 | 
				
			||||||
    static constexpr u16 MaxLinearId = 0x7FFF;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    static constexpr Handle EncodeHandle(u16 index, u16 linear_id) {
 | 
					    static constexpr Handle EncodeHandle(u16 index, u16 linear_id) {
 | 
				
			||||||
        HandlePack handle{};
 | 
					        HandlePack handle{};
 | 
				
			||||||
        handle.index.Assign(index);
 | 
					        handle.index.Assign(index);
 | 
				
			||||||
@@ -264,6 +296,10 @@ private:
 | 
				
			|||||||
        return handle.raw;
 | 
					        return handle.raw;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					    static constexpr u16 MinLinearId = 1;
 | 
				
			||||||
 | 
					    static constexpr u16 MaxLinearId = 0x7FFF;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    union EntryInfo {
 | 
					    union EntryInfo {
 | 
				
			||||||
        u16 linear_id;
 | 
					        u16 linear_id;
 | 
				
			||||||
        s16 next_free_index;
 | 
					        s16 next_free_index;
 | 
				
			||||||
@@ -271,21 +307,21 @@ private:
 | 
				
			|||||||
        constexpr u16 GetLinearId() const {
 | 
					        constexpr u16 GetLinearId() const {
 | 
				
			||||||
            return linear_id;
 | 
					            return linear_id;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        constexpr s16 GetNextFreeIndex() const {
 | 
					        constexpr s32 GetNextFreeIndex() const {
 | 
				
			||||||
            return next_free_index;
 | 
					            return next_free_index;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
 | 
					    KernelCore& m_kernel;
 | 
				
			||||||
    std::array<EntryInfo, MaxTableSize> m_entry_infos{};
 | 
					    std::array<EntryInfo, MaxTableSize> m_entry_infos{};
 | 
				
			||||||
    std::array<KAutoObject*, MaxTableSize> m_objects{};
 | 
					    std::array<KAutoObject*, MaxTableSize> m_objects{};
 | 
				
			||||||
    s32 m_free_head_index{-1};
 | 
					    mutable KSpinLock m_lock;
 | 
				
			||||||
 | 
					    s32 m_free_head_index{};
 | 
				
			||||||
    u16 m_table_size{};
 | 
					    u16 m_table_size{};
 | 
				
			||||||
    u16 m_max_count{};
 | 
					    u16 m_max_count{};
 | 
				
			||||||
    u16 m_next_linear_id{MinLinearId};
 | 
					    u16 m_next_linear_id{};
 | 
				
			||||||
    u16 m_count{};
 | 
					    u16 m_count{};
 | 
				
			||||||
    mutable KSpinLock m_lock;
 | 
					 | 
				
			||||||
    KernelCore& kernel;
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
} // namespace Kernel
 | 
					} // namespace Kernel
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user