summaryrefslogtreecommitdiff
path: root/src/core/hle
diff options
context:
space:
mode:
authorGravatar bunnei2018-01-08 21:41:37 -0500
committerGravatar bunnei2018-01-08 21:41:37 -0500
commit423679983259948c203e546887445a59b64fc32f (patch)
treed359c88bb9347677025a9f0e64a08e0ab1733a4a /src/core/hle
parentmutex: Remove unused call to VerifyGuestState. (diff)
downloadyuzu-423679983259948c203e546887445a59b64fc32f.tar.gz
yuzu-423679983259948c203e546887445a59b64fc32f.tar.xz
yuzu-423679983259948c203e546887445a59b64fc32f.zip
kernel: Rename Semaphore to ConditionVariable.
Diffstat (limited to 'src/core/hle')
-rw-r--r--src/core/hle/kernel/condition_variable.cpp65
-rw-r--r--src/core/hle/kernel/condition_variable.h65
-rw-r--r--src/core/hle/kernel/kernel.h4
-rw-r--r--src/core/hle/kernel/semaphore.cpp64
-rw-r--r--src/core/hle/kernel/semaphore.h66
-rw-r--r--src/core/hle/kernel/svc.cpp58
-rw-r--r--src/core/hle/kernel/svc.h2
-rw-r--r--src/core/hle/kernel/svc_wrap.h2
8 files changed, 167 insertions, 159 deletions
diff --git a/src/core/hle/kernel/condition_variable.cpp b/src/core/hle/kernel/condition_variable.cpp
new file mode 100644
index 000000000..8908aeeb6
--- /dev/null
+++ b/src/core/hle/kernel/condition_variable.cpp
@@ -0,0 +1,65 @@
1// Copyright 2018 Yuzu Emulator Team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "common/assert.h"
6#include "core/hle/kernel/condition_variable.h"
7#include "core/hle/kernel/errors.h"
8#include "core/hle/kernel/kernel.h"
9#include "core/hle/kernel/object_address_table.h"
10#include "core/hle/kernel/thread.h"
11
12namespace Kernel {
13
14ConditionVariable::ConditionVariable() {}
15ConditionVariable::~ConditionVariable() {}
16
17ResultVal<SharedPtr<ConditionVariable>> ConditionVariable::Create(VAddr guest_addr,
18 VAddr mutex_addr,
19 std::string name) {
20 SharedPtr<ConditionVariable> condition_variable(new ConditionVariable);
21
22 condition_variable->name = std::move(name);
23 condition_variable->guest_addr = guest_addr;
24 condition_variable->mutex_addr = mutex_addr;
25
26 // Condition variables are referenced by guest address, so track this in the kernel
27 g_object_address_table.Insert(guest_addr, condition_variable);
28
29 return MakeResult<SharedPtr<ConditionVariable>>(std::move(condition_variable));
30}
31
32bool ConditionVariable::ShouldWait(Thread* thread) const {
33 return GetAvailableCount() <= 0;
34}
35
36void ConditionVariable::Acquire(Thread* thread) {
37 if (GetAvailableCount() <= 0)
38 return;
39
40 SetAvailableCount(GetAvailableCount() - 1);
41}
42
43ResultCode ConditionVariable::Release(s32 target) {
44 if (target == -1) {
45 // When -1, wake up all waiting threads
46 SetAvailableCount(GetWaitingThreads().size());
47 WakeupAllWaitingThreads();
48 } else {
49 // Otherwise, wake up just a single thread
50 SetAvailableCount(target);
51 WakeupWaitingThread(GetHighestPriorityReadyThread());
52 }
53
54 return RESULT_SUCCESS;
55}
56
57s32 ConditionVariable::GetAvailableCount() const {
58 return Memory::Read32(guest_addr);
59}
60
61void ConditionVariable::SetAvailableCount(s32 value) const {
62 Memory::Write32(guest_addr, value);
63}
64
65} // namespace Kernel
diff --git a/src/core/hle/kernel/condition_variable.h b/src/core/hle/kernel/condition_variable.h
new file mode 100644
index 000000000..27b8547c0
--- /dev/null
+++ b/src/core/hle/kernel/condition_variable.h
@@ -0,0 +1,65 @@
1// Copyright 2018 Yuzu Emulator Team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include <queue>
8#include <string>
9#include "common/common_types.h"
10#include "core/hle/kernel/kernel.h"
11#include "core/hle/kernel/wait_object.h"
12#include "core/hle/result.h"
13
14namespace Kernel {
15
16class ConditionVariable final : public WaitObject {
17public:
18 /**
19 * Creates a condition variable.
20 * @param guest_addr Address of the object tracking the condition variable in guest memory. If
21 * specified, this condition variable will update the guest object when its state changes.
22 * @param mutex_addr Optional address of a guest mutex associated with this condition variable,
23 * used by the OS for implementing events.
24 * @param name Optional name of condition variable.
25 * @return The created condition variable.
26 */
27 static ResultVal<SharedPtr<ConditionVariable>> Create(VAddr guest_addr, VAddr mutex_addr = 0,
28 std::string name = "Unknown");
29
30 std::string GetTypeName() const override {
31 return "ConditionVariable";
32 }
33 std::string GetName() const override {
34 return name;
35 }
36
37 static const HandleType HANDLE_TYPE = HandleType::ConditionVariable;
38 HandleType GetHandleType() const override {
39 return HANDLE_TYPE;
40 }
41
42 s32 GetAvailableCount() const;
43 void SetAvailableCount(s32 value) const;
44
45 std::string name; ///< Name of condition variable (optional)
46 VAddr guest_addr; ///< Address of the guest condition variable value
47 VAddr mutex_addr; ///< (optional) Address of guest mutex value associated with this condition
48 ///< variable, used for implementing events
49
50 bool ShouldWait(Thread* thread) const override;
51 void Acquire(Thread* thread) override;
52
53 /**
54 * Releases a slot from a condition variable.
55 * @param target The number of threads to wakeup, -1 is all.
56 * @return ResultCode indicating if the operation succeeded.
57 */
58 ResultCode Release(s32 target);
59
60private:
61 ConditionVariable();
62 ~ConditionVariable() override;
63};
64
65} // namespace Kernel
diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h
index e43055bfd..a1f2090f7 100644
--- a/src/core/hle/kernel/kernel.h
+++ b/src/core/hle/kernel/kernel.h
@@ -23,7 +23,7 @@ enum class HandleType : u32 {
23 Thread, 23 Thread,
24 Process, 24 Process,
25 AddressArbiter, 25 AddressArbiter,
26 Semaphore, 26 ConditionVariable,
27 Timer, 27 Timer,
28 ResourceLimit, 28 ResourceLimit,
29 CodeSet, 29 CodeSet,
@@ -70,7 +70,7 @@ public:
70 case HandleType::Event: 70 case HandleType::Event:
71 case HandleType::Mutex: 71 case HandleType::Mutex:
72 case HandleType::Thread: 72 case HandleType::Thread:
73 case HandleType::Semaphore: 73 case HandleType::ConditionVariable:
74 case HandleType::Timer: 74 case HandleType::Timer:
75 case HandleType::ServerPort: 75 case HandleType::ServerPort:
76 case HandleType::ServerSession: 76 case HandleType::ServerSession:
diff --git a/src/core/hle/kernel/semaphore.cpp b/src/core/hle/kernel/semaphore.cpp
deleted file mode 100644
index b555bb28e..000000000
--- a/src/core/hle/kernel/semaphore.cpp
+++ /dev/null
@@ -1,64 +0,0 @@
1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "common/assert.h"
6#include "core/hle/kernel/errors.h"
7#include "core/hle/kernel/kernel.h"
8#include "core/hle/kernel/object_address_table.h"
9#include "core/hle/kernel/semaphore.h"
10#include "core/hle/kernel/thread.h"
11
12namespace Kernel {
13
14Semaphore::Semaphore() {}
15Semaphore::~Semaphore() {}
16
17ResultVal<SharedPtr<Semaphore>> Semaphore::Create(VAddr guest_addr, VAddr mutex_addr,
18 std::string name) {
19 SharedPtr<Semaphore> semaphore(new Semaphore);
20
21 semaphore->name = std::move(name);
22 semaphore->guest_addr = guest_addr;
23 semaphore->mutex_addr = mutex_addr;
24
25 // Semaphores are referenced by guest address, so track this in the kernel
26 g_object_address_table.Insert(guest_addr, semaphore);
27
28 return MakeResult<SharedPtr<Semaphore>>(std::move(semaphore));
29}
30
31bool Semaphore::ShouldWait(Thread* thread) const {
32 return GetAvailableCount() <= 0;
33}
34
35void Semaphore::Acquire(Thread* thread) {
36 if (GetAvailableCount() <= 0)
37 return;
38
39 SetAvailableCount(GetAvailableCount() - 1);
40}
41
42ResultCode Semaphore::Release(s32 target) {
43 if (target == -1) {
44 // When -1, wake up all waiting threads
45 SetAvailableCount(GetWaitingThreads().size());
46 WakeupAllWaitingThreads();
47 } else {
48 // Otherwise, wake up just a single thread
49 SetAvailableCount(target);
50 WakeupWaitingThread(GetHighestPriorityReadyThread());
51 }
52
53 return RESULT_SUCCESS;
54}
55
56s32 Semaphore::GetAvailableCount() const {
57 return Memory::Read32(guest_addr);
58}
59
60void Semaphore::SetAvailableCount(s32 value) const {
61 Memory::Write32(guest_addr, value);
62}
63
64} // namespace Kernel
diff --git a/src/core/hle/kernel/semaphore.h b/src/core/hle/kernel/semaphore.h
deleted file mode 100644
index 7254eb26d..000000000
--- a/src/core/hle/kernel/semaphore.h
+++ /dev/null
@@ -1,66 +0,0 @@
1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include <queue>
8#include <string>
9#include "common/common_types.h"
10#include "core/hle/kernel/kernel.h"
11#include "core/hle/kernel/wait_object.h"
12#include "core/hle/result.h"
13
14namespace Kernel {
15
16// TODO(Subv): This is actually a Condition Variable.
17class Semaphore final : public WaitObject {
18public:
19 /**
20 * Creates a semaphore.
21 * @param guest_addr Address of the object tracking the semaphore in guest memory. If specified,
22 * this semaphore will update the guest object when its state changes.
23 * @param mutex_addr Optional address of a guest mutex associated with this semaphore, used by
24 * the OS for implementing events.
25 * @param name Optional name of semaphore.
26 * @return The created semaphore.
27 */
28 static ResultVal<SharedPtr<Semaphore>> Create(VAddr guest_addr, VAddr mutex_addr = 0,
29 std::string name = "Unknown");
30
31 std::string GetTypeName() const override {
32 return "Semaphore";
33 }
34 std::string GetName() const override {
35 return name;
36 }
37
38 static const HandleType HANDLE_TYPE = HandleType::Semaphore;
39 HandleType GetHandleType() const override {
40 return HANDLE_TYPE;
41 }
42
43 s32 GetAvailableCount() const;
44 void SetAvailableCount(s32 value) const;
45
46 std::string name; ///< Name of semaphore (optional)
47 VAddr guest_addr; ///< Address of the guest semaphore value
48 VAddr mutex_addr; ///< (optional) Address of guest mutex value associated with this semaphore,
49 ///< used for implementing events
50
51 bool ShouldWait(Thread* thread) const override;
52 void Acquire(Thread* thread) override;
53
54 /**
55 * Releases a slot from a semaphore.
56 * @param target The number of threads to wakeup, -1 is all.
57 * @return ResultCode indicating if the operation succeeded.
58 */
59 ResultCode Release(s32 target);
60
61private:
62 Semaphore();
63 ~Semaphore() override;
64};
65
66} // namespace Kernel
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index d18d7a182..b94503536 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -1,4 +1,4 @@
1// Copyright 2014 Citra Emulator Project 1// Copyright 2018 Yuzu Emulator Team
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
@@ -8,12 +8,12 @@
8#include "core/core_timing.h" 8#include "core/core_timing.h"
9#include "core/hle/kernel/client_port.h" 9#include "core/hle/kernel/client_port.h"
10#include "core/hle/kernel/client_session.h" 10#include "core/hle/kernel/client_session.h"
11#include "core/hle/kernel/condition_variable.h"
11#include "core/hle/kernel/handle_table.h" 12#include "core/hle/kernel/handle_table.h"
12#include "core/hle/kernel/mutex.h" 13#include "core/hle/kernel/mutex.h"
13#include "core/hle/kernel/object_address_table.h" 14#include "core/hle/kernel/object_address_table.h"
14#include "core/hle/kernel/process.h" 15#include "core/hle/kernel/process.h"
15#include "core/hle/kernel/resource_limit.h" 16#include "core/hle/kernel/resource_limit.h"
16#include "core/hle/kernel/semaphore.h"
17#include "core/hle/kernel/svc.h" 17#include "core/hle/kernel/svc.h"
18#include "core/hle/kernel/svc_wrap.h" 18#include "core/hle/kernel/svc_wrap.h"
19#include "core/hle/kernel/sync_object.h" 19#include "core/hle/kernel/sync_object.h"
@@ -476,11 +476,12 @@ static void SleepThread(s64 nanoseconds) {
476} 476}
477 477
478/// Signal process wide key atomic 478/// Signal process wide key atomic
479static ResultCode WaitProcessWideKeyAtomic(VAddr mutex_addr, VAddr semaphore_addr, 479static ResultCode WaitProcessWideKeyAtomic(VAddr mutex_addr, VAddr condition_variable_addr,
480 Handle thread_handle, s64 nano_seconds) { 480 Handle thread_handle, s64 nano_seconds) {
481 LOG_TRACE(Kernel_SVC, 481 LOG_TRACE(
482 "called mutex_addr=%llx, semaphore_addr=%llx, thread_handle=0x%08X, timeout=%d", 482 Kernel_SVC,
483 mutex_addr, semaphore_addr, thread_handle, nano_seconds); 483 "called mutex_addr=%llx, condition_variable_addr=%llx, thread_handle=0x%08X, timeout=%d",
484 mutex_addr, condition_variable_addr, thread_handle, nano_seconds);
484 485
485 SharedPtr<Thread> thread = g_handle_table.Get<Thread>(thread_handle); 486 SharedPtr<Thread> thread = g_handle_table.Get<Thread>(thread_handle);
486 ASSERT(thread); 487 ASSERT(thread);
@@ -494,15 +495,18 @@ static ResultCode WaitProcessWideKeyAtomic(VAddr mutex_addr, VAddr semaphore_add
494 495
495 ASSERT(mutex->GetOwnerHandle() == thread_handle); 496 ASSERT(mutex->GetOwnerHandle() == thread_handle);
496 497
497 SharedPtr<Semaphore> semaphore = g_object_address_table.Get<Semaphore>(semaphore_addr); 498 SharedPtr<ConditionVariable> condition_variable =
498 if (!semaphore) { 499 g_object_address_table.Get<ConditionVariable>(condition_variable_addr);
499 // Create a new semaphore for the specified address if one does not already exist 500 if (!condition_variable) {
500 semaphore = Semaphore::Create(semaphore_addr, mutex_addr).Unwrap(); 501 // Create a new condition_variable for the specified address if one does not already exist
501 semaphore->name = Common::StringFromFormat("semaphore-%llx", semaphore_addr); 502 condition_variable =
503 ConditionVariable::Create(condition_variable_addr, mutex_addr).Unwrap();
504 condition_variable->name =
505 Common::StringFromFormat("condition-variable-%llx", condition_variable_addr);
502 } 506 }
503 507
504 ASSERT(semaphore->GetAvailableCount() == 0); 508 ASSERT(condition_variable->GetAvailableCount() == 0);
505 ASSERT(semaphore->mutex_addr == mutex_addr); 509 ASSERT(condition_variable->mutex_addr == mutex_addr);
506 510
507 auto wakeup_callback = [mutex, nano_seconds](ThreadWakeupReason reason, 511 auto wakeup_callback = [mutex, nano_seconds](ThreadWakeupReason reason,
508 SharedPtr<Thread> thread, 512 SharedPtr<Thread> thread,
@@ -541,7 +545,8 @@ static ResultCode WaitProcessWideKeyAtomic(VAddr mutex_addr, VAddr semaphore_add
541 545
542 return false; 546 return false;
543 }; 547 };
544 CASCADE_CODE(WaitSynchronization1(semaphore, thread.get(), nano_seconds, wakeup_callback)); 548 CASCADE_CODE(
549 WaitSynchronization1(condition_variable, thread.get(), nano_seconds, wakeup_callback));
545 550
546 mutex->Release(thread.get()); 551 mutex->Release(thread.get());
547 552
@@ -549,24 +554,27 @@ static ResultCode WaitProcessWideKeyAtomic(VAddr mutex_addr, VAddr semaphore_add
549} 554}
550 555
551/// Signal process wide key 556/// Signal process wide key
552static ResultCode SignalProcessWideKey(VAddr semaphore_addr, s32 target) { 557static ResultCode SignalProcessWideKey(VAddr condition_variable_addr, s32 target) {
553 LOG_TRACE(Kernel_SVC, "called, semaphore_addr=0x%llx, target=0x%08x", semaphore_addr, target); 558 LOG_TRACE(Kernel_SVC, "called, condition_variable_addr=0x%llx, target=0x%08x",
559 condition_variable_addr, target);
554 560
555 // Wakeup all or one thread - Any other value is unimplemented 561 // Wakeup all or one thread - Any other value is unimplemented
556 ASSERT(target == -1 || target == 1); 562 ASSERT(target == -1 || target == 1);
557 563
558 SharedPtr<Semaphore> semaphore = g_object_address_table.Get<Semaphore>(semaphore_addr); 564 SharedPtr<ConditionVariable> condition_variable =
559 if (!semaphore) { 565 g_object_address_table.Get<ConditionVariable>(condition_variable_addr);
560 // Create a new semaphore for the specified address if one does not already exist 566 if (!condition_variable) {
561 semaphore = Semaphore::Create(semaphore_addr).Unwrap(); 567 // Create a new condition_variable for the specified address if one does not already exist
562 semaphore->name = Common::StringFromFormat("semaphore-%llx", semaphore_addr); 568 condition_variable = ConditionVariable::Create(condition_variable_addr).Unwrap();
569 condition_variable->name =
570 Common::StringFromFormat("condition-variable-%llx", condition_variable_addr);
563 } 571 }
564 572
565 CASCADE_CODE(semaphore->Release(target)); 573 CASCADE_CODE(condition_variable->Release(target));
566 574
567 if (semaphore->mutex_addr) { 575 if (condition_variable->mutex_addr) {
568 // If a mutex was created for this semaphore, wait the current thread on it 576 // If a mutex was created for this condition_variable, wait the current thread on it
569 SharedPtr<Mutex> mutex = g_object_address_table.Get<Mutex>(semaphore->mutex_addr); 577 SharedPtr<Mutex> mutex = g_object_address_table.Get<Mutex>(condition_variable->mutex_addr);
570 return WaitSynchronization1(mutex, GetCurrentThread()); 578 return WaitSynchronization1(mutex, GetCurrentThread());
571 } 579 }
572 580
diff --git a/src/core/hle/kernel/svc.h b/src/core/hle/kernel/svc.h
index b0265b6c8..a95598994 100644
--- a/src/core/hle/kernel/svc.h
+++ b/src/core/hle/kernel/svc.h
@@ -1,4 +1,4 @@
1// Copyright 2018 Citra Emulator Project 1// Copyright 2018 Yuzu Emulator Team
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
diff --git a/src/core/hle/kernel/svc_wrap.h b/src/core/hle/kernel/svc_wrap.h
index 4798ce733..bffa2f7f8 100644
--- a/src/core/hle/kernel/svc_wrap.h
+++ b/src/core/hle/kernel/svc_wrap.h
@@ -1,4 +1,4 @@
1// Copyright 2018 Citra Emulator Project 1// Copyright 2018 Yuzu Emulator Team
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4