k_thread.cpp 50 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460
  1. // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
  2. // SPDX-License-Identifier: GPL-2.0-or-later
  3. #include <algorithm>
  4. #include <atomic>
  5. #include <cinttypes>
  6. #include <condition_variable>
  7. #include <mutex>
  8. #include <optional>
  9. #include <vector>
  10. #include "common/assert.h"
  11. #include "common/bit_util.h"
  12. #include "common/common_funcs.h"
  13. #include "common/common_types.h"
  14. #include "common/fiber.h"
  15. #include "common/logging/log.h"
  16. #include "common/settings.h"
  17. #include "core/core.h"
  18. #include "core/cpu_manager.h"
  19. #include "core/hardware_properties.h"
  20. #include "core/hle/kernel/k_condition_variable.h"
  21. #include "core/hle/kernel/k_handle_table.h"
  22. #include "core/hle/kernel/k_memory_layout.h"
  23. #include "core/hle/kernel/k_process.h"
  24. #include "core/hle/kernel/k_resource_limit.h"
  25. #include "core/hle/kernel/k_scheduler.h"
  26. #include "core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h"
  27. #include "core/hle/kernel/k_system_control.h"
  28. #include "core/hle/kernel/k_thread.h"
  29. #include "core/hle/kernel/k_thread_queue.h"
  30. #include "core/hle/kernel/k_worker_task_manager.h"
  31. #include "core/hle/kernel/kernel.h"
  32. #include "core/hle/kernel/svc.h"
  33. #include "core/hle/kernel/svc_results.h"
  34. #include "core/hle/kernel/svc_types.h"
  35. #include "core/hle/result.h"
  36. #include "core/memory.h"
  37. namespace {
  38. constexpr inline s32 TerminatingThreadPriority = Kernel::Svc::SystemThreadPriorityHighest - 1;
  39. static void ResetThreadContext32(Kernel::KThread::ThreadContext32& context, u32 stack_top,
  40. u32 entry_point, u32 arg) {
  41. context = {};
  42. context.cpu_registers[0] = arg;
  43. context.cpu_registers[15] = entry_point;
  44. context.cpu_registers[13] = stack_top;
  45. context.fpscr = 0;
  46. }
  47. static void ResetThreadContext64(Kernel::KThread::ThreadContext64& context, u64 stack_top,
  48. u64 entry_point, u64 arg) {
  49. context = {};
  50. context.cpu_registers[0] = arg;
  51. context.cpu_registers[18] = Kernel::KSystemControl::GenerateRandomU64() | 1;
  52. context.pc = entry_point;
  53. context.sp = stack_top;
  54. context.fpcr = 0;
  55. context.fpsr = 0;
  56. }
  57. } // namespace
  58. namespace Kernel {
  59. namespace {
  60. struct ThreadLocalRegion {
  61. static constexpr std::size_t MessageBufferSize = 0x100;
  62. std::array<u32, MessageBufferSize / sizeof(u32)> message_buffer;
  63. std::atomic_uint16_t disable_count;
  64. std::atomic_uint16_t interrupt_flag;
  65. };
  66. class ThreadQueueImplForKThreadSleep final : public KThreadQueueWithoutEndWait {
  67. public:
  68. explicit ThreadQueueImplForKThreadSleep(KernelCore& kernel)
  69. : KThreadQueueWithoutEndWait(kernel) {}
  70. };
  71. class ThreadQueueImplForKThreadSetProperty final : public KThreadQueue {
  72. public:
  73. explicit ThreadQueueImplForKThreadSetProperty(KernelCore& kernel, KThread::WaiterList* wl)
  74. : KThreadQueue(kernel), m_wait_list(wl) {}
  75. void CancelWait(KThread* waiting_thread, Result wait_result, bool cancel_timer_task) override {
  76. // Remove the thread from the wait list.
  77. m_wait_list->erase(m_wait_list->iterator_to(*waiting_thread));
  78. // Invoke the base cancel wait handler.
  79. KThreadQueue::CancelWait(waiting_thread, wait_result, cancel_timer_task);
  80. }
  81. private:
  82. KThread::WaiterList* m_wait_list{};
  83. };
  84. } // namespace
  85. KThread::KThread(KernelCore& kernel)
  86. : KAutoObjectWithSlabHeapAndContainer{kernel}, m_activity_pause_lock{kernel} {}
  87. KThread::~KThread() = default;
  88. Result KThread::Initialize(KThreadFunction func, uintptr_t arg, KProcessAddress user_stack_top,
  89. s32 prio, s32 virt_core, KProcess* owner, ThreadType type) {
  90. // Assert parameters are valid.
  91. ASSERT((type == ThreadType::Main) || (type == ThreadType::Dummy) ||
  92. (Svc::HighestThreadPriority <= prio && prio <= Svc::LowestThreadPriority));
  93. ASSERT((owner != nullptr) || (type != ThreadType::User));
  94. ASSERT(0 <= virt_core && virt_core < static_cast<s32>(Common::BitSize<u64>()));
  95. // Convert the virtual core to a physical core.
  96. const s32 phys_core = Core::Hardware::VirtualToPhysicalCoreMap[virt_core];
  97. ASSERT(0 <= phys_core && phys_core < static_cast<s32>(Core::Hardware::NUM_CPU_CORES));
  98. // First, clear the TLS address.
  99. m_tls_address = {};
  100. // Next, assert things based on the type.
  101. switch (type) {
  102. case ThreadType::Main:
  103. ASSERT(arg == 0);
  104. [[fallthrough]];
  105. case ThreadType::User:
  106. ASSERT(((owner == nullptr) ||
  107. (owner->GetCoreMask() | (1ULL << virt_core)) == owner->GetCoreMask()));
  108. ASSERT(((owner == nullptr) || (prio > Svc::LowestThreadPriority) ||
  109. (owner->GetPriorityMask() | (1ULL << prio)) == owner->GetPriorityMask()));
  110. break;
  111. case ThreadType::HighPriority:
  112. case ThreadType::Dummy:
  113. break;
  114. case ThreadType::Kernel:
  115. UNIMPLEMENTED();
  116. break;
  117. default:
  118. ASSERT_MSG(false, "KThread::Initialize: Unknown ThreadType {}", static_cast<u32>(type));
  119. break;
  120. }
  121. m_thread_type = type;
  122. // Set the ideal core ID and affinity mask.
  123. m_virtual_ideal_core_id = virt_core;
  124. m_physical_ideal_core_id = phys_core;
  125. m_virtual_affinity_mask = 1ULL << virt_core;
  126. m_physical_affinity_mask.SetAffinity(phys_core, true);
  127. // Set the thread state.
  128. m_thread_state = (type == ThreadType::Main || type == ThreadType::Dummy)
  129. ? ThreadState::Runnable
  130. : ThreadState::Initialized;
  131. // Set TLS address.
  132. m_tls_address = 0;
  133. // Set parent and condvar tree.
  134. m_parent = nullptr;
  135. m_condvar_tree = nullptr;
  136. // Set sync booleans.
  137. m_signaled = false;
  138. m_termination_requested = false;
  139. m_wait_cancelled = false;
  140. m_cancellable = false;
  141. // Set core ID and wait result.
  142. m_core_id = phys_core;
  143. m_wait_result = ResultNoSynchronizationObject;
  144. // Set priorities.
  145. m_priority = prio;
  146. m_base_priority = prio;
  147. // Initialize sleeping queue.
  148. m_wait_queue = nullptr;
  149. // Set suspend flags.
  150. m_suspend_request_flags = 0;
  151. m_suspend_allowed_flags = static_cast<u32>(ThreadState::SuspendFlagMask);
  152. // We're neither debug attached, nor are we nesting our priority inheritance.
  153. m_debug_attached = false;
  154. m_priority_inheritance_count = 0;
  155. // We haven't been scheduled, and we have done no light IPC.
  156. m_schedule_count = -1;
  157. m_last_scheduled_tick = 0;
  158. m_light_ipc_data = nullptr;
  159. // We're not waiting for a lock, and we haven't disabled migration.
  160. m_waiting_lock_info = nullptr;
  161. m_num_core_migration_disables = 0;
  162. // We have no waiters, but we do have an entrypoint.
  163. m_num_kernel_waiters = 0;
  164. // Set our current core id.
  165. m_current_core_id = phys_core;
  166. // We haven't released our resource limit hint, and we've spent no time on the cpu.
  167. m_resource_limit_release_hint = false;
  168. m_cpu_time = 0;
  169. // Set debug context.
  170. m_stack_top = user_stack_top;
  171. m_argument = arg;
  172. // Clear our stack parameters.
  173. std::memset(static_cast<void*>(std::addressof(this->GetStackParameters())), 0,
  174. sizeof(StackParameters));
  175. // Set parent, if relevant.
  176. if (owner != nullptr) {
  177. // Setup the TLS, if needed.
  178. if (type == ThreadType::User) {
  179. R_TRY(owner->CreateThreadLocalRegion(std::addressof(m_tls_address)));
  180. owner->GetMemory().ZeroBlock(m_tls_address, Svc::ThreadLocalRegionSize);
  181. }
  182. m_parent = owner;
  183. m_parent->Open();
  184. }
  185. // Initialize thread context.
  186. ResetThreadContext64(m_thread_context_64, GetInteger(user_stack_top), GetInteger(func), arg);
  187. ResetThreadContext32(m_thread_context_32, static_cast<u32>(GetInteger(user_stack_top)),
  188. static_cast<u32>(GetInteger(func)), static_cast<u32>(arg));
  189. // Setup the stack parameters.
  190. StackParameters& sp = this->GetStackParameters();
  191. sp.cur_thread = this;
  192. sp.disable_count = 1;
  193. this->SetInExceptionHandler();
  194. // Set thread ID.
  195. m_thread_id = m_kernel.CreateNewThreadID();
  196. // We initialized!
  197. m_initialized = true;
  198. // Register ourselves with our parent process.
  199. if (m_parent != nullptr) {
  200. m_parent->RegisterThread(this);
  201. if (m_parent->IsSuspended()) {
  202. RequestSuspend(SuspendType::Process);
  203. }
  204. }
  205. R_SUCCEED();
  206. }
  207. Result KThread::InitializeThread(KThread* thread, KThreadFunction func, uintptr_t arg,
  208. KProcessAddress user_stack_top, s32 prio, s32 core,
  209. KProcess* owner, ThreadType type,
  210. std::function<void()>&& init_func) {
  211. // Initialize the thread.
  212. R_TRY(thread->Initialize(func, arg, user_stack_top, prio, core, owner, type));
  213. // Initialize emulation parameters.
  214. thread->m_host_context = std::make_shared<Common::Fiber>(std::move(init_func));
  215. R_SUCCEED();
  216. }
  217. Result KThread::InitializeDummyThread(KThread* thread, KProcess* owner) {
  218. // Initialize the thread.
  219. R_TRY(thread->Initialize({}, {}, {}, DummyThreadPriority, 3, owner, ThreadType::Dummy));
  220. // Initialize emulation parameters.
  221. thread->m_stack_parameters.disable_count = 0;
  222. R_SUCCEED();
  223. }
  224. Result KThread::InitializeMainThread(Core::System& system, KThread* thread, s32 virt_core) {
  225. R_RETURN(InitializeThread(thread, {}, {}, {}, IdleThreadPriority, virt_core, {},
  226. ThreadType::Main, system.GetCpuManager().GetGuestActivateFunc()));
  227. }
  228. Result KThread::InitializeIdleThread(Core::System& system, KThread* thread, s32 virt_core) {
  229. R_RETURN(InitializeThread(thread, {}, {}, {}, IdleThreadPriority, virt_core, {},
  230. ThreadType::Main, system.GetCpuManager().GetIdleThreadStartFunc()));
  231. }
  232. Result KThread::InitializeHighPriorityThread(Core::System& system, KThread* thread,
  233. KThreadFunction func, uintptr_t arg, s32 virt_core) {
  234. R_RETURN(InitializeThread(thread, func, arg, {}, {}, virt_core, nullptr,
  235. ThreadType::HighPriority,
  236. system.GetCpuManager().GetShutdownThreadStartFunc()));
  237. }
  238. Result KThread::InitializeUserThread(Core::System& system, KThread* thread, KThreadFunction func,
  239. uintptr_t arg, KProcessAddress user_stack_top, s32 prio,
  240. s32 virt_core, KProcess* owner) {
  241. system.Kernel().GlobalSchedulerContext().AddThread(thread);
  242. R_RETURN(InitializeThread(thread, func, arg, user_stack_top, prio, virt_core, owner,
  243. ThreadType::User, system.GetCpuManager().GetGuestThreadFunc()));
  244. }
  245. Result KThread::InitializeServiceThread(Core::System& system, KThread* thread,
  246. std::function<void()>&& func, s32 prio, s32 virt_core,
  247. KProcess* owner) {
  248. system.Kernel().GlobalSchedulerContext().AddThread(thread);
  249. std::function<void()> func2{[&system, func_{std::move(func)}] {
  250. // Similar to UserModeThreadStarter.
  251. system.Kernel().CurrentScheduler()->OnThreadStart();
  252. // Run the guest function.
  253. func_();
  254. // Exit.
  255. Svc::ExitThread(system);
  256. }};
  257. R_RETURN(InitializeThread(thread, {}, {}, {}, prio, virt_core, owner, ThreadType::HighPriority,
  258. std::move(func2)));
  259. }
  260. void KThread::PostDestroy(uintptr_t arg) {
  261. KProcess* owner = reinterpret_cast<KProcess*>(arg & ~1ULL);
  262. const bool resource_limit_release_hint = (arg & 1);
  263. const s64 hint_value = (resource_limit_release_hint ? 0 : 1);
  264. if (owner != nullptr) {
  265. owner->GetResourceLimit()->Release(LimitableResource::ThreadCountMax, 1, hint_value);
  266. owner->Close();
  267. }
  268. }
  269. void KThread::Finalize() {
  270. // If the thread has an owner process, unregister it.
  271. if (m_parent != nullptr) {
  272. m_parent->UnregisterThread(this);
  273. }
  274. // If the thread has a local region, delete it.
  275. if (m_tls_address != 0) {
  276. ASSERT(m_parent->DeleteThreadLocalRegion(m_tls_address).IsSuccess());
  277. }
  278. // Release any waiters.
  279. {
  280. ASSERT(m_waiting_lock_info == nullptr);
  281. KScopedSchedulerLock sl{m_kernel};
  282. // Check that we have no kernel waiters.
  283. ASSERT(m_num_kernel_waiters == 0);
  284. auto it = m_held_lock_info_list.begin();
  285. while (it != m_held_lock_info_list.end()) {
  286. // Get the lock info.
  287. auto* const lock_info = std::addressof(*it);
  288. // The lock shouldn't have a kernel waiter.
  289. ASSERT(!lock_info->GetIsKernelAddressKey());
  290. // Remove all waiters.
  291. while (lock_info->GetWaiterCount() != 0) {
  292. // Get the front waiter.
  293. KThread* const waiter = lock_info->GetHighestPriorityWaiter();
  294. // Remove it from the lock.
  295. if (lock_info->RemoveWaiter(waiter)) {
  296. ASSERT(lock_info->GetWaiterCount() == 0);
  297. }
  298. // Cancel the thread's wait.
  299. waiter->CancelWait(ResultInvalidState, true);
  300. }
  301. // Remove the held lock from our list.
  302. it = m_held_lock_info_list.erase(it);
  303. // Free the lock info.
  304. LockWithPriorityInheritanceInfo::Free(m_kernel, lock_info);
  305. }
  306. }
  307. // Release host emulation members.
  308. m_host_context.reset();
  309. // Perform inherited finalization.
  310. KSynchronizationObject::Finalize();
  311. }
  312. bool KThread::IsSignaled() const {
  313. return m_signaled;
  314. }
  315. void KThread::OnTimer() {
  316. ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(m_kernel));
  317. // If we're waiting, cancel the wait.
  318. if (this->GetState() == ThreadState::Waiting) {
  319. m_wait_queue->CancelWait(this, ResultTimedOut, false);
  320. }
  321. }
  322. void KThread::StartTermination() {
  323. ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(m_kernel));
  324. // Release user exception and unpin, if relevant.
  325. if (m_parent != nullptr) {
  326. m_parent->ReleaseUserException(this);
  327. if (m_parent->GetPinnedThread(GetCurrentCoreId(m_kernel)) == this) {
  328. m_parent->UnpinCurrentThread();
  329. }
  330. }
  331. // Set state to terminated.
  332. this->SetState(ThreadState::Terminated);
  333. // Clear the thread's status as running in parent.
  334. if (m_parent != nullptr) {
  335. m_parent->ClearRunningThread(this);
  336. }
  337. // Clear previous thread in KScheduler.
  338. KScheduler::ClearPreviousThread(m_kernel, this);
  339. // Register terminated dpc flag.
  340. this->RegisterDpc(DpcFlag::Terminated);
  341. }
  342. void KThread::FinishTermination() {
  343. // Ensure that the thread is not executing on any core.
  344. if (m_parent != nullptr) {
  345. for (std::size_t i = 0; i < static_cast<std::size_t>(Core::Hardware::NUM_CPU_CORES); ++i) {
  346. KThread* core_thread{};
  347. do {
  348. core_thread = m_kernel.Scheduler(i).GetSchedulerCurrentThread();
  349. } while (core_thread == this);
  350. }
  351. }
  352. // Acquire the scheduler lock.
  353. KScopedSchedulerLock sl{m_kernel};
  354. // Signal.
  355. m_signaled = true;
  356. KSynchronizationObject::NotifyAvailable();
  357. // Close the thread.
  358. this->Close();
  359. }
  360. void KThread::DoWorkerTaskImpl() {
  361. // Finish the termination that was begun by Exit().
  362. this->FinishTermination();
  363. }
  364. void KThread::Pin(s32 current_core) {
  365. ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(m_kernel));
  366. // Set ourselves as pinned.
  367. GetStackParameters().is_pinned = true;
  368. // Disable core migration.
  369. ASSERT(m_num_core_migration_disables == 0);
  370. {
  371. ++m_num_core_migration_disables;
  372. // Save our ideal state to restore when we're unpinned.
  373. m_original_physical_ideal_core_id = m_physical_ideal_core_id;
  374. m_original_physical_affinity_mask = m_physical_affinity_mask;
  375. // Bind ourselves to this core.
  376. const s32 active_core = this->GetActiveCore();
  377. this->SetActiveCore(current_core);
  378. m_physical_ideal_core_id = current_core;
  379. m_physical_affinity_mask.SetAffinityMask(1ULL << current_core);
  380. if (active_core != current_core ||
  381. m_physical_affinity_mask.GetAffinityMask() !=
  382. m_original_physical_affinity_mask.GetAffinityMask()) {
  383. KScheduler::OnThreadAffinityMaskChanged(m_kernel, this,
  384. m_original_physical_affinity_mask, active_core);
  385. }
  386. }
  387. // Disallow performing thread suspension.
  388. {
  389. // Update our allow flags.
  390. m_suspend_allowed_flags &= ~(1 << (static_cast<u32>(SuspendType::Thread) +
  391. static_cast<u32>(ThreadState::SuspendShift)));
  392. // Update our state.
  393. this->UpdateState();
  394. }
  395. // TODO(bunnei): Update our SVC access permissions.
  396. ASSERT(m_parent != nullptr);
  397. }
  398. void KThread::Unpin() {
  399. ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(m_kernel));
  400. // Set ourselves as unpinned.
  401. this->GetStackParameters().is_pinned = false;
  402. // Enable core migration.
  403. ASSERT(m_num_core_migration_disables == 1);
  404. {
  405. m_num_core_migration_disables--;
  406. // Restore our original state.
  407. const KAffinityMask old_mask = m_physical_affinity_mask;
  408. m_physical_ideal_core_id = m_original_physical_ideal_core_id;
  409. m_physical_affinity_mask = m_original_physical_affinity_mask;
  410. if (m_physical_affinity_mask.GetAffinityMask() != old_mask.GetAffinityMask()) {
  411. const s32 active_core = this->GetActiveCore();
  412. if (!m_physical_affinity_mask.GetAffinity(active_core)) {
  413. if (m_physical_ideal_core_id >= 0) {
  414. this->SetActiveCore(m_physical_ideal_core_id);
  415. } else {
  416. this->SetActiveCore(static_cast<s32>(
  417. Common::BitSize<u64>() - 1 -
  418. std::countl_zero(m_physical_affinity_mask.GetAffinityMask())));
  419. }
  420. }
  421. KScheduler::OnThreadAffinityMaskChanged(m_kernel, this, old_mask, active_core);
  422. }
  423. }
  424. // Allow performing thread suspension (if termination hasn't been requested).
  425. if (!this->IsTerminationRequested()) {
  426. // Update our allow flags.
  427. m_suspend_allowed_flags |= (1 << (static_cast<u32>(SuspendType::Thread) +
  428. static_cast<u32>(ThreadState::SuspendShift)));
  429. // Update our state.
  430. this->UpdateState();
  431. }
  432. // TODO(bunnei): Update our SVC access permissions.
  433. ASSERT(m_parent != nullptr);
  434. // Resume any threads that began waiting on us while we were pinned.
  435. for (auto it = m_pinned_waiter_list.begin(); it != m_pinned_waiter_list.end(); ++it) {
  436. it->EndWait(ResultSuccess);
  437. }
  438. }
  439. u16 KThread::GetUserDisableCount() const {
  440. if (!this->IsUserThread()) {
  441. // We only emulate TLS for user threads
  442. return {};
  443. }
  444. auto& memory = this->GetOwnerProcess()->GetMemory();
  445. return memory.Read16(m_tls_address + offsetof(ThreadLocalRegion, disable_count));
  446. }
  447. void KThread::SetInterruptFlag() {
  448. if (!this->IsUserThread()) {
  449. // We only emulate TLS for user threads
  450. return;
  451. }
  452. auto& memory = this->GetOwnerProcess()->GetMemory();
  453. memory.Write16(m_tls_address + offsetof(ThreadLocalRegion, interrupt_flag), 1);
  454. }
  455. void KThread::ClearInterruptFlag() {
  456. if (!this->IsUserThread()) {
  457. // We only emulate TLS for user threads
  458. return;
  459. }
  460. auto& memory = this->GetOwnerProcess()->GetMemory();
  461. memory.Write16(m_tls_address + offsetof(ThreadLocalRegion, interrupt_flag), 0);
  462. }
  463. Result KThread::GetCoreMask(s32* out_ideal_core, u64* out_affinity_mask) {
  464. KScopedSchedulerLock sl{m_kernel};
  465. // Get the virtual mask.
  466. *out_ideal_core = m_virtual_ideal_core_id;
  467. *out_affinity_mask = m_virtual_affinity_mask;
  468. R_SUCCEED();
  469. }
  470. Result KThread::GetPhysicalCoreMask(s32* out_ideal_core, u64* out_affinity_mask) {
  471. KScopedSchedulerLock sl{m_kernel};
  472. ASSERT(m_num_core_migration_disables >= 0);
  473. // Select between core mask and original core mask.
  474. if (m_num_core_migration_disables == 0) {
  475. *out_ideal_core = m_physical_ideal_core_id;
  476. *out_affinity_mask = m_physical_affinity_mask.GetAffinityMask();
  477. } else {
  478. *out_ideal_core = m_original_physical_ideal_core_id;
  479. *out_affinity_mask = m_original_physical_affinity_mask.GetAffinityMask();
  480. }
  481. R_SUCCEED();
  482. }
  483. Result KThread::SetCoreMask(s32 core_id, u64 v_affinity_mask) {
  484. ASSERT(m_parent != nullptr);
  485. ASSERT(v_affinity_mask != 0);
  486. KScopedLightLock lk(m_activity_pause_lock);
  487. // Set the core mask.
  488. u64 p_affinity_mask = 0;
  489. {
  490. KScopedSchedulerLock sl(m_kernel);
  491. ASSERT(m_num_core_migration_disables >= 0);
  492. // If we're updating, set our ideal virtual core.
  493. if (core_id != Svc::IdealCoreNoUpdate) {
  494. m_virtual_ideal_core_id = core_id;
  495. } else {
  496. // Preserve our ideal core id.
  497. core_id = m_virtual_ideal_core_id;
  498. R_UNLESS(((1ULL << core_id) & v_affinity_mask) != 0, ResultInvalidCombination);
  499. }
  500. // Set our affinity mask.
  501. m_virtual_affinity_mask = v_affinity_mask;
  502. // Translate the virtual core to a physical core.
  503. if (core_id >= 0) {
  504. core_id = Core::Hardware::VirtualToPhysicalCoreMap[core_id];
  505. }
  506. // Translate the virtual affinity mask to a physical one.
  507. while (v_affinity_mask != 0) {
  508. const u64 next = std::countr_zero(v_affinity_mask);
  509. v_affinity_mask &= ~(1ULL << next);
  510. p_affinity_mask |= (1ULL << Core::Hardware::VirtualToPhysicalCoreMap[next]);
  511. }
  512. // If we haven't disabled migration, perform an affinity change.
  513. if (m_num_core_migration_disables == 0) {
  514. const KAffinityMask old_mask = m_physical_affinity_mask;
  515. // Set our new ideals.
  516. m_physical_ideal_core_id = core_id;
  517. m_physical_affinity_mask.SetAffinityMask(p_affinity_mask);
  518. if (m_physical_affinity_mask.GetAffinityMask() != old_mask.GetAffinityMask()) {
  519. const s32 active_core = GetActiveCore();
  520. if (active_core >= 0 && !m_physical_affinity_mask.GetAffinity(active_core)) {
  521. const s32 new_core = static_cast<s32>(
  522. m_physical_ideal_core_id >= 0
  523. ? m_physical_ideal_core_id
  524. : Common::BitSize<u64>() - 1 -
  525. std::countl_zero(m_physical_affinity_mask.GetAffinityMask()));
  526. SetActiveCore(new_core);
  527. }
  528. KScheduler::OnThreadAffinityMaskChanged(m_kernel, this, old_mask, active_core);
  529. }
  530. } else {
  531. // Otherwise, we edit the original affinity for restoration later.
  532. m_original_physical_ideal_core_id = core_id;
  533. m_original_physical_affinity_mask.SetAffinityMask(p_affinity_mask);
  534. }
  535. }
  536. // Update the pinned waiter list.
  537. ThreadQueueImplForKThreadSetProperty wait_queue(m_kernel, std::addressof(m_pinned_waiter_list));
  538. {
  539. bool retry_update{};
  540. do {
  541. // Lock the scheduler.
  542. KScopedSchedulerLock sl(m_kernel);
  543. // Don't do any further management if our termination has been requested.
  544. R_SUCCEED_IF(this->IsTerminationRequested());
  545. // By default, we won't need to retry.
  546. retry_update = false;
  547. // Check if the thread is currently running.
  548. bool thread_is_current{};
  549. s32 thread_core;
  550. for (thread_core = 0; thread_core < static_cast<s32>(Core::Hardware::NUM_CPU_CORES);
  551. ++thread_core) {
  552. if (m_kernel.Scheduler(thread_core).GetSchedulerCurrentThread() == this) {
  553. thread_is_current = true;
  554. break;
  555. }
  556. }
  557. // If the thread is currently running, check whether it's no longer allowed under the
  558. // new mask.
  559. if (thread_is_current && ((1ULL << thread_core) & p_affinity_mask) == 0) {
  560. // If the thread is pinned, we want to wait until it's not pinned.
  561. if (this->GetStackParameters().is_pinned) {
  562. // Verify that the current thread isn't terminating.
  563. R_UNLESS(!GetCurrentThread(m_kernel).IsTerminationRequested(),
  564. ResultTerminationRequested);
  565. // Wait until the thread isn't pinned any more.
  566. m_pinned_waiter_list.push_back(GetCurrentThread(m_kernel));
  567. GetCurrentThread(m_kernel).BeginWait(std::addressof(wait_queue));
  568. } else {
  569. // If the thread isn't pinned, release the scheduler lock and retry until it's
  570. // not current.
  571. retry_update = true;
  572. }
  573. }
  574. } while (retry_update);
  575. }
  576. R_SUCCEED();
  577. }
  578. void KThread::SetBasePriority(s32 value) {
  579. ASSERT(Svc::HighestThreadPriority <= value && value <= Svc::LowestThreadPriority);
  580. KScopedSchedulerLock sl{m_kernel};
  581. // Change our base priority.
  582. m_base_priority = value;
  583. // Perform a priority restoration.
  584. RestorePriority(m_kernel, this);
  585. }
  586. KThread* KThread::GetLockOwner() const {
  587. return m_waiting_lock_info != nullptr ? m_waiting_lock_info->GetOwner() : nullptr;
  588. }
  589. void KThread::IncreaseBasePriority(s32 priority) {
  590. ASSERT(Svc::HighestThreadPriority <= priority && priority <= Svc::LowestThreadPriority);
  591. ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(m_kernel));
  592. ASSERT(!this->GetStackParameters().is_pinned);
  593. // Set our base priority.
  594. if (m_base_priority > priority) {
  595. m_base_priority = priority;
  596. // Perform a priority restoration.
  597. RestorePriority(m_kernel, this);
  598. }
  599. }
  600. void KThread::RequestSuspend(SuspendType type) {
  601. KScopedSchedulerLock sl{m_kernel};
  602. // Note the request in our flags.
  603. m_suspend_request_flags |=
  604. (1U << (static_cast<u32>(ThreadState::SuspendShift) + static_cast<u32>(type)));
  605. // Try to perform the suspend.
  606. this->TrySuspend();
  607. }
  608. void KThread::Resume(SuspendType type) {
  609. KScopedSchedulerLock sl{m_kernel};
  610. // Clear the request in our flags.
  611. m_suspend_request_flags &=
  612. ~(1U << (static_cast<u32>(ThreadState::SuspendShift) + static_cast<u32>(type)));
  613. // Update our state.
  614. this->UpdateState();
  615. }
  616. void KThread::WaitCancel() {
  617. KScopedSchedulerLock sl{m_kernel};
  618. // Check if we're waiting and cancellable.
  619. if (this->GetState() == ThreadState::Waiting && m_cancellable) {
  620. m_wait_cancelled = false;
  621. m_wait_queue->CancelWait(this, ResultCancelled, true);
  622. } else {
  623. // Otherwise, note that we cancelled a wait.
  624. m_wait_cancelled = true;
  625. }
  626. }
  627. void KThread::TrySuspend() {
  628. ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(m_kernel));
  629. ASSERT(this->IsSuspendRequested());
  630. // Ensure that we have no waiters.
  631. if (this->GetNumKernelWaiters() > 0) {
  632. return;
  633. }
  634. ASSERT(this->GetNumKernelWaiters() == 0);
  635. // Perform the suspend.
  636. this->UpdateState();
  637. }
  638. void KThread::UpdateState() {
  639. ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(m_kernel));
  640. // Set our suspend flags in state.
  641. const ThreadState old_state = m_thread_state.load(std::memory_order_relaxed);
  642. const auto new_state =
  643. static_cast<ThreadState>(this->GetSuspendFlags()) | (old_state & ThreadState::Mask);
  644. m_thread_state.store(new_state, std::memory_order_relaxed);
  645. // Note the state change in scheduler.
  646. if (new_state != old_state) {
  647. KScheduler::OnThreadStateChanged(m_kernel, this, old_state);
  648. }
  649. }
  650. void KThread::Continue() {
  651. ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(m_kernel));
  652. // Clear our suspend flags in state.
  653. const ThreadState old_state = m_thread_state.load(std::memory_order_relaxed);
  654. m_thread_state.store(old_state & ThreadState::Mask, std::memory_order_relaxed);
  655. // Note the state change in scheduler.
  656. KScheduler::OnThreadStateChanged(m_kernel, this, old_state);
  657. }
  658. void KThread::CloneFpuStatus() {
  659. // We shouldn't reach here when starting kernel threads.
  660. ASSERT(this->GetOwnerProcess() != nullptr);
  661. ASSERT(this->GetOwnerProcess() == GetCurrentProcessPointer(m_kernel));
  662. if (this->GetOwnerProcess()->Is64Bit()) {
  663. // Clone FPSR and FPCR.
  664. ThreadContext64 cur_ctx{};
  665. m_kernel.System().CurrentArmInterface().SaveContext(cur_ctx);
  666. this->GetContext64().fpcr = cur_ctx.fpcr;
  667. this->GetContext64().fpsr = cur_ctx.fpsr;
  668. } else {
  669. // Clone FPSCR.
  670. ThreadContext32 cur_ctx{};
  671. m_kernel.System().CurrentArmInterface().SaveContext(cur_ctx);
  672. this->GetContext32().fpscr = cur_ctx.fpscr;
  673. }
  674. }
  675. Result KThread::SetActivity(Svc::ThreadActivity activity) {
  676. // Lock ourselves.
  677. KScopedLightLock lk(m_activity_pause_lock);
  678. // Set the activity.
  679. {
  680. // Lock the scheduler.
  681. KScopedSchedulerLock sl(m_kernel);
  682. // Verify our state.
  683. const auto cur_state = this->GetState();
  684. R_UNLESS((cur_state == ThreadState::Waiting || cur_state == ThreadState::Runnable),
  685. ResultInvalidState);
  686. // Either pause or resume.
  687. if (activity == Svc::ThreadActivity::Paused) {
  688. // Verify that we're not suspended.
  689. R_UNLESS(!this->IsSuspendRequested(SuspendType::Thread), ResultInvalidState);
  690. // Suspend.
  691. this->RequestSuspend(SuspendType::Thread);
  692. } else {
  693. ASSERT(activity == Svc::ThreadActivity::Runnable);
  694. // Verify that we're suspended.
  695. R_UNLESS(this->IsSuspendRequested(SuspendType::Thread), ResultInvalidState);
  696. // Resume.
  697. this->Resume(SuspendType::Thread);
  698. }
  699. }
  700. // If the thread is now paused, update the pinned waiter list.
  701. if (activity == Svc::ThreadActivity::Paused) {
  702. ThreadQueueImplForKThreadSetProperty wait_queue(m_kernel,
  703. std::addressof(m_pinned_waiter_list));
  704. bool thread_is_current{};
  705. do {
  706. // Lock the scheduler.
  707. KScopedSchedulerLock sl(m_kernel);
  708. // Don't do any further management if our termination has been requested.
  709. R_SUCCEED_IF(this->IsTerminationRequested());
  710. // By default, treat the thread as not current.
  711. thread_is_current = false;
  712. // Check whether the thread is pinned.
  713. if (this->GetStackParameters().is_pinned) {
  714. // Verify that the current thread isn't terminating.
  715. R_UNLESS(!GetCurrentThread(m_kernel).IsTerminationRequested(),
  716. ResultTerminationRequested);
  717. // Wait until the thread isn't pinned any more.
  718. m_pinned_waiter_list.push_back(GetCurrentThread(m_kernel));
  719. GetCurrentThread(m_kernel).BeginWait(std::addressof(wait_queue));
  720. } else {
  721. // Check if the thread is currently running.
  722. // If it is, we'll need to retry.
  723. for (auto i = 0; i < static_cast<s32>(Core::Hardware::NUM_CPU_CORES); ++i) {
  724. if (m_kernel.Scheduler(i).GetSchedulerCurrentThread() == this) {
  725. thread_is_current = true;
  726. break;
  727. }
  728. }
  729. }
  730. } while (thread_is_current);
  731. }
  732. R_SUCCEED();
  733. }
  734. Result KThread::GetThreadContext3(Common::ScratchBuffer<u8>& out) {
  735. // Lock ourselves.
  736. KScopedLightLock lk{m_activity_pause_lock};
  737. // Get the context.
  738. {
  739. // Lock the scheduler.
  740. KScopedSchedulerLock sl{m_kernel};
  741. // Verify that we're suspended.
  742. R_UNLESS(this->IsSuspendRequested(SuspendType::Thread), ResultInvalidState);
  743. // If we're not terminating, get the thread's user context.
  744. if (!this->IsTerminationRequested()) {
  745. if (m_parent->Is64Bit()) {
  746. // Mask away mode bits, interrupt bits, IL bit, and other reserved bits.
  747. auto context = GetContext64();
  748. context.pstate &= 0xFF0FFE20;
  749. out.resize_destructive(sizeof(context));
  750. std::memcpy(out.data(), std::addressof(context), sizeof(context));
  751. } else {
  752. // Mask away mode bits, interrupt bits, IL bit, and other reserved bits.
  753. auto context = GetContext32();
  754. context.cpsr &= 0xFF0FFE20;
  755. out.resize_destructive(sizeof(context));
  756. std::memcpy(out.data(), std::addressof(context), sizeof(context));
  757. }
  758. }
  759. }
  760. R_SUCCEED();
  761. }
  762. void KThread::AddHeldLock(LockWithPriorityInheritanceInfo* lock_info) {
  763. ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(m_kernel));
  764. // Set ourselves as the lock's owner.
  765. lock_info->SetOwner(this);
  766. // Add the lock to our held list.
  767. m_held_lock_info_list.push_front(*lock_info);
  768. }
  769. KThread::LockWithPriorityInheritanceInfo* KThread::FindHeldLock(KProcessAddress address_key,
  770. bool is_kernel_address_key) {
  771. ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(m_kernel));
  772. // Try to find an existing held lock.
  773. for (auto& held_lock : m_held_lock_info_list) {
  774. if (held_lock.GetAddressKey() == address_key &&
  775. held_lock.GetIsKernelAddressKey() == is_kernel_address_key) {
  776. return std::addressof(held_lock);
  777. }
  778. }
  779. return nullptr;
  780. }
  781. void KThread::AddWaiterImpl(KThread* thread) {
  782. ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(m_kernel));
  783. ASSERT(thread->GetConditionVariableTree() == nullptr);
  784. // Get the thread's address key.
  785. const auto address_key = thread->GetAddressKey();
  786. const auto is_kernel_address_key = thread->GetIsKernelAddressKey();
  787. // Keep track of how many kernel waiters we have.
  788. if (is_kernel_address_key) {
  789. ASSERT((m_num_kernel_waiters++) >= 0);
  790. KScheduler::SetSchedulerUpdateNeeded(m_kernel);
  791. }
  792. // Get the relevant lock info.
  793. auto* lock_info = this->FindHeldLock(address_key, is_kernel_address_key);
  794. if (lock_info == nullptr) {
  795. // Create a new lock for the address key.
  796. lock_info =
  797. LockWithPriorityInheritanceInfo::Create(m_kernel, address_key, is_kernel_address_key);
  798. // Add the new lock to our list.
  799. this->AddHeldLock(lock_info);
  800. }
  801. // Add the thread as waiter to the lock info.
  802. lock_info->AddWaiter(thread);
  803. }
  804. void KThread::RemoveWaiterImpl(KThread* thread) {
  805. ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(m_kernel));
  806. // Keep track of how many kernel waiters we have.
  807. if (thread->GetIsKernelAddressKey()) {
  808. ASSERT((m_num_kernel_waiters--) > 0);
  809. KScheduler::SetSchedulerUpdateNeeded(m_kernel);
  810. }
  811. // Get the info for the lock the thread is waiting on.
  812. auto* lock_info = thread->GetWaitingLockInfo();
  813. ASSERT(lock_info->GetOwner() == this);
  814. // Remove the waiter.
  815. if (lock_info->RemoveWaiter(thread)) {
  816. m_held_lock_info_list.erase(m_held_lock_info_list.iterator_to(*lock_info));
  817. LockWithPriorityInheritanceInfo::Free(m_kernel, lock_info);
  818. }
  819. }
  820. void KThread::RestorePriority(KernelCore& kernel, KThread* thread) {
  821. ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(kernel));
  822. while (thread != nullptr) {
  823. // We want to inherit priority where possible.
  824. s32 new_priority = thread->GetBasePriority();
  825. for (const auto& held_lock : thread->m_held_lock_info_list) {
  826. new_priority =
  827. std::min(new_priority, held_lock.GetHighestPriorityWaiter()->GetPriority());
  828. }
  829. // If the priority we would inherit is not different from ours, don't do anything.
  830. if (new_priority == thread->GetPriority()) {
  831. return;
  832. }
  833. // Get the owner of whatever lock this thread is waiting on.
  834. KThread* const lock_owner = thread->GetLockOwner();
  835. // If the thread is waiting on some lock, remove it as a waiter to prevent violating red
  836. // black tree invariants.
  837. if (lock_owner != nullptr) {
  838. lock_owner->RemoveWaiterImpl(thread);
  839. }
  840. // Ensure we don't violate condition variable red black tree invariants.
  841. if (auto* cv_tree = thread->GetConditionVariableTree(); cv_tree != nullptr) {
  842. BeforeUpdatePriority(kernel, cv_tree, thread);
  843. }
  844. // Change the priority.
  845. const s32 old_priority = thread->GetPriority();
  846. thread->SetPriority(new_priority);
  847. // Restore the condition variable, if relevant.
  848. if (auto* cv_tree = thread->GetConditionVariableTree(); cv_tree != nullptr) {
  849. AfterUpdatePriority(kernel, cv_tree, thread);
  850. }
  851. // If we removed the thread from some lock's waiting list, add it back.
  852. if (lock_owner != nullptr) {
  853. lock_owner->AddWaiterImpl(thread);
  854. }
  855. // Update the scheduler.
  856. KScheduler::OnThreadPriorityChanged(kernel, thread, old_priority);
  857. // Continue inheriting priority.
  858. thread = lock_owner;
  859. }
  860. }
  861. void KThread::AddWaiter(KThread* thread) {
  862. this->AddWaiterImpl(thread);
  863. // If the thread has a higher priority than us, we should inherit.
  864. if (thread->GetPriority() < this->GetPriority()) {
  865. RestorePriority(m_kernel, this);
  866. }
  867. }
  868. void KThread::RemoveWaiter(KThread* thread) {
  869. this->RemoveWaiterImpl(thread);
  870. // If our priority is the same as the thread's (and we've inherited), we may need to restore to
  871. // lower priority.
  872. if (this->GetPriority() == thread->GetPriority() &&
  873. this->GetPriority() < this->GetBasePriority()) {
  874. RestorePriority(m_kernel, this);
  875. }
  876. }
  877. KThread* KThread::RemoveWaiterByKey(bool* out_has_waiters, KProcessAddress key,
  878. bool is_kernel_address_key_) {
  879. ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(m_kernel));
  880. // Get the relevant lock info.
  881. auto* lock_info = this->FindHeldLock(key, is_kernel_address_key_);
  882. if (lock_info == nullptr) {
  883. *out_has_waiters = false;
  884. return nullptr;
  885. }
  886. // Remove the lock info from our held list.
  887. m_held_lock_info_list.erase(m_held_lock_info_list.iterator_to(*lock_info));
  888. // Keep track of how many kernel waiters we have.
  889. if (lock_info->GetIsKernelAddressKey()) {
  890. m_num_kernel_waiters -= lock_info->GetWaiterCount();
  891. ASSERT(m_num_kernel_waiters >= 0);
  892. KScheduler::SetSchedulerUpdateNeeded(m_kernel);
  893. }
  894. ASSERT(lock_info->GetWaiterCount() > 0);
  895. // Remove the highest priority waiter from the lock to be the next owner.
  896. KThread* next_lock_owner = lock_info->GetHighestPriorityWaiter();
  897. if (lock_info->RemoveWaiter(next_lock_owner)) {
  898. // The new owner was the only waiter.
  899. *out_has_waiters = false;
  900. // Free the lock info, since it has no waiters.
  901. LockWithPriorityInheritanceInfo::Free(m_kernel, lock_info);
  902. } else {
  903. // There are additional waiters on the lock.
  904. *out_has_waiters = true;
  905. // Add the lock to the new owner's held list.
  906. next_lock_owner->AddHeldLock(lock_info);
  907. // Keep track of any kernel waiters for the new owner.
  908. if (lock_info->GetIsKernelAddressKey()) {
  909. next_lock_owner->m_num_kernel_waiters += lock_info->GetWaiterCount();
  910. ASSERT(next_lock_owner->m_num_kernel_waiters > 0);
  911. // NOTE: No need to set scheduler update needed, because we will have already done so
  912. // when removing earlier.
  913. }
  914. }
  915. // If our priority is the same as the next owner's (and we've inherited), we may need to restore
  916. // to lower priority.
  917. if (this->GetPriority() == next_lock_owner->GetPriority() &&
  918. this->GetPriority() < this->GetBasePriority()) {
  919. RestorePriority(m_kernel, this);
  920. // NOTE: No need to restore priority on the next lock owner, because it was already the
  921. // highest priority waiter on the lock.
  922. }
  923. // Return the next lock owner.
  924. return next_lock_owner;
  925. }
  926. Result KThread::Run() {
  927. while (true) {
  928. KScopedSchedulerLock lk{m_kernel};
  929. // If either this thread or the current thread are requesting termination, note it.
  930. R_UNLESS(!this->IsTerminationRequested(), ResultTerminationRequested);
  931. R_UNLESS(!GetCurrentThread(m_kernel).IsTerminationRequested(), ResultTerminationRequested);
  932. // Ensure our thread state is correct.
  933. R_UNLESS(this->GetState() == ThreadState::Initialized, ResultInvalidState);
  934. // If the current thread has been asked to suspend, suspend it and retry.
  935. if (GetCurrentThread(m_kernel).IsSuspended()) {
  936. GetCurrentThread(m_kernel).UpdateState();
  937. continue;
  938. }
  939. // If we're not a kernel thread and we've been asked to suspend, suspend ourselves.
  940. if (KProcess* owner = this->GetOwnerProcess(); owner != nullptr) {
  941. if (this->IsUserThread() && this->IsSuspended()) {
  942. this->UpdateState();
  943. }
  944. owner->IncrementRunningThreadCount();
  945. }
  946. // Open a reference, now that we're running.
  947. this->Open();
  948. // Set our state and finish.
  949. this->SetState(ThreadState::Runnable);
  950. R_SUCCEED();
  951. }
  952. }
  953. void KThread::Exit() {
  954. ASSERT(this == GetCurrentThreadPointer(m_kernel));
  955. // Release the thread resource hint, running thread count from parent.
  956. if (m_parent != nullptr) {
  957. m_parent->GetResourceLimit()->Release(Kernel::LimitableResource::ThreadCountMax, 0, 1);
  958. m_resource_limit_release_hint = true;
  959. m_parent->DecrementRunningThreadCount();
  960. }
  961. // Perform termination.
  962. {
  963. KScopedSchedulerLock sl{m_kernel};
  964. // Disallow all suspension.
  965. m_suspend_allowed_flags = 0;
  966. this->UpdateState();
  967. // Disallow all suspension.
  968. m_suspend_allowed_flags = 0;
  969. // Start termination.
  970. this->StartTermination();
  971. // Register the thread as a work task.
  972. KWorkerTaskManager::AddTask(m_kernel, KWorkerTaskManager::WorkerType::Exit, this);
  973. }
  974. UNREACHABLE_MSG("KThread::Exit() would return");
  975. }
  976. Result KThread::Terminate() {
  977. ASSERT(this != GetCurrentThreadPointer(m_kernel));
  978. // Request the thread terminate if it hasn't already.
  979. if (const auto new_state = this->RequestTerminate(); new_state != ThreadState::Terminated) {
  980. // If the thread isn't terminated, wait for it to terminate.
  981. s32 index;
  982. KSynchronizationObject* objects[] = {this};
  983. R_TRY(KSynchronizationObject::Wait(m_kernel, std::addressof(index), objects, 1,
  984. Svc::WaitInfinite));
  985. }
  986. R_SUCCEED();
  987. }
  988. ThreadState KThread::RequestTerminate() {
  989. ASSERT(this != GetCurrentThreadPointer(m_kernel));
  990. KScopedSchedulerLock sl{m_kernel};
  991. // Determine if this is the first termination request.
  992. const bool first_request = [&]() -> bool {
  993. // Perform an atomic compare-and-swap from false to true.
  994. bool expected = false;
  995. return m_termination_requested.compare_exchange_strong(expected, true);
  996. }();
  997. // If this is the first request, start termination procedure.
  998. if (first_request) {
  999. // If the thread is in initialized state, just change state to terminated.
  1000. if (this->GetState() == ThreadState::Initialized) {
  1001. m_thread_state = ThreadState::Terminated;
  1002. return ThreadState::Terminated;
  1003. }
  1004. // Register the terminating dpc.
  1005. this->RegisterDpc(DpcFlag::Terminating);
  1006. // If the thread is pinned, unpin it.
  1007. if (this->GetStackParameters().is_pinned) {
  1008. this->GetOwnerProcess()->UnpinThread(this);
  1009. }
  1010. // If the thread is suspended, continue it.
  1011. if (this->IsSuspended()) {
  1012. m_suspend_allowed_flags = 0;
  1013. this->UpdateState();
  1014. }
  1015. // Change the thread's priority to be higher than any system thread's.
  1016. this->IncreaseBasePriority(TerminatingThreadPriority);
  1017. // If the thread is runnable, send a termination interrupt to other cores.
  1018. if (this->GetState() == ThreadState::Runnable) {
  1019. if (const u64 core_mask = m_physical_affinity_mask.GetAffinityMask() &
  1020. ~(1ULL << GetCurrentCoreId(m_kernel));
  1021. core_mask != 0) {
  1022. Kernel::KInterruptManager::SendInterProcessorInterrupt(m_kernel, core_mask);
  1023. }
  1024. }
  1025. // Wake up the thread.
  1026. if (this->GetState() == ThreadState::Waiting) {
  1027. m_wait_queue->CancelWait(this, ResultTerminationRequested, true);
  1028. }
  1029. }
  1030. return this->GetState();
  1031. }
  1032. Result KThread::Sleep(s64 timeout) {
  1033. ASSERT(!KScheduler::IsSchedulerLockedByCurrentThread(m_kernel));
  1034. ASSERT(this == GetCurrentThreadPointer(m_kernel));
  1035. ASSERT(timeout > 0);
  1036. ThreadQueueImplForKThreadSleep wait_queue(m_kernel);
  1037. KHardwareTimer* timer{};
  1038. {
  1039. // Setup the scheduling lock and sleep.
  1040. KScopedSchedulerLockAndSleep slp(m_kernel, std::addressof(timer), this, timeout);
  1041. // Check if the thread should terminate.
  1042. if (this->IsTerminationRequested()) {
  1043. slp.CancelSleep();
  1044. R_THROW(ResultTerminationRequested);
  1045. }
  1046. // Wait for the sleep to end.
  1047. wait_queue.SetHardwareTimer(timer);
  1048. this->BeginWait(std::addressof(wait_queue));
  1049. this->SetWaitReasonForDebugging(ThreadWaitReasonForDebugging::Sleep);
  1050. }
  1051. R_SUCCEED();
  1052. }
  1053. void KThread::RequestDummyThreadWait() {
  1054. ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(m_kernel));
  1055. ASSERT(this->IsDummyThread());
  1056. // We will block when the scheduler lock is released.
  1057. std::scoped_lock lock{m_dummy_thread_mutex};
  1058. m_dummy_thread_runnable = false;
  1059. }
  1060. void KThread::DummyThreadBeginWait() {
  1061. if (!this->IsDummyThread() || m_kernel.IsPhantomModeForSingleCore()) {
  1062. // Occurs in single core mode.
  1063. return;
  1064. }
  1065. // Block until runnable is no longer false.
  1066. std::unique_lock lock{m_dummy_thread_mutex};
  1067. m_dummy_thread_cv.wait(lock, [this] { return m_dummy_thread_runnable; });
  1068. }
  1069. void KThread::DummyThreadEndWait() {
  1070. ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(m_kernel));
  1071. ASSERT(this->IsDummyThread());
  1072. // Wake up the waiting thread.
  1073. {
  1074. std::scoped_lock lock{m_dummy_thread_mutex};
  1075. m_dummy_thread_runnable = true;
  1076. }
  1077. m_dummy_thread_cv.notify_one();
  1078. }
  1079. void KThread::BeginWait(KThreadQueue* queue) {
  1080. // Set our state as waiting.
  1081. this->SetState(ThreadState::Waiting);
  1082. // Set our wait queue.
  1083. m_wait_queue = queue;
  1084. }
  1085. void KThread::NotifyAvailable(KSynchronizationObject* signaled_object, Result wait_result) {
  1086. // Lock the scheduler.
  1087. KScopedSchedulerLock sl(m_kernel);
  1088. // If we're waiting, notify our queue that we're available.
  1089. if (this->GetState() == ThreadState::Waiting) {
  1090. m_wait_queue->NotifyAvailable(this, signaled_object, wait_result);
  1091. }
  1092. }
  1093. void KThread::EndWait(Result wait_result) {
  1094. // Lock the scheduler.
  1095. KScopedSchedulerLock sl(m_kernel);
  1096. // If we're waiting, notify our queue that we're available.
  1097. if (this->GetState() == ThreadState::Waiting) {
  1098. if (m_wait_queue == nullptr) {
  1099. // This should never happen, but avoid a hard crash below to get this logged.
  1100. ASSERT_MSG(false, "wait_queue is nullptr!");
  1101. return;
  1102. }
  1103. m_wait_queue->EndWait(this, wait_result);
  1104. }
  1105. }
  1106. void KThread::CancelWait(Result wait_result, bool cancel_timer_task) {
  1107. // Lock the scheduler.
  1108. KScopedSchedulerLock sl(m_kernel);
  1109. // If we're waiting, notify our queue that we're available.
  1110. if (this->GetState() == ThreadState::Waiting) {
  1111. m_wait_queue->CancelWait(this, wait_result, cancel_timer_task);
  1112. }
  1113. }
  1114. void KThread::SetState(ThreadState state) {
  1115. KScopedSchedulerLock sl{m_kernel};
  1116. // Clear debugging state
  1117. this->SetWaitReasonForDebugging({});
  1118. const ThreadState old_state = m_thread_state.load(std::memory_order_relaxed);
  1119. m_thread_state.store(
  1120. static_cast<ThreadState>((old_state & ~ThreadState::Mask) | (state & ThreadState::Mask)),
  1121. std::memory_order_relaxed);
  1122. if (m_thread_state.load(std::memory_order_relaxed) != old_state) {
  1123. KScheduler::OnThreadStateChanged(m_kernel, this, old_state);
  1124. }
  1125. }
  1126. std::shared_ptr<Common::Fiber>& KThread::GetHostContext() {
  1127. return m_host_context;
  1128. }
  1129. void SetCurrentThread(KernelCore& kernel, KThread* thread) {
  1130. kernel.SetCurrentEmuThread(thread);
  1131. }
  1132. KThread* GetCurrentThreadPointer(KernelCore& kernel) {
  1133. return kernel.GetCurrentEmuThread();
  1134. }
  1135. KThread& GetCurrentThread(KernelCore& kernel) {
  1136. return *GetCurrentThreadPointer(kernel);
  1137. }
  1138. KProcess* GetCurrentProcessPointer(KernelCore& kernel) {
  1139. return GetCurrentThread(kernel).GetOwnerProcess();
  1140. }
  1141. KProcess& GetCurrentProcess(KernelCore& kernel) {
  1142. return *GetCurrentProcessPointer(kernel);
  1143. }
  1144. s32 GetCurrentCoreId(KernelCore& kernel) {
  1145. return GetCurrentThread(kernel).GetCurrentCore();
  1146. }
  1147. Core::Memory::Memory& GetCurrentMemory(KernelCore& kernel) {
  1148. // TODO: per-process memory
  1149. return kernel.System().ApplicationMemory();
  1150. }
  1151. KScopedDisableDispatch::~KScopedDisableDispatch() {
  1152. // If we are shutting down the kernel, none of this is relevant anymore.
  1153. if (m_kernel.IsShuttingDown()) {
  1154. return;
  1155. }
  1156. if (GetCurrentThread(m_kernel).GetDisableDispatchCount() <= 1) {
  1157. auto* scheduler = m_kernel.CurrentScheduler();
  1158. if (scheduler && !m_kernel.IsPhantomModeForSingleCore()) {
  1159. scheduler->RescheduleCurrentCore();
  1160. } else {
  1161. KScheduler::RescheduleCurrentHLEThread(m_kernel);
  1162. }
  1163. } else {
  1164. GetCurrentThread(m_kernel).EnableDispatch();
  1165. }
  1166. }
  1167. } // namespace Kernel