forked from ShuriZma/suyu
kernel: Rename Semaphore to ConditionVariable.
This commit is contained in:
parent
9fcd2bf672
commit
4236799832
|
@ -5,9 +5,9 @@
|
||||||
#include "citra_qt/debugger/wait_tree.h"
|
#include "citra_qt/debugger/wait_tree.h"
|
||||||
#include "citra_qt/util/util.h"
|
#include "citra_qt/util/util.h"
|
||||||
|
|
||||||
|
#include "core/hle/kernel/condition_variable.h"
|
||||||
#include "core/hle/kernel/event.h"
|
#include "core/hle/kernel/event.h"
|
||||||
#include "core/hle/kernel/mutex.h"
|
#include "core/hle/kernel/mutex.h"
|
||||||
#include "core/hle/kernel/semaphore.h"
|
|
||||||
#include "core/hle/kernel/thread.h"
|
#include "core/hle/kernel/thread.h"
|
||||||
#include "core/hle/kernel/timer.h"
|
#include "core/hle/kernel/timer.h"
|
||||||
#include "core/hle/kernel/wait_object.h"
|
#include "core/hle/kernel/wait_object.h"
|
||||||
|
@ -85,8 +85,9 @@ std::unique_ptr<WaitTreeWaitObject> WaitTreeWaitObject::make(const Kernel::WaitO
|
||||||
return std::make_unique<WaitTreeEvent>(static_cast<const Kernel::Event&>(object));
|
return std::make_unique<WaitTreeEvent>(static_cast<const Kernel::Event&>(object));
|
||||||
case Kernel::HandleType::Mutex:
|
case Kernel::HandleType::Mutex:
|
||||||
return std::make_unique<WaitTreeMutex>(static_cast<const Kernel::Mutex&>(object));
|
return std::make_unique<WaitTreeMutex>(static_cast<const Kernel::Mutex&>(object));
|
||||||
case Kernel::HandleType::Semaphore:
|
case Kernel::HandleType::ConditionVariable:
|
||||||
return std::make_unique<WaitTreeSemaphore>(static_cast<const Kernel::Semaphore&>(object));
|
return std::make_unique<WaitTreeConditionVariable>(
|
||||||
|
static_cast<const Kernel::ConditionVariable&>(object));
|
||||||
case Kernel::HandleType::Timer:
|
case Kernel::HandleType::Timer:
|
||||||
return std::make_unique<WaitTreeTimer>(static_cast<const Kernel::Timer&>(object));
|
return std::make_unique<WaitTreeTimer>(static_cast<const Kernel::Timer&>(object));
|
||||||
case Kernel::HandleType::Thread:
|
case Kernel::HandleType::Thread:
|
||||||
|
@ -266,15 +267,15 @@ std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeMutex::GetChildren() const {
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
WaitTreeSemaphore::WaitTreeSemaphore(const Kernel::Semaphore& object)
|
WaitTreeConditionVariable::WaitTreeConditionVariable(const Kernel::ConditionVariable& object)
|
||||||
: WaitTreeWaitObject(object) {}
|
: WaitTreeWaitObject(object) {}
|
||||||
|
|
||||||
std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeSemaphore::GetChildren() const {
|
std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeConditionVariable::GetChildren() const {
|
||||||
std::vector<std::unique_ptr<WaitTreeItem>> list(WaitTreeWaitObject::GetChildren());
|
std::vector<std::unique_ptr<WaitTreeItem>> list(WaitTreeWaitObject::GetChildren());
|
||||||
|
|
||||||
const auto& semaphore = static_cast<const Kernel::Semaphore&>(object);
|
const auto& condition_variable = static_cast<const Kernel::ConditionVariable&>(object);
|
||||||
list.push_back(std::make_unique<WaitTreeText>(
|
list.push_back(std::make_unique<WaitTreeText>(
|
||||||
tr("available count = %1").arg(semaphore.GetAvailableCount())));
|
tr("available count = %1").arg(condition_variable.GetAvailableCount())));
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ namespace Kernel {
|
||||||
class WaitObject;
|
class WaitObject;
|
||||||
class Event;
|
class Event;
|
||||||
class Mutex;
|
class Mutex;
|
||||||
class Semaphore;
|
class ConditionVariable;
|
||||||
class Thread;
|
class Thread;
|
||||||
class Timer;
|
class Timer;
|
||||||
}
|
}
|
||||||
|
@ -111,10 +111,10 @@ public:
|
||||||
std::vector<std::unique_ptr<WaitTreeItem>> GetChildren() const override;
|
std::vector<std::unique_ptr<WaitTreeItem>> GetChildren() const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class WaitTreeSemaphore : public WaitTreeWaitObject {
|
class WaitTreeConditionVariable : public WaitTreeWaitObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit WaitTreeSemaphore(const Kernel::Semaphore& object);
|
explicit WaitTreeConditionVariable(const Kernel::ConditionVariable& object);
|
||||||
std::vector<std::unique_ptr<WaitTreeItem>> GetChildren() const override;
|
std::vector<std::unique_ptr<WaitTreeItem>> GetChildren() const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,7 @@ set(SRCS
|
||||||
hle/kernel/address_arbiter.cpp
|
hle/kernel/address_arbiter.cpp
|
||||||
hle/kernel/client_port.cpp
|
hle/kernel/client_port.cpp
|
||||||
hle/kernel/client_session.cpp
|
hle/kernel/client_session.cpp
|
||||||
|
hle/kernel/condition_variable.cpp
|
||||||
hle/kernel/domain.cpp
|
hle/kernel/domain.cpp
|
||||||
hle/kernel/event.cpp
|
hle/kernel/event.cpp
|
||||||
hle/kernel/handle_table.cpp
|
hle/kernel/handle_table.cpp
|
||||||
|
@ -26,7 +27,6 @@ set(SRCS
|
||||||
hle/kernel/object_address_table.cpp
|
hle/kernel/object_address_table.cpp
|
||||||
hle/kernel/process.cpp
|
hle/kernel/process.cpp
|
||||||
hle/kernel/resource_limit.cpp
|
hle/kernel/resource_limit.cpp
|
||||||
hle/kernel/semaphore.cpp
|
|
||||||
hle/kernel/server_port.cpp
|
hle/kernel/server_port.cpp
|
||||||
hle/kernel/server_session.cpp
|
hle/kernel/server_session.cpp
|
||||||
hle/kernel/shared_memory.cpp
|
hle/kernel/shared_memory.cpp
|
||||||
|
@ -94,6 +94,7 @@ set(HEADERS
|
||||||
hle/kernel/address_arbiter.h
|
hle/kernel/address_arbiter.h
|
||||||
hle/kernel/client_port.h
|
hle/kernel/client_port.h
|
||||||
hle/kernel/client_session.h
|
hle/kernel/client_session.h
|
||||||
|
hle/kernel/condition_variable.h
|
||||||
hle/kernel/domain.h
|
hle/kernel/domain.h
|
||||||
hle/kernel/errors.h
|
hle/kernel/errors.h
|
||||||
hle/kernel/event.h
|
hle/kernel/event.h
|
||||||
|
@ -105,7 +106,6 @@ set(HEADERS
|
||||||
hle/kernel/object_address_table.h
|
hle/kernel/object_address_table.h
|
||||||
hle/kernel/process.h
|
hle/kernel/process.h
|
||||||
hle/kernel/resource_limit.h
|
hle/kernel/resource_limit.h
|
||||||
hle/kernel/semaphore.h
|
|
||||||
hle/kernel/server_port.h
|
hle/kernel/server_port.h
|
||||||
hle/kernel/server_session.h
|
hle/kernel/server_session.h
|
||||||
hle/kernel/session.h
|
hle/kernel/session.h
|
||||||
|
|
|
@ -0,0 +1,65 @@
|
||||||
|
// Copyright 2018 Yuzu Emulator Team
|
||||||
|
// Licensed under GPLv2 or any later version
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#include "common/assert.h"
|
||||||
|
#include "core/hle/kernel/condition_variable.h"
|
||||||
|
#include "core/hle/kernel/errors.h"
|
||||||
|
#include "core/hle/kernel/kernel.h"
|
||||||
|
#include "core/hle/kernel/object_address_table.h"
|
||||||
|
#include "core/hle/kernel/thread.h"
|
||||||
|
|
||||||
|
namespace Kernel {
|
||||||
|
|
||||||
|
ConditionVariable::ConditionVariable() {}
|
||||||
|
ConditionVariable::~ConditionVariable() {}
|
||||||
|
|
||||||
|
ResultVal<SharedPtr<ConditionVariable>> ConditionVariable::Create(VAddr guest_addr,
|
||||||
|
VAddr mutex_addr,
|
||||||
|
std::string name) {
|
||||||
|
SharedPtr<ConditionVariable> condition_variable(new ConditionVariable);
|
||||||
|
|
||||||
|
condition_variable->name = std::move(name);
|
||||||
|
condition_variable->guest_addr = guest_addr;
|
||||||
|
condition_variable->mutex_addr = mutex_addr;
|
||||||
|
|
||||||
|
// Condition variables are referenced by guest address, so track this in the kernel
|
||||||
|
g_object_address_table.Insert(guest_addr, condition_variable);
|
||||||
|
|
||||||
|
return MakeResult<SharedPtr<ConditionVariable>>(std::move(condition_variable));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ConditionVariable::ShouldWait(Thread* thread) const {
|
||||||
|
return GetAvailableCount() <= 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConditionVariable::Acquire(Thread* thread) {
|
||||||
|
if (GetAvailableCount() <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
SetAvailableCount(GetAvailableCount() - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
ResultCode ConditionVariable::Release(s32 target) {
|
||||||
|
if (target == -1) {
|
||||||
|
// When -1, wake up all waiting threads
|
||||||
|
SetAvailableCount(GetWaitingThreads().size());
|
||||||
|
WakeupAllWaitingThreads();
|
||||||
|
} else {
|
||||||
|
// Otherwise, wake up just a single thread
|
||||||
|
SetAvailableCount(target);
|
||||||
|
WakeupWaitingThread(GetHighestPriorityReadyThread());
|
||||||
|
}
|
||||||
|
|
||||||
|
return RESULT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
s32 ConditionVariable::GetAvailableCount() const {
|
||||||
|
return Memory::Read32(guest_addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConditionVariable::SetAvailableCount(s32 value) const {
|
||||||
|
Memory::Write32(guest_addr, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Kernel
|
|
@ -0,0 +1,65 @@
|
||||||
|
// Copyright 2018 Yuzu Emulator Team
|
||||||
|
// Licensed under GPLv2 or any later version
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <queue>
|
||||||
|
#include <string>
|
||||||
|
#include "common/common_types.h"
|
||||||
|
#include "core/hle/kernel/kernel.h"
|
||||||
|
#include "core/hle/kernel/wait_object.h"
|
||||||
|
#include "core/hle/result.h"
|
||||||
|
|
||||||
|
namespace Kernel {
|
||||||
|
|
||||||
|
class ConditionVariable final : public WaitObject {
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Creates a condition variable.
|
||||||
|
* @param guest_addr Address of the object tracking the condition variable in guest memory. If
|
||||||
|
* specified, this condition variable will update the guest object when its state changes.
|
||||||
|
* @param mutex_addr Optional address of a guest mutex associated with this condition variable,
|
||||||
|
* used by the OS for implementing events.
|
||||||
|
* @param name Optional name of condition variable.
|
||||||
|
* @return The created condition variable.
|
||||||
|
*/
|
||||||
|
static ResultVal<SharedPtr<ConditionVariable>> Create(VAddr guest_addr, VAddr mutex_addr = 0,
|
||||||
|
std::string name = "Unknown");
|
||||||
|
|
||||||
|
std::string GetTypeName() const override {
|
||||||
|
return "ConditionVariable";
|
||||||
|
}
|
||||||
|
std::string GetName() const override {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const HandleType HANDLE_TYPE = HandleType::ConditionVariable;
|
||||||
|
HandleType GetHandleType() const override {
|
||||||
|
return HANDLE_TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
|
s32 GetAvailableCount() const;
|
||||||
|
void SetAvailableCount(s32 value) const;
|
||||||
|
|
||||||
|
std::string name; ///< Name of condition variable (optional)
|
||||||
|
VAddr guest_addr; ///< Address of the guest condition variable value
|
||||||
|
VAddr mutex_addr; ///< (optional) Address of guest mutex value associated with this condition
|
||||||
|
///< variable, used for implementing events
|
||||||
|
|
||||||
|
bool ShouldWait(Thread* thread) const override;
|
||||||
|
void Acquire(Thread* thread) override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Releases a slot from a condition variable.
|
||||||
|
* @param target The number of threads to wakeup, -1 is all.
|
||||||
|
* @return ResultCode indicating if the operation succeeded.
|
||||||
|
*/
|
||||||
|
ResultCode Release(s32 target);
|
||||||
|
|
||||||
|
private:
|
||||||
|
ConditionVariable();
|
||||||
|
~ConditionVariable() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Kernel
|
|
@ -23,7 +23,7 @@ enum class HandleType : u32 {
|
||||||
Thread,
|
Thread,
|
||||||
Process,
|
Process,
|
||||||
AddressArbiter,
|
AddressArbiter,
|
||||||
Semaphore,
|
ConditionVariable,
|
||||||
Timer,
|
Timer,
|
||||||
ResourceLimit,
|
ResourceLimit,
|
||||||
CodeSet,
|
CodeSet,
|
||||||
|
@ -70,7 +70,7 @@ public:
|
||||||
case HandleType::Event:
|
case HandleType::Event:
|
||||||
case HandleType::Mutex:
|
case HandleType::Mutex:
|
||||||
case HandleType::Thread:
|
case HandleType::Thread:
|
||||||
case HandleType::Semaphore:
|
case HandleType::ConditionVariable:
|
||||||
case HandleType::Timer:
|
case HandleType::Timer:
|
||||||
case HandleType::ServerPort:
|
case HandleType::ServerPort:
|
||||||
case HandleType::ServerSession:
|
case HandleType::ServerSession:
|
||||||
|
|
|
@ -1,64 +0,0 @@
|
||||||
// Copyright 2014 Citra Emulator Project
|
|
||||||
// Licensed under GPLv2 or any later version
|
|
||||||
// Refer to the license.txt file included.
|
|
||||||
|
|
||||||
#include "common/assert.h"
|
|
||||||
#include "core/hle/kernel/errors.h"
|
|
||||||
#include "core/hle/kernel/kernel.h"
|
|
||||||
#include "core/hle/kernel/object_address_table.h"
|
|
||||||
#include "core/hle/kernel/semaphore.h"
|
|
||||||
#include "core/hle/kernel/thread.h"
|
|
||||||
|
|
||||||
namespace Kernel {
|
|
||||||
|
|
||||||
Semaphore::Semaphore() {}
|
|
||||||
Semaphore::~Semaphore() {}
|
|
||||||
|
|
||||||
ResultVal<SharedPtr<Semaphore>> Semaphore::Create(VAddr guest_addr, VAddr mutex_addr,
|
|
||||||
std::string name) {
|
|
||||||
SharedPtr<Semaphore> semaphore(new Semaphore);
|
|
||||||
|
|
||||||
semaphore->name = std::move(name);
|
|
||||||
semaphore->guest_addr = guest_addr;
|
|
||||||
semaphore->mutex_addr = mutex_addr;
|
|
||||||
|
|
||||||
// Semaphores are referenced by guest address, so track this in the kernel
|
|
||||||
g_object_address_table.Insert(guest_addr, semaphore);
|
|
||||||
|
|
||||||
return MakeResult<SharedPtr<Semaphore>>(std::move(semaphore));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Semaphore::ShouldWait(Thread* thread) const {
|
|
||||||
return GetAvailableCount() <= 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Semaphore::Acquire(Thread* thread) {
|
|
||||||
if (GetAvailableCount() <= 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
SetAvailableCount(GetAvailableCount() - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
ResultCode Semaphore::Release(s32 target) {
|
|
||||||
if (target == -1) {
|
|
||||||
// When -1, wake up all waiting threads
|
|
||||||
SetAvailableCount(GetWaitingThreads().size());
|
|
||||||
WakeupAllWaitingThreads();
|
|
||||||
} else {
|
|
||||||
// Otherwise, wake up just a single thread
|
|
||||||
SetAvailableCount(target);
|
|
||||||
WakeupWaitingThread(GetHighestPriorityReadyThread());
|
|
||||||
}
|
|
||||||
|
|
||||||
return RESULT_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
s32 Semaphore::GetAvailableCount() const {
|
|
||||||
return Memory::Read32(guest_addr);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Semaphore::SetAvailableCount(s32 value) const {
|
|
||||||
Memory::Write32(guest_addr, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Kernel
|
|
|
@ -1,66 +0,0 @@
|
||||||
// Copyright 2014 Citra Emulator Project
|
|
||||||
// Licensed under GPLv2 or any later version
|
|
||||||
// Refer to the license.txt file included.
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <queue>
|
|
||||||
#include <string>
|
|
||||||
#include "common/common_types.h"
|
|
||||||
#include "core/hle/kernel/kernel.h"
|
|
||||||
#include "core/hle/kernel/wait_object.h"
|
|
||||||
#include "core/hle/result.h"
|
|
||||||
|
|
||||||
namespace Kernel {
|
|
||||||
|
|
||||||
// TODO(Subv): This is actually a Condition Variable.
|
|
||||||
class Semaphore final : public WaitObject {
|
|
||||||
public:
|
|
||||||
/**
|
|
||||||
* Creates a semaphore.
|
|
||||||
* @param guest_addr Address of the object tracking the semaphore in guest memory. If specified,
|
|
||||||
* this semaphore will update the guest object when its state changes.
|
|
||||||
* @param mutex_addr Optional address of a guest mutex associated with this semaphore, used by
|
|
||||||
* the OS for implementing events.
|
|
||||||
* @param name Optional name of semaphore.
|
|
||||||
* @return The created semaphore.
|
|
||||||
*/
|
|
||||||
static ResultVal<SharedPtr<Semaphore>> Create(VAddr guest_addr, VAddr mutex_addr = 0,
|
|
||||||
std::string name = "Unknown");
|
|
||||||
|
|
||||||
std::string GetTypeName() const override {
|
|
||||||
return "Semaphore";
|
|
||||||
}
|
|
||||||
std::string GetName() const override {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const HandleType HANDLE_TYPE = HandleType::Semaphore;
|
|
||||||
HandleType GetHandleType() const override {
|
|
||||||
return HANDLE_TYPE;
|
|
||||||
}
|
|
||||||
|
|
||||||
s32 GetAvailableCount() const;
|
|
||||||
void SetAvailableCount(s32 value) const;
|
|
||||||
|
|
||||||
std::string name; ///< Name of semaphore (optional)
|
|
||||||
VAddr guest_addr; ///< Address of the guest semaphore value
|
|
||||||
VAddr mutex_addr; ///< (optional) Address of guest mutex value associated with this semaphore,
|
|
||||||
///< used for implementing events
|
|
||||||
|
|
||||||
bool ShouldWait(Thread* thread) const override;
|
|
||||||
void Acquire(Thread* thread) override;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Releases a slot from a semaphore.
|
|
||||||
* @param target The number of threads to wakeup, -1 is all.
|
|
||||||
* @return ResultCode indicating if the operation succeeded.
|
|
||||||
*/
|
|
||||||
ResultCode Release(s32 target);
|
|
||||||
|
|
||||||
private:
|
|
||||||
Semaphore();
|
|
||||||
~Semaphore() override;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace Kernel
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2014 Citra Emulator Project
|
// Copyright 2018 Yuzu Emulator Team
|
||||||
// Licensed under GPLv2 or any later version
|
// Licensed under GPLv2 or any later version
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
@ -8,12 +8,12 @@
|
||||||
#include "core/core_timing.h"
|
#include "core/core_timing.h"
|
||||||
#include "core/hle/kernel/client_port.h"
|
#include "core/hle/kernel/client_port.h"
|
||||||
#include "core/hle/kernel/client_session.h"
|
#include "core/hle/kernel/client_session.h"
|
||||||
|
#include "core/hle/kernel/condition_variable.h"
|
||||||
#include "core/hle/kernel/handle_table.h"
|
#include "core/hle/kernel/handle_table.h"
|
||||||
#include "core/hle/kernel/mutex.h"
|
#include "core/hle/kernel/mutex.h"
|
||||||
#include "core/hle/kernel/object_address_table.h"
|
#include "core/hle/kernel/object_address_table.h"
|
||||||
#include "core/hle/kernel/process.h"
|
#include "core/hle/kernel/process.h"
|
||||||
#include "core/hle/kernel/resource_limit.h"
|
#include "core/hle/kernel/resource_limit.h"
|
||||||
#include "core/hle/kernel/semaphore.h"
|
|
||||||
#include "core/hle/kernel/svc.h"
|
#include "core/hle/kernel/svc.h"
|
||||||
#include "core/hle/kernel/svc_wrap.h"
|
#include "core/hle/kernel/svc_wrap.h"
|
||||||
#include "core/hle/kernel/sync_object.h"
|
#include "core/hle/kernel/sync_object.h"
|
||||||
|
@ -476,11 +476,12 @@ static void SleepThread(s64 nanoseconds) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Signal process wide key atomic
|
/// Signal process wide key atomic
|
||||||
static ResultCode WaitProcessWideKeyAtomic(VAddr mutex_addr, VAddr semaphore_addr,
|
static ResultCode WaitProcessWideKeyAtomic(VAddr mutex_addr, VAddr condition_variable_addr,
|
||||||
Handle thread_handle, s64 nano_seconds) {
|
Handle thread_handle, s64 nano_seconds) {
|
||||||
LOG_TRACE(Kernel_SVC,
|
LOG_TRACE(
|
||||||
"called mutex_addr=%llx, semaphore_addr=%llx, thread_handle=0x%08X, timeout=%d",
|
Kernel_SVC,
|
||||||
mutex_addr, semaphore_addr, thread_handle, nano_seconds);
|
"called mutex_addr=%llx, condition_variable_addr=%llx, thread_handle=0x%08X, timeout=%d",
|
||||||
|
mutex_addr, condition_variable_addr, thread_handle, nano_seconds);
|
||||||
|
|
||||||
SharedPtr<Thread> thread = g_handle_table.Get<Thread>(thread_handle);
|
SharedPtr<Thread> thread = g_handle_table.Get<Thread>(thread_handle);
|
||||||
ASSERT(thread);
|
ASSERT(thread);
|
||||||
|
@ -494,15 +495,18 @@ static ResultCode WaitProcessWideKeyAtomic(VAddr mutex_addr, VAddr semaphore_add
|
||||||
|
|
||||||
ASSERT(mutex->GetOwnerHandle() == thread_handle);
|
ASSERT(mutex->GetOwnerHandle() == thread_handle);
|
||||||
|
|
||||||
SharedPtr<Semaphore> semaphore = g_object_address_table.Get<Semaphore>(semaphore_addr);
|
SharedPtr<ConditionVariable> condition_variable =
|
||||||
if (!semaphore) {
|
g_object_address_table.Get<ConditionVariable>(condition_variable_addr);
|
||||||
// Create a new semaphore for the specified address if one does not already exist
|
if (!condition_variable) {
|
||||||
semaphore = Semaphore::Create(semaphore_addr, mutex_addr).Unwrap();
|
// Create a new condition_variable for the specified address if one does not already exist
|
||||||
semaphore->name = Common::StringFromFormat("semaphore-%llx", semaphore_addr);
|
condition_variable =
|
||||||
|
ConditionVariable::Create(condition_variable_addr, mutex_addr).Unwrap();
|
||||||
|
condition_variable->name =
|
||||||
|
Common::StringFromFormat("condition-variable-%llx", condition_variable_addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSERT(semaphore->GetAvailableCount() == 0);
|
ASSERT(condition_variable->GetAvailableCount() == 0);
|
||||||
ASSERT(semaphore->mutex_addr == mutex_addr);
|
ASSERT(condition_variable->mutex_addr == mutex_addr);
|
||||||
|
|
||||||
auto wakeup_callback = [mutex, nano_seconds](ThreadWakeupReason reason,
|
auto wakeup_callback = [mutex, nano_seconds](ThreadWakeupReason reason,
|
||||||
SharedPtr<Thread> thread,
|
SharedPtr<Thread> thread,
|
||||||
|
@ -541,7 +545,8 @@ static ResultCode WaitProcessWideKeyAtomic(VAddr mutex_addr, VAddr semaphore_add
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
CASCADE_CODE(WaitSynchronization1(semaphore, thread.get(), nano_seconds, wakeup_callback));
|
CASCADE_CODE(
|
||||||
|
WaitSynchronization1(condition_variable, thread.get(), nano_seconds, wakeup_callback));
|
||||||
|
|
||||||
mutex->Release(thread.get());
|
mutex->Release(thread.get());
|
||||||
|
|
||||||
|
@ -549,24 +554,27 @@ static ResultCode WaitProcessWideKeyAtomic(VAddr mutex_addr, VAddr semaphore_add
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Signal process wide key
|
/// Signal process wide key
|
||||||
static ResultCode SignalProcessWideKey(VAddr semaphore_addr, s32 target) {
|
static ResultCode SignalProcessWideKey(VAddr condition_variable_addr, s32 target) {
|
||||||
LOG_TRACE(Kernel_SVC, "called, semaphore_addr=0x%llx, target=0x%08x", semaphore_addr, target);
|
LOG_TRACE(Kernel_SVC, "called, condition_variable_addr=0x%llx, target=0x%08x",
|
||||||
|
condition_variable_addr, target);
|
||||||
|
|
||||||
// Wakeup all or one thread - Any other value is unimplemented
|
// Wakeup all or one thread - Any other value is unimplemented
|
||||||
ASSERT(target == -1 || target == 1);
|
ASSERT(target == -1 || target == 1);
|
||||||
|
|
||||||
SharedPtr<Semaphore> semaphore = g_object_address_table.Get<Semaphore>(semaphore_addr);
|
SharedPtr<ConditionVariable> condition_variable =
|
||||||
if (!semaphore) {
|
g_object_address_table.Get<ConditionVariable>(condition_variable_addr);
|
||||||
// Create a new semaphore for the specified address if one does not already exist
|
if (!condition_variable) {
|
||||||
semaphore = Semaphore::Create(semaphore_addr).Unwrap();
|
// Create a new condition_variable for the specified address if one does not already exist
|
||||||
semaphore->name = Common::StringFromFormat("semaphore-%llx", semaphore_addr);
|
condition_variable = ConditionVariable::Create(condition_variable_addr).Unwrap();
|
||||||
|
condition_variable->name =
|
||||||
|
Common::StringFromFormat("condition-variable-%llx", condition_variable_addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
CASCADE_CODE(semaphore->Release(target));
|
CASCADE_CODE(condition_variable->Release(target));
|
||||||
|
|
||||||
if (semaphore->mutex_addr) {
|
if (condition_variable->mutex_addr) {
|
||||||
// If a mutex was created for this semaphore, wait the current thread on it
|
// If a mutex was created for this condition_variable, wait the current thread on it
|
||||||
SharedPtr<Mutex> mutex = g_object_address_table.Get<Mutex>(semaphore->mutex_addr);
|
SharedPtr<Mutex> mutex = g_object_address_table.Get<Mutex>(condition_variable->mutex_addr);
|
||||||
return WaitSynchronization1(mutex, GetCurrentThread());
|
return WaitSynchronization1(mutex, GetCurrentThread());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2018 Citra Emulator Project
|
// Copyright 2018 Yuzu Emulator Team
|
||||||
// Licensed under GPLv2 or any later version
|
// Licensed under GPLv2 or any later version
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2018 Citra Emulator Project
|
// Copyright 2018 Yuzu Emulator Team
|
||||||
// Licensed under GPLv2 or any later version
|
// Licensed under GPLv2 or any later version
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue