mirror of
				https://git.suyu.dev/suyu/suyu
				synced 2025-11-04 00:49:02 -06:00 
			
		
		
		
	kernel: split SetAddressKey into user and kernel variants
This commit is contained in:
		@@ -171,7 +171,7 @@ Result KConditionVariable::WaitForAddress(Handle handle, VAddr addr, u32 value)
 | 
			
		||||
        R_UNLESS(owner_thread != nullptr, ResultInvalidHandle);
 | 
			
		||||
 | 
			
		||||
        // Update the lock.
 | 
			
		||||
        cur_thread->SetAddressKey(addr, value);
 | 
			
		||||
        cur_thread->SetUserAddressKey(addr, value);
 | 
			
		||||
        owner_thread->AddWaiter(cur_thread);
 | 
			
		||||
 | 
			
		||||
        // Begin waiting.
 | 
			
		||||
 
 | 
			
		||||
@@ -68,7 +68,7 @@ bool KLightLock::LockSlowPath(uintptr_t _owner, uintptr_t _cur_thread) {
 | 
			
		||||
 | 
			
		||||
        // Add the current thread as a waiter on the owner.
 | 
			
		||||
        KThread* owner_thread = reinterpret_cast<KThread*>(_owner & ~1ULL);
 | 
			
		||||
        cur_thread->SetAddressKey(reinterpret_cast<uintptr_t>(std::addressof(tag)));
 | 
			
		||||
        cur_thread->SetKernelAddressKey(reinterpret_cast<uintptr_t>(std::addressof(tag)));
 | 
			
		||||
        owner_thread->AddWaiter(cur_thread);
 | 
			
		||||
 | 
			
		||||
        // Begin waiting to hold the lock.
 | 
			
		||||
 
 | 
			
		||||
@@ -67,9 +67,9 @@ constexpr size_t KernelPageBufferAdditionalSize = 0x33C000;
 | 
			
		||||
constexpr std::size_t KernelResourceSize = KernelPageTableHeapSize + KernelInitialPageHeapSize +
 | 
			
		||||
                                           KernelSlabHeapSize + KernelPageBufferHeapSize;
 | 
			
		||||
 | 
			
		||||
constexpr bool IsKernelAddressKey(VAddr key) {
 | 
			
		||||
    return KernelVirtualAddressSpaceBase <= key && key <= KernelVirtualAddressSpaceLast;
 | 
			
		||||
}
 | 
			
		||||
//! NB: Use KThread::GetAddressKeyIsKernel().
 | 
			
		||||
//! See explanation for deviation of GetAddressKey.
 | 
			
		||||
bool IsKernelAddressKey(VAddr key) = delete;
 | 
			
		||||
 | 
			
		||||
constexpr bool IsKernelAddress(VAddr address) {
 | 
			
		||||
    return KernelVirtualAddressSpaceBase <= address && address < KernelVirtualAddressSpaceEnd;
 | 
			
		||||
 
 | 
			
		||||
@@ -330,7 +330,7 @@ void KThread::Finalize() {
 | 
			
		||||
            KThread* const waiter = std::addressof(*it);
 | 
			
		||||
 | 
			
		||||
            // The thread shouldn't be a kernel waiter.
 | 
			
		||||
            ASSERT(!IsKernelAddressKey(waiter->GetAddressKey()));
 | 
			
		||||
            ASSERT(!waiter->GetAddressKeyIsKernel());
 | 
			
		||||
 | 
			
		||||
            // Clear the lock owner.
 | 
			
		||||
            waiter->SetLockOwner(nullptr);
 | 
			
		||||
@@ -884,7 +884,7 @@ void KThread::AddWaiterImpl(KThread* thread) {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Keep track of how many kernel waiters we have.
 | 
			
		||||
    if (IsKernelAddressKey(thread->GetAddressKey())) {
 | 
			
		||||
    if (thread->GetAddressKeyIsKernel()) {
 | 
			
		||||
        ASSERT((num_kernel_waiters++) >= 0);
 | 
			
		||||
        KScheduler::SetSchedulerUpdateNeeded(kernel);
 | 
			
		||||
    }
 | 
			
		||||
@@ -898,7 +898,7 @@ void KThread::RemoveWaiterImpl(KThread* thread) {
 | 
			
		||||
    ASSERT(kernel.GlobalSchedulerContext().IsLocked());
 | 
			
		||||
 | 
			
		||||
    // Keep track of how many kernel waiters we have.
 | 
			
		||||
    if (IsKernelAddressKey(thread->GetAddressKey())) {
 | 
			
		||||
    if (thread->GetAddressKeyIsKernel()) {
 | 
			
		||||
        ASSERT((num_kernel_waiters--) > 0);
 | 
			
		||||
        KScheduler::SetSchedulerUpdateNeeded(kernel);
 | 
			
		||||
    }
 | 
			
		||||
@@ -974,7 +974,7 @@ KThread* KThread::RemoveWaiterByKey(s32* out_num_waiters, VAddr key) {
 | 
			
		||||
            KThread* thread = std::addressof(*it);
 | 
			
		||||
 | 
			
		||||
            // Keep track of how many kernel waiters we have.
 | 
			
		||||
            if (IsKernelAddressKey(thread->GetAddressKey())) {
 | 
			
		||||
            if (thread->GetAddressKeyIsKernel()) {
 | 
			
		||||
                ASSERT((num_kernel_waiters--) > 0);
 | 
			
		||||
                KScheduler::SetSchedulerUpdateNeeded(kernel);
 | 
			
		||||
            }
 | 
			
		||||
 
 | 
			
		||||
@@ -605,13 +605,30 @@ public:
 | 
			
		||||
        return address_key_value;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void SetAddressKey(VAddr key) {
 | 
			
		||||
        address_key = key;
 | 
			
		||||
    [[nodiscard]] bool GetAddressKeyIsKernel() const {
 | 
			
		||||
        return address_key_is_kernel;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void SetAddressKey(VAddr key, u32 val) {
 | 
			
		||||
    //! NB: intentional deviation from official kernel.
 | 
			
		||||
    //
 | 
			
		||||
    // Separate SetAddressKey into user and kernel versions
 | 
			
		||||
    // to cope with arbitrary host pointers making their way
 | 
			
		||||
    // into things.
 | 
			
		||||
 | 
			
		||||
    void SetUserAddressKey(VAddr key) {
 | 
			
		||||
        address_key = key;
 | 
			
		||||
        address_key_is_kernel = false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void SetUserAddressKey(VAddr key, u32 val) {
 | 
			
		||||
        address_key = key;
 | 
			
		||||
        address_key_value = val;
 | 
			
		||||
        address_key_is_kernel = false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void SetKernelAddressKey(VAddr key) {
 | 
			
		||||
        address_key = key;
 | 
			
		||||
        address_key_is_kernel = true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void ClearWaitQueue() {
 | 
			
		||||
@@ -770,6 +787,7 @@ private:
 | 
			
		||||
    bool debug_attached{};
 | 
			
		||||
    s8 priority_inheritance_count{};
 | 
			
		||||
    bool resource_limit_release_hint{};
 | 
			
		||||
    bool address_key_is_kernel{};
 | 
			
		||||
    StackParameters stack_parameters{};
 | 
			
		||||
    Common::SpinLock context_guard{};
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user