diff options
Diffstat (limited to 'src/core/hle/kernel/address_arbiter.cpp')
-rw-r--r-- | src/core/hle/kernel/address_arbiter.cpp | 67 |
1 files changed, 31 insertions, 36 deletions
diff --git a/src/core/hle/kernel/address_arbiter.cpp b/src/core/hle/kernel/address_arbiter.cpp index 62e3460e..42f8ce2d 100644 --- a/src/core/hle/kernel/address_arbiter.cpp +++ b/src/core/hle/kernel/address_arbiter.cpp @@ -15,53 +15,64 @@ namespace Kernel { -class AddressArbiter : public Object { -public: - std::string GetTypeName() const override { return "Arbiter"; } - std::string GetName() const override { return name; } +AddressArbiter::AddressArbiter() {} +AddressArbiter::~AddressArbiter() {} - static const HandleType HANDLE_TYPE = HandleType::AddressArbiter; - HandleType GetHandleType() const override { return HANDLE_TYPE; } +SharedPtr<AddressArbiter> AddressArbiter::Create(std::string name) { + SharedPtr<AddressArbiter> address_arbiter(new AddressArbiter); - std::string name; ///< Name of address arbiter object (optional) -}; + address_arbiter->name = std::move(name); -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/// Arbitrate an address -ResultCode ArbitrateAddress(Handle handle, ArbitrationType type, u32 address, s32 value) { - Object* object = Kernel::g_handle_table.GetGeneric(handle).get(); - if (object == nullptr) - return InvalidHandle(ErrorModule::Kernel); + return address_arbiter; +} +ResultCode AddressArbiter::ArbitrateAddress(ArbitrationType type, VAddr address, s32 value, + u64 nanoseconds) { switch (type) { // Signal thread(s) waiting for arbitrate address... case ArbitrationType::Signal: // Negative value means resume all threads if (value < 0) { - ArbitrateAllThreads(object, address); + ArbitrateAllThreads(address); } else { // Resume first N threads for(int i = 0; i < value; i++) - ArbitrateHighestPriorityThread(object, address); + ArbitrateHighestPriorityThread(address); } break; // Wait current thread (acquire the arbiter)... case ArbitrationType::WaitIfLessThan: if ((s32)Memory::Read32(address) <= value) { - Kernel::WaitCurrentThread(WAITTYPE_ARB, object, address); + Kernel::WaitCurrentThread_ArbitrateAddress(address); + HLE::Reschedule(__func__); + } + break; + case ArbitrationType::WaitIfLessThanWithTimeout: + if ((s32)Memory::Read32(address) <= value) { + Kernel::WaitCurrentThread_ArbitrateAddress(address); + GetCurrentThread()->WakeAfterDelay(nanoseconds); HLE::Reschedule(__func__); } break; - case ArbitrationType::DecrementAndWaitIfLessThan: { s32 memory_value = Memory::Read32(address) - 1; Memory::Write32(address, memory_value); if (memory_value <= value) { - Kernel::WaitCurrentThread(WAITTYPE_ARB, object, address); + Kernel::WaitCurrentThread_ArbitrateAddress(address); + HLE::Reschedule(__func__); + } + break; + } + case ArbitrationType::DecrementAndWaitIfLessThanWithTimeout: + { + s32 memory_value = Memory::Read32(address) - 1; + Memory::Write32(address, memory_value); + if (memory_value <= value) { + Kernel::WaitCurrentThread_ArbitrateAddress(address); + GetCurrentThread()->WakeAfterDelay(nanoseconds); HLE::Reschedule(__func__); } break; @@ -74,20 +85,4 @@ ResultCode ArbitrateAddress(Handle handle, ArbitrationType type, u32 address, s3 return RESULT_SUCCESS; } -/// Create an address arbiter -AddressArbiter* CreateAddressArbiter(Handle& handle, const std::string& name) { - AddressArbiter* address_arbiter = new AddressArbiter; - // TOOD(yuriks): Fix error reporting - handle = Kernel::g_handle_table.Create(address_arbiter).ValueOr(INVALID_HANDLE); - address_arbiter->name = name; - return address_arbiter; -} - -/// Create an address arbiter -Handle CreateAddressArbiter(const std::string& name) { - Handle handle; - CreateAddressArbiter(handle, name); - return handle; -} - } // namespace Kernel |