diff options
| author | 2014-07-06 23:15:40 -0400 | |
|---|---|---|
| committer | 2014-07-08 18:46:38 -0400 | |
| commit | 3eb89f3e98b118f7829d3e56f32bcacbe58afc46 (patch) | |
| tree | a4e8761b1b55ca53941db9f2ce8c04f224226238 /src/core/hle/kernel | |
| parent | Thread: Added functions to resume threads from address arbitration. (diff) | |
| download | yuzu-3eb89f3e98b118f7829d3e56f32bcacbe58afc46.tar.gz yuzu-3eb89f3e98b118f7829d3e56f32bcacbe58afc46.tar.xz yuzu-3eb89f3e98b118f7829d3e56f32bcacbe58afc46.zip | |
Kernel: Added preliminary support for address arbiters.
AddressArbiter: Added documentation comment, fixed whitespace issue.
AddressArbiter: Fixed incorrect comment, reordered if-statement to be more clear.
SVC: Removed trailing whitespace.
Diffstat (limited to 'src/core/hle/kernel')
| -rw-r--r-- | src/core/hle/kernel/address_arbiter.cpp | 87 | ||||
| -rw-r--r-- | src/core/hle/kernel/address_arbiter.h | 36 | ||||
| -rw-r--r-- | src/core/hle/kernel/kernel.h | 2 |
3 files changed, 124 insertions, 1 deletions
diff --git a/src/core/hle/kernel/address_arbiter.cpp b/src/core/hle/kernel/address_arbiter.cpp new file mode 100644 index 000000000..61717bbe4 --- /dev/null +++ b/src/core/hle/kernel/address_arbiter.cpp | |||
| @@ -0,0 +1,87 @@ | |||
| 1 | // Copyright 2014 Citra Emulator Project | ||
| 2 | // Licensed under GPLv2 | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include "common/common_types.h" | ||
| 6 | |||
| 7 | #include "core/mem_map.h" | ||
| 8 | |||
| 9 | #include "core/hle/hle.h" | ||
| 10 | #include "core/hle/kernel/address_arbiter.h" | ||
| 11 | #include "core/hle/kernel/thread.h" | ||
| 12 | |||
| 13 | //////////////////////////////////////////////////////////////////////////////////////////////////// | ||
| 14 | // Kernel namespace | ||
| 15 | |||
| 16 | namespace Kernel { | ||
| 17 | |||
| 18 | class AddressArbiter : public Object { | ||
| 19 | public: | ||
| 20 | const char* GetTypeName() const { return "Arbiter"; } | ||
| 21 | const char* GetName() const { return name.c_str(); } | ||
| 22 | |||
| 23 | static Kernel::HandleType GetStaticHandleType() { return HandleType::AddressArbiter; } | ||
| 24 | Kernel::HandleType GetHandleType() const { return HandleType::AddressArbiter; } | ||
| 25 | |||
| 26 | std::string name; ///< Name of address arbiter object (optional) | ||
| 27 | |||
| 28 | /** | ||
| 29 | * Wait for kernel object to synchronize | ||
| 30 | * @param wait Boolean wait set if current thread should wait as a result of sync operation | ||
| 31 | * @return Result of operation, 0 on success, otherwise error code | ||
| 32 | */ | ||
| 33 | Result WaitSynchronization(bool* wait) { | ||
| 34 | // TODO(bunnei): ImplementMe | ||
| 35 | ERROR_LOG(OSHLE, "(UNIMPLEMENTED)"); | ||
| 36 | return 0; | ||
| 37 | } | ||
| 38 | }; | ||
| 39 | |||
| 40 | //////////////////////////////////////////////////////////////////////////////////////////////////// | ||
| 41 | |||
| 42 | /// Arbitrate an address | ||
| 43 | Result ArbitrateAddress(Handle handle, ArbitrationType type, u32 address, s32 value) { | ||
| 44 | switch (type) { | ||
| 45 | |||
| 46 | // Signal thread(s) waiting for arbitrate address... | ||
| 47 | case ArbitrationType::Signal: | ||
| 48 | // Negative value means resume all threads | ||
| 49 | if (value < 0) { | ||
| 50 | ArbitrateAllThreads(handle, address); | ||
| 51 | } else { | ||
| 52 | // Resume first N threads | ||
| 53 | for(int i = 0; i < value; i++) | ||
| 54 | ArbitrateHighestPriorityThread(handle, address); | ||
| 55 | } | ||
| 56 | HLE::Reschedule(__func__); | ||
| 57 | |||
| 58 | // Wait current thread (acquire the arbiter)... | ||
| 59 | case ArbitrationType::WaitIfLessThan: | ||
| 60 | if ((s32)Memory::Read32(address) <= value) { | ||
| 61 | Kernel::WaitCurrentThread(WAITTYPE_ARB, handle); | ||
| 62 | HLE::Reschedule(__func__); | ||
| 63 | } | ||
| 64 | |||
| 65 | default: | ||
| 66 | ERROR_LOG(KERNEL, "unknown type=%d", type); | ||
| 67 | return -1; | ||
| 68 | } | ||
| 69 | return 0; | ||
| 70 | } | ||
| 71 | |||
| 72 | /// Create an address arbiter | ||
| 73 | AddressArbiter* CreateAddressArbiter(Handle& handle, const std::string& name) { | ||
| 74 | AddressArbiter* address_arbiter = new AddressArbiter; | ||
| 75 | handle = Kernel::g_object_pool.Create(address_arbiter); | ||
| 76 | address_arbiter->name = name; | ||
| 77 | return address_arbiter; | ||
| 78 | } | ||
| 79 | |||
| 80 | /// Create an address arbiter | ||
| 81 | Handle CreateAddressArbiter(const std::string& name) { | ||
| 82 | Handle handle; | ||
| 83 | CreateAddressArbiter(handle, name); | ||
| 84 | return handle; | ||
| 85 | } | ||
| 86 | |||
| 87 | } // namespace Kernel | ||
diff --git a/src/core/hle/kernel/address_arbiter.h b/src/core/hle/kernel/address_arbiter.h new file mode 100644 index 000000000..a483fe466 --- /dev/null +++ b/src/core/hle/kernel/address_arbiter.h | |||
| @@ -0,0 +1,36 @@ | |||
| 1 | // Copyright 2014 Citra Emulator Project | ||
| 2 | // Licensed under GPLv2 | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include "common/common_types.h" | ||
| 8 | |||
| 9 | #include "core/hle/kernel/kernel.h" | ||
| 10 | |||
| 11 | // Address arbiters are an underlying kernel synchronization object that can be created/used via | ||
| 12 | // supervisor calls (SVCs). They function as sort of a global lock. Typically, games/other CTR | ||
| 13 | // applications use them as an underlying mechanism to implement thread-safe barriers, events, and | ||
| 14 | // semphores. | ||
| 15 | |||
| 16 | //////////////////////////////////////////////////////////////////////////////////////////////////// | ||
| 17 | // Kernel namespace | ||
| 18 | |||
| 19 | namespace Kernel { | ||
| 20 | |||
| 21 | /// Address arbitration types | ||
| 22 | enum class ArbitrationType : u32 { | ||
| 23 | Signal, | ||
| 24 | WaitIfLessThan, | ||
| 25 | DecrementAndWaitIfLessThan, | ||
| 26 | WaitIfLessThanWithTimeout, | ||
| 27 | DecrementAndWaitIfLessThanWithTimeout, | ||
| 28 | }; | ||
| 29 | |||
| 30 | /// Arbitrate an address | ||
| 31 | Result ArbitrateAddress(Handle handle, ArbitrationType type, u32 address, s32 value); | ||
| 32 | |||
| 33 | /// Create an address arbiter | ||
| 34 | Handle CreateAddressArbiter(const std::string& name = "Unknown"); | ||
| 35 | |||
| 36 | } // namespace FileSys | ||
diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index 69f4ddd37..d9afcdd25 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h | |||
| @@ -26,7 +26,7 @@ enum class HandleType : u32 { | |||
| 26 | Redirection = 6, | 26 | Redirection = 6, |
| 27 | Thread = 7, | 27 | Thread = 7, |
| 28 | Process = 8, | 28 | Process = 8, |
| 29 | Arbiter = 9, | 29 | AddressArbiter = 9, |
| 30 | File = 10, | 30 | File = 10, |
| 31 | Semaphore = 11, | 31 | Semaphore = 11, |
| 32 | Archive = 12, | 32 | Archive = 12, |