committed by
FernandoS27
23 changed files with 212 additions and 80 deletions
-
2src/core/CMakeLists.txt
-
5src/core/hle/kernel/client_session.cpp
-
2src/core/hle/kernel/client_session.h
-
13src/core/hle/kernel/kernel.cpp
-
7src/core/hle/kernel/kernel.h
-
2src/core/hle/kernel/process.cpp
-
4src/core/hle/kernel/process.h
-
14src/core/hle/kernel/readable_event.cpp
-
6src/core/hle/kernel/readable_event.h
-
4src/core/hle/kernel/server_port.cpp
-
2src/core/hle/kernel/server_port.h
-
10src/core/hle/kernel/server_session.cpp
-
2src/core/hle/kernel/server_session.h
-
5src/core/hle/kernel/session.cpp
-
2src/core/hle/kernel/session.h
-
67src/core/hle/kernel/svc.cpp
-
86src/core/hle/kernel/synchronization.cpp
-
34src/core/hle/kernel/synchronization.h
-
5src/core/hle/kernel/synchronization_object.cpp
-
10src/core/hle/kernel/synchronization_object.h
-
6src/core/hle/kernel/thread.cpp
-
1src/core/hle/kernel/thread.h
-
3src/core/hle/kernel/writable_event.cpp
@ -0,0 +1,86 @@ |
|||
// 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/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
|
|||
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); |
|||
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, 0}; |
|||
} |
|||
|
|||
if (thread->IsSyncCancelled()) { |
|||
thread->SetSyncCancelled(false); |
|||
return {ERR_SYNCHRONIZATION_CANCELED, 0}; |
|||
} |
|||
|
|||
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, 0}; |
|||
} |
|||
|
|||
} // namespace Kernel
|
|||
@ -0,0 +1,34 @@ |
|||
// 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 "core/hle/kernel/object.h" |
|||
#include "core/hle/result.h" |
|||
|
|||
namespace Core { |
|||
class System; |
|||
} // namespace Core |
|||
|
|||
namespace Kernel { |
|||
|
|||
class KernelCore; |
|||
class SynchronizationObject; |
|||
|
|||
class Synchronization { |
|||
public: |
|||
Synchronization(Core::System& system); |
|||
|
|||
void SignalObject(SynchronizationObject& obj) const; |
|||
|
|||
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