summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
authorGravatar bunnei2018-12-26 15:54:14 -0500
committerGravatar GitHub2018-12-26 15:54:14 -0500
commitae582b6669eed99e66829b1941152f0b8b073128 (patch)
tree5aa768c110f6876823a61d31193cca58c103ddc6 /src/core
parentMerge pull request #1943 from ReinUsesLisp/fixup-texs (diff)
parentdebugger: Set paused thread color (diff)
downloadyuzu-ae582b6669eed99e66829b1941152f0b8b073128.tar.gz
yuzu-ae582b6669eed99e66829b1941152f0b8b073128.tar.xz
yuzu-ae582b6669eed99e66829b1941152f0b8b073128.zip
Merge pull request #1849 from encounter/svcSetThreadActivity
svc: Implement SetThreadActivity (thread suspension)
Diffstat (limited to 'src/core')
-rw-r--r--src/core/hle/kernel/errors.h2
-rw-r--r--src/core/hle/kernel/svc.cpp38
-rw-r--r--src/core/hle/kernel/thread.cpp24
-rw-r--r--src/core/hle/kernel/thread.h14
4 files changed, 72 insertions, 6 deletions
diff --git a/src/core/hle/kernel/errors.h b/src/core/hle/kernel/errors.h
index 8b58d701d..d8240ec6d 100644
--- a/src/core/hle/kernel/errors.h
+++ b/src/core/hle/kernel/errors.h
@@ -27,7 +27,7 @@ constexpr ResultCode ERR_SYNCHRONIZATION_CANCELED{ErrorModule::Kernel, 118};
27constexpr ResultCode ERR_OUT_OF_RANGE{ErrorModule::Kernel, 119}; 27constexpr ResultCode ERR_OUT_OF_RANGE{ErrorModule::Kernel, 119};
28constexpr ResultCode ERR_INVALID_ENUM_VALUE{ErrorModule::Kernel, 120}; 28constexpr ResultCode ERR_INVALID_ENUM_VALUE{ErrorModule::Kernel, 120};
29constexpr ResultCode ERR_NOT_FOUND{ErrorModule::Kernel, 121}; 29constexpr ResultCode ERR_NOT_FOUND{ErrorModule::Kernel, 121};
30constexpr ResultCode ERR_ALREADY_REGISTERED{ErrorModule::Kernel, 122}; 30constexpr ResultCode ERR_BUSY{ErrorModule::Kernel, 122};
31constexpr ResultCode ERR_SESSION_CLOSED_BY_REMOTE{ErrorModule::Kernel, 123}; 31constexpr ResultCode ERR_SESSION_CLOSED_BY_REMOTE{ErrorModule::Kernel, 123};
32constexpr ResultCode ERR_INVALID_STATE{ErrorModule::Kernel, 125}; 32constexpr ResultCode ERR_INVALID_STATE{ErrorModule::Kernel, 125};
33constexpr ResultCode ERR_RESOURCE_LIMIT_EXCEEDED{ErrorModule::Kernel, 132}; 33constexpr ResultCode ERR_RESOURCE_LIMIT_EXCEEDED{ErrorModule::Kernel, 132};
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index 28268e112..2e80b48c2 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -932,8 +932,35 @@ static ResultCode GetInfo(u64* result, u64 info_id, u64 handle, u64 info_sub_id)
932} 932}
933 933
934/// Sets the thread activity 934/// Sets the thread activity
935static ResultCode SetThreadActivity(Handle handle, u32 unknown) { 935static ResultCode SetThreadActivity(Handle handle, u32 activity) {
936 LOG_WARNING(Kernel_SVC, "(STUBBED) called, handle=0x{:08X}, unknown=0x{:08X}", handle, unknown); 936 LOG_DEBUG(Kernel_SVC, "called, handle=0x{:08X}, activity=0x{:08X}", handle, activity);
937 if (activity > static_cast<u32>(ThreadActivity::Paused)) {
938 return ERR_INVALID_ENUM_VALUE;
939 }
940
941 const auto* current_process = Core::CurrentProcess();
942 const SharedPtr<Thread> thread = current_process->GetHandleTable().Get<Thread>(handle);
943 if (!thread) {
944 LOG_ERROR(Kernel_SVC, "Thread handle does not exist, handle=0x{:08X}", handle);
945 return ERR_INVALID_HANDLE;
946 }
947
948 if (thread->GetOwnerProcess() != current_process) {
949 LOG_ERROR(Kernel_SVC,
950 "The current process does not own the current thread, thread_handle={:08X} "
951 "thread_pid={}, "
952 "current_process_pid={}",
953 handle, thread->GetOwnerProcess()->GetProcessID(),
954 current_process->GetProcessID());
955 return ERR_INVALID_HANDLE;
956 }
957
958 if (thread == GetCurrentThread()) {
959 LOG_ERROR(Kernel_SVC, "The thread handle specified is the current running thread");
960 return ERR_BUSY;
961 }
962
963 thread->SetActivity(static_cast<ThreadActivity>(activity));
937 return RESULT_SUCCESS; 964 return RESULT_SUCCESS;
938} 965}
939 966
@@ -960,7 +987,7 @@ static ResultCode GetThreadContext(VAddr thread_context, Handle handle) {
960 987
961 if (thread == GetCurrentThread()) { 988 if (thread == GetCurrentThread()) {
962 LOG_ERROR(Kernel_SVC, "The thread handle specified is the current running thread"); 989 LOG_ERROR(Kernel_SVC, "The thread handle specified is the current running thread");
963 return ERR_ALREADY_REGISTERED; 990 return ERR_BUSY;
964 } 991 }
965 992
966 Core::ARM_Interface::ThreadContext ctx = thread->GetContext(); 993 Core::ARM_Interface::ThreadContext ctx = thread->GetContext();
@@ -1245,7 +1272,10 @@ static ResultCode StartThread(Handle thread_handle) {
1245 ASSERT(thread->GetStatus() == ThreadStatus::Dormant); 1272 ASSERT(thread->GetStatus() == ThreadStatus::Dormant);
1246 1273
1247 thread->ResumeFromWait(); 1274 thread->ResumeFromWait();
1248 Core::System::GetInstance().CpuCore(thread->GetProcessorID()).PrepareReschedule(); 1275
1276 if (thread->GetStatus() == ThreadStatus::Ready) {
1277 Core::System::GetInstance().CpuCore(thread->GetProcessorID()).PrepareReschedule();
1278 }
1249 1279
1250 return RESULT_SUCCESS; 1280 return RESULT_SUCCESS;
1251} 1281}
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp
index 63f8923fd..434655638 100644
--- a/src/core/hle/kernel/thread.cpp
+++ b/src/core/hle/kernel/thread.cpp
@@ -50,7 +50,7 @@ void Thread::Stop() {
50 50
51 // Clean up thread from ready queue 51 // Clean up thread from ready queue
52 // This is only needed when the thread is terminated forcefully (SVC TerminateProcess) 52 // This is only needed when the thread is terminated forcefully (SVC TerminateProcess)
53 if (status == ThreadStatus::Ready) { 53 if (status == ThreadStatus::Ready || status == ThreadStatus::Paused) {
54 scheduler->UnscheduleThread(this, current_priority); 54 scheduler->UnscheduleThread(this, current_priority);
55 } 55 }
56 56
@@ -140,6 +140,11 @@ void Thread::ResumeFromWait() {
140 140
141 wakeup_callback = nullptr; 141 wakeup_callback = nullptr;
142 142
143 if (activity == ThreadActivity::Paused) {
144 status = ThreadStatus::Paused;
145 return;
146 }
147
143 status = ThreadStatus::Ready; 148 status = ThreadStatus::Ready;
144 149
145 ChangeScheduler(); 150 ChangeScheduler();
@@ -391,6 +396,23 @@ bool Thread::InvokeWakeupCallback(ThreadWakeupReason reason, SharedPtr<Thread> t
391 return wakeup_callback(reason, std::move(thread), std::move(object), index); 396 return wakeup_callback(reason, std::move(thread), std::move(object), index);
392} 397}
393 398
399void Thread::SetActivity(ThreadActivity value) {
400 activity = value;
401
402 if (value == ThreadActivity::Paused) {
403 // Set status if not waiting
404 if (status == ThreadStatus::Ready) {
405 status = ThreadStatus::Paused;
406 } else if (status == ThreadStatus::Running) {
407 status = ThreadStatus::Paused;
408 Core::System::GetInstance().CpuCore(processor_id).PrepareReschedule();
409 }
410 } else if (status == ThreadStatus::Paused) {
411 // Ready to reschedule
412 ResumeFromWait();
413 }
414}
415
394//////////////////////////////////////////////////////////////////////////////////////////////////// 416////////////////////////////////////////////////////////////////////////////////////////////////////
395 417
396/** 418/**
diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h
index d6e7981d3..fe5398d56 100644
--- a/src/core/hle/kernel/thread.h
+++ b/src/core/hle/kernel/thread.h
@@ -45,6 +45,7 @@ enum ThreadProcessorId : s32 {
45enum class ThreadStatus { 45enum class ThreadStatus {
46 Running, ///< Currently running 46 Running, ///< Currently running
47 Ready, ///< Ready to run 47 Ready, ///< Ready to run
48 Paused, ///< Paused by SetThreadActivity or debug
48 WaitHLEEvent, ///< Waiting for hle event to finish 49 WaitHLEEvent, ///< Waiting for hle event to finish
49 WaitSleep, ///< Waiting due to a SleepThread SVC 50 WaitSleep, ///< Waiting due to a SleepThread SVC
50 WaitIPC, ///< Waiting for the reply from an IPC request 51 WaitIPC, ///< Waiting for the reply from an IPC request
@@ -61,6 +62,11 @@ enum class ThreadWakeupReason {
61 Timeout // The thread was woken up due to a wait timeout. 62 Timeout // The thread was woken up due to a wait timeout.
62}; 63};
63 64
65enum class ThreadActivity : u32 {
66 Normal = 0,
67 Paused = 1,
68};
69
64class Thread final : public WaitObject { 70class Thread final : public WaitObject {
65public: 71public:
66 using TLSMemory = std::vector<u8>; 72 using TLSMemory = std::vector<u8>;
@@ -371,6 +377,12 @@ public:
371 return affinity_mask; 377 return affinity_mask;
372 } 378 }
373 379
380 ThreadActivity GetActivity() const {
381 return activity;
382 }
383
384 void SetActivity(ThreadActivity value);
385
374private: 386private:
375 explicit Thread(KernelCore& kernel); 387 explicit Thread(KernelCore& kernel);
376 ~Thread() override; 388 ~Thread() override;
@@ -439,6 +451,8 @@ private:
439 TLSMemoryPtr tls_memory = std::make_shared<TLSMemory>(); 451 TLSMemoryPtr tls_memory = std::make_shared<TLSMemory>();
440 452
441 std::string name; 453 std::string name;
454
455 ThreadActivity activity = ThreadActivity::Normal;
442}; 456};
443 457
444/** 458/**