summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/citra_qt/debugger/wait_tree.cpp5
-rw-r--r--src/core/hle/kernel/semaphore.cpp23
-rw-r--r--src/core/hle/kernel/semaphore.h9
-rw-r--r--src/core/hle/kernel/svc.cpp2
4 files changed, 18 insertions, 21 deletions
diff --git a/src/citra_qt/debugger/wait_tree.cpp b/src/citra_qt/debugger/wait_tree.cpp
index ebcc02894..6d15e43aa 100644
--- a/src/citra_qt/debugger/wait_tree.cpp
+++ b/src/citra_qt/debugger/wait_tree.cpp
@@ -273,9 +273,8 @@ std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeSemaphore::GetChildren() cons
273 std::vector<std::unique_ptr<WaitTreeItem>> list(WaitTreeWaitObject::GetChildren()); 273 std::vector<std::unique_ptr<WaitTreeItem>> list(WaitTreeWaitObject::GetChildren());
274 274
275 const auto& semaphore = static_cast<const Kernel::Semaphore&>(object); 275 const auto& semaphore = static_cast<const Kernel::Semaphore&>(object);
276 list.push_back( 276 list.push_back(std::make_unique<WaitTreeText>(
277 std::make_unique<WaitTreeText>(tr("available count = %1").arg(semaphore.available_count))); 277 tr("available count = %1").arg(semaphore.GetAvailableCount())));
278 list.push_back(std::make_unique<WaitTreeText>(tr("max count = %1").arg(semaphore.max_count)));
279 return list; 278 return list;
280} 279}
281 280
diff --git a/src/core/hle/kernel/semaphore.cpp b/src/core/hle/kernel/semaphore.cpp
index 9c58aa42f..b555bb28e 100644
--- a/src/core/hle/kernel/semaphore.cpp
+++ b/src/core/hle/kernel/semaphore.cpp
@@ -18,9 +18,6 @@ ResultVal<SharedPtr<Semaphore>> Semaphore::Create(VAddr guest_addr, VAddr mutex_
18 std::string name) { 18 std::string name) {
19 SharedPtr<Semaphore> semaphore(new Semaphore); 19 SharedPtr<Semaphore> semaphore(new Semaphore);
20 20
21 // When the semaphore is created, some slots are reserved for other threads,
22 // and the rest is reserved for the caller thread;
23 semaphore->available_count = Memory::Read32(guest_addr);
24 semaphore->name = std::move(name); 21 semaphore->name = std::move(name);
25 semaphore->guest_addr = guest_addr; 22 semaphore->guest_addr = guest_addr;
26 semaphore->mutex_addr = mutex_addr; 23 semaphore->mutex_addr = mutex_addr;
@@ -32,34 +29,36 @@ ResultVal<SharedPtr<Semaphore>> Semaphore::Create(VAddr guest_addr, VAddr mutex_
32} 29}
33 30
34bool Semaphore::ShouldWait(Thread* thread) const { 31bool Semaphore::ShouldWait(Thread* thread) const {
35 return available_count <= 0; 32 return GetAvailableCount() <= 0;
36} 33}
37 34
38void Semaphore::Acquire(Thread* thread) { 35void Semaphore::Acquire(Thread* thread) {
39 if (available_count <= 0) 36 if (GetAvailableCount() <= 0)
40 return; 37 return;
41 38
42 --available_count; 39 SetAvailableCount(GetAvailableCount() - 1);
43 UpdateGuestState();
44} 40}
45 41
46ResultCode Semaphore::Release(s32 target) { 42ResultCode Semaphore::Release(s32 target) {
47 ++available_count;
48 UpdateGuestState();
49
50 if (target == -1) { 43 if (target == -1) {
51 // When -1, wake up all waiting threads 44 // When -1, wake up all waiting threads
45 SetAvailableCount(GetWaitingThreads().size());
52 WakeupAllWaitingThreads(); 46 WakeupAllWaitingThreads();
53 } else { 47 } else {
54 // Otherwise, wake up just a single thread 48 // Otherwise, wake up just a single thread
49 SetAvailableCount(target);
55 WakeupWaitingThread(GetHighestPriorityReadyThread()); 50 WakeupWaitingThread(GetHighestPriorityReadyThread());
56 } 51 }
57 52
58 return RESULT_SUCCESS; 53 return RESULT_SUCCESS;
59} 54}
60 55
61void Semaphore::UpdateGuestState() { 56s32 Semaphore::GetAvailableCount() const {
62 Memory::Write32(guest_addr, available_count); 57 return Memory::Read32(guest_addr);
58}
59
60void Semaphore::SetAvailableCount(s32 value) const {
61 Memory::Write32(guest_addr, value);
63} 62}
64 63
65} // namespace Kernel 64} // namespace Kernel
diff --git a/src/core/hle/kernel/semaphore.h b/src/core/hle/kernel/semaphore.h
index e80230cac..7254eb26d 100644
--- a/src/core/hle/kernel/semaphore.h
+++ b/src/core/hle/kernel/semaphore.h
@@ -13,6 +13,7 @@
13 13
14namespace Kernel { 14namespace Kernel {
15 15
16// TODO(Subv): This is actually a Condition Variable.
16class Semaphore final : public WaitObject { 17class Semaphore final : public WaitObject {
17public: 18public:
18 /** 19 /**
@@ -39,8 +40,9 @@ public:
39 return HANDLE_TYPE; 40 return HANDLE_TYPE;
40 } 41 }
41 42
42 s32 max_count; ///< Maximum number of simultaneous holders the semaphore can have 43 s32 GetAvailableCount() const;
43 s32 available_count; ///< Number of free slots left in the semaphore 44 void SetAvailableCount(s32 value) const;
45
44 std::string name; ///< Name of semaphore (optional) 46 std::string name; ///< Name of semaphore (optional)
45 VAddr guest_addr; ///< Address of the guest semaphore value 47 VAddr guest_addr; ///< Address of the guest semaphore value
46 VAddr mutex_addr; ///< (optional) Address of guest mutex value associated with this semaphore, 48 VAddr mutex_addr; ///< (optional) Address of guest mutex value associated with this semaphore,
@@ -59,9 +61,6 @@ public:
59private: 61private:
60 Semaphore(); 62 Semaphore();
61 ~Semaphore() override; 63 ~Semaphore() override;
62
63 /// Updates the state of the object tracking this semaphore in guest memory
64 void UpdateGuestState();
65}; 64};
66 65
67} // namespace Kernel 66} // namespace Kernel
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index a3ac3d782..d18d7a182 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -501,7 +501,7 @@ static ResultCode WaitProcessWideKeyAtomic(VAddr mutex_addr, VAddr semaphore_add
501 semaphore->name = Common::StringFromFormat("semaphore-%llx", semaphore_addr); 501 semaphore->name = Common::StringFromFormat("semaphore-%llx", semaphore_addr);
502 } 502 }
503 503
504 ASSERT(semaphore->available_count == 0); 504 ASSERT(semaphore->GetAvailableCount() == 0);
505 ASSERT(semaphore->mutex_addr == mutex_addr); 505 ASSERT(semaphore->mutex_addr == mutex_addr);
506 506
507 auto wakeup_callback = [mutex, nano_seconds](ThreadWakeupReason reason, 507 auto wakeup_callback = [mutex, nano_seconds](ThreadWakeupReason reason,