Browse Source
Merge pull request #3401 from FernandoS27/synchronization
Merge pull request #3401 from FernandoS27/synchronization
Set of refactors for Kernel Synchronization and Hardware Constantsnce_cpp
committed by
GitHub
42 changed files with 434 additions and 227 deletions
-
6src/core/CMakeLists.txt
-
3src/core/arm/dynarmic/arm_dynarmic.cpp
-
3src/core/core_timing.cpp
-
18src/core/core_timing_util.cpp
-
12src/core/core_timing_util.h
-
5src/core/cpu_manager.h
-
45src/core/hardware_properties.h
-
7src/core/hle/kernel/client_session.cpp
-
6src/core/hle/kernel/client_session.h
-
20src/core/hle/kernel/hle_ipc.cpp
-
17src/core/hle/kernel/kernel.cpp
-
7src/core/hle/kernel/kernel.h
-
4src/core/hle/kernel/process.cpp
-
8src/core/hle/kernel/process.h
-
16src/core/hle/kernel/readable_event.cpp
-
10src/core/hle/kernel/readable_event.h
-
12src/core/hle/kernel/scheduler.cpp
-
13src/core/hle/kernel/scheduler.h
-
6src/core/hle/kernel/server_port.cpp
-
6src/core/hle/kernel/server_port.h
-
12src/core/hle/kernel/server_session.cpp
-
6src/core/hle/kernel/server_session.h
-
7src/core/hle/kernel/session.cpp
-
6src/core/hle/kernel/session.h
-
72src/core/hle/kernel/svc.cpp
-
87src/core/hle/kernel/synchronization.cpp
-
44src/core/hle/kernel/synchronization.h
-
28src/core/hle/kernel/synchronization_object.cpp
-
23src/core/hle/kernel/synchronization_object.h
-
37src/core/hle/kernel/thread.cpp
-
23src/core/hle/kernel/thread.h
-
3src/core/hle/kernel/writable_event.cpp
-
7src/core/hle/service/hid/hid.cpp
-
7src/core/hle/service/nvflinger/nvflinger.cpp
-
3src/core/hle/service/time/standard_steady_clock_core.cpp
-
3src/core/hle/service/time/tick_based_steady_clock_core.cpp
-
3src/core/hle/service/time/time.cpp
-
3src/core/hle/service/time/time_sharedmemory.cpp
-
3src/core/memory/cheat_engine.cpp
-
3src/core/tools/freezer.cpp
-
35src/yuzu/debugger/wait_tree.cpp
-
22src/yuzu/debugger/wait_tree.h
@ -0,0 +1,45 @@ |
|||
// Copyright 2020 yuzu Emulator Project |
|||
// Licensed under GPLv2 or any later version |
|||
// Refer to the license.txt file included. |
|||
|
|||
#pragma once |
|||
|
|||
#include <tuple> |
|||
|
|||
#include "common/common_types.h" |
|||
|
|||
namespace Core { |
|||
|
|||
namespace Hardware { |
|||
|
|||
// The below clock rate is based on Switch's clockspeed being widely known as 1.020GHz |
|||
// The exact value used is of course unverified. |
|||
constexpr u64 BASE_CLOCK_RATE = 1019215872; // Switch cpu frequency is 1020MHz un/docked |
|||
constexpr u64 CNTFREQ = 19200000; // Switch's hardware clock speed |
|||
constexpr u32 NUM_CPU_CORES = 4; // Number of CPU Cores |
|||
|
|||
} // namespace Hardware |
|||
|
|||
struct EmuThreadHandle { |
|||
u32 host_handle; |
|||
u32 guest_handle; |
|||
|
|||
u64 GetRaw() const { |
|||
return (static_cast<u64>(host_handle) << 32) | guest_handle; |
|||
} |
|||
|
|||
bool operator==(const EmuThreadHandle& rhs) const { |
|||
return std::tie(host_handle, guest_handle) == std::tie(rhs.host_handle, rhs.guest_handle); |
|||
} |
|||
|
|||
bool operator!=(const EmuThreadHandle& rhs) const { |
|||
return !operator==(rhs); |
|||
} |
|||
|
|||
static constexpr EmuThreadHandle InvalidHandle() { |
|||
constexpr u32 invalid_handle = 0xFFFFFFFF; |
|||
return {invalid_handle, invalid_handle}; |
|||
} |
|||
}; |
|||
|
|||
} // namespace Core |
|||
@ -0,0 +1,87 @@ |
|||
// Copyright 2020 yuzu Emulator Project
|
|||
// Licensed under GPLv2 or any later version
|
|||
// Refer to the license.txt file included.
|
|||
|
|||
#include "core/core.h"
|
|||
#include "core/hle/kernel/errors.h"
|
|||
#include "core/hle/kernel/handle_table.h"
|
|||
#include "core/hle/kernel/kernel.h"
|
|||
#include "core/hle/kernel/scheduler.h"
|
|||
#include "core/hle/kernel/synchronization.h"
|
|||
#include "core/hle/kernel/synchronization_object.h"
|
|||
#include "core/hle/kernel/thread.h"
|
|||
|
|||
namespace Kernel { |
|||
|
|||
/// Default thread wakeup callback for WaitSynchronization
|
|||
static bool DefaultThreadWakeupCallback(ThreadWakeupReason reason, std::shared_ptr<Thread> thread, |
|||
std::shared_ptr<SynchronizationObject> object, |
|||
std::size_t index) { |
|||
ASSERT(thread->GetStatus() == ThreadStatus::WaitSynch); |
|||
|
|||
if (reason == ThreadWakeupReason::Timeout) { |
|||
thread->SetWaitSynchronizationResult(RESULT_TIMEOUT); |
|||
return true; |
|||
} |
|||
|
|||
ASSERT(reason == ThreadWakeupReason::Signal); |
|||
thread->SetWaitSynchronizationResult(RESULT_SUCCESS); |
|||
thread->SetWaitSynchronizationOutput(static_cast<u32>(index)); |
|||
return true; |
|||
} |
|||
|
|||
Synchronization::Synchronization(Core::System& system) : system{system} {} |
|||
|
|||
void Synchronization::SignalObject(SynchronizationObject& obj) const { |
|||
if (obj.IsSignaled()) { |
|||
obj.WakeupAllWaitingThreads(); |
|||
} |
|||
} |
|||
|
|||
std::pair<ResultCode, Handle> Synchronization::WaitFor( |
|||
std::vector<std::shared_ptr<SynchronizationObject>>& sync_objects, s64 nano_seconds) { |
|||
auto* const thread = system.CurrentScheduler().GetCurrentThread(); |
|||
// Find the first object that is acquirable in the provided list of objects
|
|||
const auto itr = std::find_if(sync_objects.begin(), sync_objects.end(), |
|||
[thread](const std::shared_ptr<SynchronizationObject>& object) { |
|||
return object->IsSignaled(); |
|||
}); |
|||
|
|||
if (itr != sync_objects.end()) { |
|||
// We found a ready object, acquire it and set the result value
|
|||
SynchronizationObject* object = itr->get(); |
|||
object->Acquire(thread); |
|||
const u32 index = static_cast<s32>(std::distance(sync_objects.begin(), itr)); |
|||
return {RESULT_SUCCESS, index}; |
|||
} |
|||
|
|||
// No objects were ready to be acquired, prepare to suspend the thread.
|
|||
|
|||
// If a timeout value of 0 was provided, just return the Timeout error code instead of
|
|||
// suspending the thread.
|
|||
if (nano_seconds == 0) { |
|||
return {RESULT_TIMEOUT, InvalidHandle}; |
|||
} |
|||
|
|||
if (thread->IsSyncCancelled()) { |
|||
thread->SetSyncCancelled(false); |
|||
return {ERR_SYNCHRONIZATION_CANCELED, InvalidHandle}; |
|||
} |
|||
|
|||
for (auto& object : sync_objects) { |
|||
object->AddWaitingThread(SharedFrom(thread)); |
|||
} |
|||
|
|||
thread->SetSynchronizationObjects(std::move(sync_objects)); |
|||
thread->SetStatus(ThreadStatus::WaitSynch); |
|||
|
|||
// Create an event to wake the thread up after the specified nanosecond delay has passed
|
|||
thread->WakeAfterDelay(nano_seconds); |
|||
thread->SetWakeupCallback(DefaultThreadWakeupCallback); |
|||
|
|||
system.PrepareReschedule(thread->GetProcessorID()); |
|||
|
|||
return {RESULT_TIMEOUT, InvalidHandle}; |
|||
} |
|||
|
|||
} // namespace Kernel
|
|||
@ -0,0 +1,44 @@ |
|||
// Copyright 2020 yuzu Emulator Project |
|||
// Licensed under GPLv2 or any later version |
|||
// Refer to the license.txt file included. |
|||
|
|||
#pragma once |
|||
|
|||
#include <memory> |
|||
#include <utility> |
|||
#include <vector> |
|||
|
|||
#include "core/hle/kernel/object.h" |
|||
#include "core/hle/result.h" |
|||
|
|||
namespace Core { |
|||
class System; |
|||
} // namespace Core |
|||
|
|||
namespace Kernel { |
|||
|
|||
class SynchronizationObject; |
|||
|
|||
/** |
|||
* The 'Synchronization' class is an interface for handling synchronization methods |
|||
* used by Synchronization objects and synchronization SVCs. This centralizes processing of |
|||
* such |
|||
*/ |
|||
class Synchronization { |
|||
public: |
|||
explicit Synchronization(Core::System& system); |
|||
|
|||
/// Signals a synchronization object, waking up all its waiting threads |
|||
void SignalObject(SynchronizationObject& obj) const; |
|||
|
|||
/// Tries to see if waiting for any of the sync_objects is necessary, if not |
|||
/// it returns Success and the handle index of the signaled sync object. In |
|||
/// case not, the current thread will be locked and wait for nano_seconds or |
|||
/// for a synchronization object to signal. |
|||
std::pair<ResultCode, Handle> WaitFor( |
|||
std::vector<std::shared_ptr<SynchronizationObject>>& sync_objects, s64 nano_seconds); |
|||
|
|||
private: |
|||
Core::System& system; |
|||
}; |
|||
} // namespace Kernel |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue