mirror of
				https://git.zaroz.cloud/nintendo-back-up/yuzu/yuzu-mainline.git
				synced 2025-03-21 01:53:15 +00:00 
			
		
		
		
	Kernel: Move WaitObject to a separate file
Now that HandleTable doesn't directly depend on WaitObject anymore, this can be separated from the main kernel.h header.
This commit is contained in:
		
							parent
							
								
									9453223075
								
							
						
					
					
						commit
						64ecf81a3c
					
				@ -10,6 +10,7 @@
 | 
			
		||||
#include "core/hle/kernel/semaphore.h"
 | 
			
		||||
#include "core/hle/kernel/thread.h"
 | 
			
		||||
#include "core/hle/kernel/timer.h"
 | 
			
		||||
#include "core/hle/kernel/wait_object.h"
 | 
			
		||||
 | 
			
		||||
WaitTreeItem::~WaitTreeItem() {}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -4,12 +4,10 @@
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include <boost/container/flat_set.hpp>
 | 
			
		||||
 | 
			
		||||
#include <QAbstractItemModel>
 | 
			
		||||
#include <QDockWidget>
 | 
			
		||||
#include <QTreeView>
 | 
			
		||||
 | 
			
		||||
#include <boost/container/flat_set.hpp>
 | 
			
		||||
#include "core/core.h"
 | 
			
		||||
#include "core/hle/kernel/kernel.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -57,6 +57,7 @@ set(SRCS
 | 
			
		||||
            hle/kernel/thread.cpp
 | 
			
		||||
            hle/kernel/timer.cpp
 | 
			
		||||
            hle/kernel/vm_manager.cpp
 | 
			
		||||
            hle/kernel/wait_object.cpp
 | 
			
		||||
            hle/service/ac/ac.cpp
 | 
			
		||||
            hle/service/ac/ac_i.cpp
 | 
			
		||||
            hle/service/ac/ac_u.cpp
 | 
			
		||||
