k_thread.cpp 49 KB

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