@ -249,6 +250,7 @@ set(HEADERS
 | 
			
		||||
            hle/kernel/thread.h
 | 
			
		||||
            hle/kernel/timer.h
 | 
			
		||||
            hle/kernel/vm_manager.h
 | 
			
		||||
            hle/kernel/wait_object.h
 | 
			
		||||
            hle/result.h
 | 
			
		||||
            hle/service/ac/ac.h
 | 
			
		||||
            hle/service/ac/ac_i.h
 | 
			
		||||
 | 
			
		||||
@ -6,6 +6,7 @@
 | 
			
		||||
 | 
			
		||||
#include "common/common_types.h"
 | 
			
		||||
#include "core/hle/kernel/kernel.h"
 | 
			
		||||
#include "core/hle/kernel/wait_object.h"
 | 
			
		||||
 | 
			
		||||
namespace Kernel {
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -20,85 +20,6 @@ namespace Kernel {
 | 
			
		||||
unsigned int Object::next_object_id;
 | 
			
		||||
HandleTable g_handle_table;
 | 
			
		||||
 | 
			
		||||
void WaitObject::AddWaitingThread(SharedPtr<Thread> thread) {
 | 
			
		||||
    auto itr = std::find(waiting_threads.begin(), waiting_threads.end(), thread);
 | 
			
		||||
    if (itr == waiting_threads.end())
 | 
			
		||||
        waiting_threads.push_back(std::move(thread));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void WaitObject::RemoveWaitingThread(Thread* thread) {
 | 
			
		||||
    auto itr = std::find(waiting_threads.begin(), waiting_threads.end(), thread);
 | 
			
		||||
    // If a thread passed multiple handles to the same object,
 | 
			
		||||
    // the kernel might attempt to remove the thread from the object's
 | 
			
		||||
    // waiting threads list multiple times.
 | 
			
		||||
    if (itr != waiting_threads.end())
 | 
			
		||||
        waiting_threads.erase(itr);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
SharedPtr<Thread> WaitObject::GetHighestPriorityReadyThread() {
 | 
			
		||||
    Thread* candidate = nullptr;
 | 
			
		||||
    s32 candidate_priority = THREADPRIO_LOWEST + 1;
 | 
			
		||||
 | 
			
		||||
    for (const auto& thread : waiting_threads) {
 | 
			
		||||
        // The list of waiting threads must not contain threads that are not waiting to be awakened.
 | 
			
		||||
        ASSERT_MSG(thread->status == THREADSTATUS_WAIT_SYNCH_ANY ||
 | 
			
		||||
                       thread->status == THREADSTATUS_WAIT_SYNCH_ALL,
 | 
			
		||||
                   "Inconsistent thread statuses in waiting_threads");
 | 
			
		||||
 | 
			
		||||
        if (thread->current_priority >= candidate_priority)
 | 
			
		||||
            continue;
 | 
			
		||||
 | 
			
		||||
        if (ShouldWait(thread.get()))
 | 
			
		||||
            continue;
 | 
			
		||||
 | 
			
		||||
        // A thread is ready to run if it's either in THREADSTATUS_WAIT_SYNCH_ANY or
 | 
			
		||||
        // in THREADSTATUS_WAIT_SYNCH_ALL and the rest of the objects it is waiting on are ready.
 | 
			
		||||
        bool ready_to_run = true;
 | 
			
		||||
        if (thread->status == THREADSTATUS_WAIT_SYNCH_ALL) {
 | 
			
		||||
            ready_to_run = std::none_of(thread->wait_objects.begin(), thread->wait_objects.end(),
 | 
			
		||||
                                        [&thread](const SharedPtr<WaitObject>& object) {
 | 
			
		||||
                                            return object->ShouldWait(thread.get());
 | 
			
		||||
                                        });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (ready_to_run) {
 | 
			
		||||
            candidate = thread.get();
 | 
			
		||||
            candidate_priority = thread->current_priority;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return candidate;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void WaitObject::WakeupAllWaitingThreads() {
 | 
			
		||||
    while (auto thread = GetHighestPriorityReadyThread()) {
 | 
			
		||||
        if (!thread->IsSleepingOnWaitAll()) {
 | 
			
		||||
            Acquire(thread.get());
 | 
			
		||||
            // Set the output index of the WaitSynchronizationN call to the index of this object.
 | 
			
		||||
            if (thread->wait_set_output) {
 | 
			
		||||
                thread->SetWaitSynchronizationOutput(thread->GetWaitObjectIndex(this));
 | 
			
		||||
                thread->wait_set_output = false;
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            for (auto& object : thread->wait_objects) {
 | 
			
		||||
                object->Acquire(thread.get());
 | 
			
		||||
            }
 | 
			
		||||
            // Note: This case doesn't update the output index of WaitSynchronizationN.
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        for (auto& object : thread->wait_objects)
 | 
			
		||||
            object->RemoveWaitingThread(thread.get());
 | 
			
		||||
        thread->wait_objects.clear();
 | 
			
		||||
 | 
			
		||||
        thread->SetWaitSynchronizationResult(RESULT_SUCCESS);
 | 
			
		||||
        thread->ResumeFromWait();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const std::vector<SharedPtr<Thread>>& WaitObject::GetWaitingThreads() const {
 | 
			
		||||
    return waiting_threads;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
HandleTable::HandleTable() {
 | 
			
		||||
    next_generation = 1;
 | 
			
		||||
    Clear();
 | 
			
		||||
 | 
			
		||||
@ -17,8 +17,6 @@ namespace Kernel {
 | 
			
		||||
 | 
			
		||||
using Handle = u32;
 | 
			
		||||
 | 
			
		||||
class Thread;
 | 
			
		||||
 | 
			
		||||
enum KernelHandle : Handle {
 | 
			
		||||
    CurrentThread = 0xFFFF8000,
 | 
			
		||||
    CurrentProcess = 0xFFFF8001,
 | 
			
		||||
@ -133,57 +131,6 @@ inline SharedPtr<T> DynamicObjectCast(SharedPtr<Object> object) {
 | 
			
		||||
    return nullptr;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Class that represents a Kernel object that a thread can be waiting on
 | 
			
		||||
class WaitObject : public Object {
 | 
			
		||||
public:
 | 
			
		||||
    /**
 | 
			
		||||
     * Check if the specified thread should wait until the object is available
 | 
			
		||||
     * @param thread The thread about which we're deciding.
 | 
			
		||||
     * @return True if the current thread should wait due to this object being unavailable
 | 
			
		||||
     */
 | 
			
		||||
    virtual bool ShouldWait(Thread* thread) const = 0;
 | 
			
		||||
 | 
			
		||||
    /// Acquire/lock the object for the specified thread if it is available
 | 
			
		||||
    virtual void Acquire(Thread* thread) = 0;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Add a thread to wait on this object
 | 
			
		||||
     * @param thread Pointer to thread to add
 | 
			
		||||
     */
 | 
			
		||||
    virtual void AddWaitingThread(SharedPtr<Thread> thread);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Removes a thread from waiting on this object (e.g. if it was resumed already)
 | 
			
		||||
     * @param thread Pointer to thread to remove
 | 
			
		||||
     */
 | 
			
		||||
    virtual void RemoveWaitingThread(Thread* thread);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Wake up all threads waiting on this object that can be awoken, in priority order,
 | 
			
		||||
     * and set the synchronization result and output of the thread.
 | 
			
		||||
     */
 | 
			
		||||
    virtual void WakeupAllWaitingThreads();
 | 
			
		||||
 | 
			
		||||
    /// Obtains the highest priority thread that is ready to run from this object's waiting list.
 | 
			
		||||
    SharedPtr<Thread> GetHighestPriorityReadyThread();
 | 
			
		||||
 | 
			
		||||
    /// Get a const reference to the waiting threads list for debug use
 | 
			
		||||
    const std::vector<SharedPtr<Thread>>& GetWaitingThreads() const;
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    /// Threads waiting for this object to become available
 | 
			
		||||
    std::vector<SharedPtr<Thread>> waiting_threads;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Specialization of DynamicObjectCast for WaitObjects
 | 
			
		||||
template <>
 | 
			
		||||
inline SharedPtr<WaitObject> DynamicObjectCast<WaitObject>(SharedPtr<Object> object) {
 | 
			
		||||
    if (object != nullptr && object->IsWaitable()) {
 | 
			
		||||
        return boost::static_pointer_cast<WaitObject>(std::move(object));
 | 
			
		||||
    }
 | 
			
		||||
    return nullptr;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * This class allows the creation of Handles, which are references to objects that can be tested
 | 
			
		||||
 * for validity and looked up. Here they are used to pass references to kernel objects to/from the
 | 
			
		||||
 | 
			
		||||
@ -7,6 +7,7 @@
 | 
			
		||||
#include <string>
 | 
			
		||||
#include "common/common_types.h"
 | 
			
		||||
#include "core/hle/kernel/kernel.h"
 | 
			
		||||
#include "core/hle/kernel/wait_object.h"
 | 
			
		||||
 | 
			
		||||
namespace Kernel {
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -8,6 +8,7 @@
 | 
			
		||||
#include <string>
 | 
			
		||||
#include "common/common_types.h"
 | 
			
		||||
#include "core/hle/kernel/kernel.h"
 | 
			
		||||
#include "core/hle/kernel/wait_object.h"
 | 
			
		||||
 | 
			
		||||
namespace Kernel {
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -9,6 +9,7 @@
 | 
			
		||||
#include <tuple>
 | 
			
		||||
#include "common/common_types.h"
 | 
			
		||||
#include "core/hle/kernel/kernel.h"
 | 
			
		||||
#include "core/hle/kernel/wait_object.h"
 | 
			
		||||
 | 
			
		||||
namespace Service {
 | 
			
		||||
class SessionRequestHandler;
 | 
			
		||||
 | 
			
		||||
@ -11,6 +11,7 @@
 | 
			
		||||
#include "core/hle/kernel/kernel.h"
 | 
			
		||||
#include "core/hle/kernel/session.h"
 | 
			
		||||
#include "core/hle/kernel/thread.h"
 | 
			
		||||
#include "core/hle/kernel/wait_object.h"
 | 
			
		||||
#include "core/hle/result.h"
 | 
			
		||||
#include "core/hle/service/service.h"
 | 
			
		||||
#include "core/memory.h"
 | 
			
		||||
 | 
			
		||||
@ -12,6 +12,7 @@
 | 
			
		||||
#include "common/common_types.h"
 | 
			
		||||
#include "core/arm/arm_interface.h"
 | 
			
		||||
#include "core/hle/kernel/kernel.h"
 | 
			
		||||
#include "core/hle/kernel/wait_object.h"
 | 
			
		||||
#include "core/hle/result.h"
 | 
			
		||||
 | 
			
		||||
enum ThreadPriority : s32 {
 | 
			
		||||
 | 
			
		||||
@ -6,6 +6,7 @@
 | 
			
		||||
 | 
			
		||||
#include "common/common_types.h"
 | 
			
		||||
#include "core/hle/kernel/kernel.h"
 | 
			
		||||
#include "core/hle/kernel/wait_object.h"
 | 
			
		||||
 | 
			
		||||
namespace Kernel {
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										99
									
								
								src/core/hle/kernel/wait_object.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										99
									
								
								src/core/hle/kernel/wait_object.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,99 @@
 | 
			
		||||
// Copyright 2014 Citra Emulator Project
 | 
			
		||||
// Licensed under GPLv2 or any later version
 | 
			
		||||
// Refer to the license.txt file included.
 | 
			
		||||
 | 
			
		||||
#include <algorithm>
 | 
			
		||||
#include "common/assert.h"
 | 
			
		||||
#include "common/logging/log.h"
 | 
			
		||||
#include "core/hle/config_mem.h"
 | 
			
		||||
#include "core/hle/kernel/errors.h"
 | 
			
		||||
#include "core/hle/kernel/kernel.h"
 | 
			
		||||
#include "core/hle/kernel/memory.h"
 | 
			
		||||
#include "core/hle/kernel/process.h"
 | 
			
		||||
#include "core/hle/kernel/resource_limit.h"
 | 
			
		||||
#include "core/hle/kernel/thread.h"
 | 
			
		||||
#include "core/hle/kernel/timer.h"
 | 
			
		||||
#include "core/hle/shared_page.h"
 | 
			
		||||
 | 
			
		||||
namespace Kernel {
 | 
			
		||||
 | 
			
		||||
void WaitObject::AddWaitingThread(SharedPtr<Thread> thread) {
 | 
			
		||||
    auto itr = std::find(waiting_threads.begin(), waiting_threads.end(), thread);
 | 
			
		||||
    if (itr == waiting_threads.end())
 | 
			
		||||
        waiting_threads.push_back(std::move(thread));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void WaitObject::RemoveWaitingThread(Thread* thread) {
 | 
			
		||||
    auto itr = std::find(waiting_threads.begin(), waiting_threads.end(), thread);
 | 
			
		||||
    // If a thread passed multiple handles to the same object,
 | 
			
		||||
    // the kernel might attempt to remove the thread from the object's
 | 
			
		||||
    // waiting threads list multiple times.
 | 
			
		||||
    if (itr != waiting_threads.end())
 | 
			
		||||
        waiting_threads.erase(itr);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
SharedPtr<Thread> WaitObject::GetHighestPriorityReadyThread() {
 | 
			
		||||
    Thread* candidate = nullptr;
 | 
			
		||||
    s32 candidate_priority = THREADPRIO_LOWEST + 1;
 | 
			
		||||
 | 
			
		||||
    for (const auto& thread : waiting_threads) {
 | 
			
		||||
        // The list of waiting threads must not contain threads that are not waiting to be awakened.
 | 
			
		||||
        ASSERT_MSG(thread->status == THREADSTATUS_WAIT_SYNCH_ANY ||
 | 
			
		||||
                       thread->status == THREADSTATUS_WAIT_SYNCH_ALL,
 | 
			
		||||
                   "Inconsistent thread statuses in waiting_threads");
 | 
			
		||||
 | 
			
		||||
        if (thread->current_priority >= candidate_priority)
 | 
			
		||||
            continue;
 | 
			
		||||
 | 
			
		||||
        if (ShouldWait(thread.get()))
 | 
			
		||||
            continue;
 | 
			
		||||
 | 
			
		||||
        // A thread is ready to run if it's either in THREADSTATUS_WAIT_SYNCH_ANY or
 | 
			
		||||
        // in THREADSTATUS_WAIT_SYNCH_ALL and the rest of the objects it is waiting on are ready.
 | 
			
		||||
        bool ready_to_run = true;
 | 
			
		||||
        if (thread->status == THREADSTATUS_WAIT_SYNCH_ALL) {
 | 
			
		||||
            ready_to_run = std::none_of(thread->wait_objects.begin(), thread->wait_objects.end(),
 | 
			
		||||
                                        [&thread](const SharedPtr<WaitObject>& object) {
 | 
			
		||||
                                            return object->ShouldWait(thread.get());
 | 
			
		||||
                                        });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (ready_to_run) {
 | 
			
		||||
            candidate = thread.get();
 | 
			
		||||
            candidate_priority = thread->current_priority;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return candidate;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void WaitObject::WakeupAllWaitingThreads() {
 | 
			
		||||
    while (auto thread = GetHighestPriorityReadyThread()) {
 | 
			
		||||
        if (!thread->IsSleepingOnWaitAll()) {
 | 
			
		||||
            Acquire(thread.get());
 | 
			
		||||
            // Set the output index of the WaitSynchronizationN call to the index of this object.
 | 
			
		||||
            if (thread->wait_set_output) {
 | 
			
		||||
                thread->SetWaitSynchronizationOutput(thread->GetWaitObjectIndex(this));
 | 
			
		||||
                thread->wait_set_output = false;
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            for (auto& object : thread->wait_objects) {
 | 
			
		||||
                object->Acquire(thread.get());
 | 
			
		||||
            }
 | 
			
		||||
            // Note: This case doesn't update the output index of WaitSynchronizationN.
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        for (auto& object : thread->wait_objects)
 | 
			
		||||
            object->RemoveWaitingThread(thread.get());
 | 
			
		||||
        thread->wait_objects.clear();
 | 
			
		||||
 | 
			
		||||
        thread->SetWaitSynchronizationResult(RESULT_SUCCESS);
 | 
			
		||||
        thread->ResumeFromWait();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const std::vector<SharedPtr<Thread>>& WaitObject::GetWaitingThreads() const {
 | 
			
		||||
    return waiting_threads;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // namespace Kernel
 | 
			
		||||
							
								
								
									
										67
									
								
								src/core/hle/kernel/wait_object.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								src/core/hle/kernel/wait_object.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,67 @@
 | 
			
		||||
// Copyright 2014 Citra Emulator Project
 | 
			
		||||
// Licensed under GPLv2 or any later version
 | 
			
		||||
// Refer to the license.txt file included.
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include <vector>
 | 
			
		||||
#include <boost/smart_ptr/intrusive_ptr.hpp>
 | 
			
		||||
#include "common/common_types.h"
 | 
			
		||||
#include "core/hle/kernel/kernel.h"
 | 
			
		||||
 | 
			
		||||
namespace Kernel {
 | 
			
		||||
 | 
			
		||||
class Thread;
 | 
			
		||||
 | 
			
		||||
/// Class that represents a Kernel object that a thread can be waiting on
 | 
			
		||||
class WaitObject : public Object {
 | 
			
		||||
public:
 | 
			
		||||
    /**
 | 
			
		||||
     * Check if the specified thread should wait until the object is available
 | 
			
		||||
     * @param thread The thread about which we're deciding.
 | 
			
		||||
     * @return True if the current thread should wait due to this object being unavailable
 | 
			
		||||
     */
 | 
			
		||||
    virtual bool ShouldWait(Thread* thread) const = 0;
 | 
			
		||||
 | 
			
		||||
    /// Acquire/lock the object for the specified thread if it is available
 | 
			
		||||
    virtual void Acquire(Thread* thread) = 0;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Add a thread to wait on this object
 | 
			
		||||
     * @param thread Pointer to thread to add
 | 
			
		||||
     */
 | 
			
		||||
    virtual void AddWaitingThread(SharedPtr<Thread> thread);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Removes a thread from waiting on this object (e.g. if it was resumed already)
 | 
			
		||||
     * @param thread Pointer to thread to remove
 | 
			
		||||
     */
 | 
			
		||||
    virtual void RemoveWaitingThread(Thread* thread);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Wake up all threads waiting on this object that can be awoken, in priority order,
 | 
			
		||||
     * and set the synchronization result and output of the thread.
 | 
			
		||||
     */
 | 
			
		||||
    virtual void WakeupAllWaitingThreads();
 | 
			
		||||
 | 
			
		||||
    /// Obtains the highest priority thread that is ready to run from this object's waiting list.
 | 
			
		||||
    SharedPtr<Thread> GetHighestPriorityReadyThread();
 | 
			
		||||
 | 
			
		||||
    /// Get a const reference to the waiting threads list for debug use
 | 
			
		||||
    const std::vector<SharedPtr<Thread>>& GetWaitingThreads() const;
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    /// Threads waiting for this object to become available
 | 
			
		||||
    std::vector<SharedPtr<Thread>> waiting_threads;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Specialization of DynamicObjectCast for WaitObjects
 | 
			
		||||
template <>
 | 
			
		||||
inline SharedPtr<WaitObject> DynamicObjectCast<WaitObject>(SharedPtr<Object> object) {
 | 
			
		||||
    if (object != nullptr && object->IsWaitable()) {
 | 
			
		||||
        return boost::static_pointer_cast<WaitObject>(std::move(object));
 | 
			
		||||
    }
 | 
			
		||||
    return nullptr;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // namespace Kernel
 | 
			
		||||
@ -27,6 +27,7 @@
 | 
			
		||||
#include "core/hle/kernel/thread.h"
 | 
			
		||||
#include "core/hle/kernel/timer.h"
 | 
			
		||||
#include "core/hle/kernel/vm_manager.h"
 | 
			
		||||
#include "core/hle/kernel/wait_object.h"
 | 
			
		||||
#include "core/hle/result.h"
 | 
			
		||||
#include "core/hle/service/service.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user