|  |  |  | @@ -308,6 +308,37 @@ void WaitCurrentThread(WaitType wait_type, Handle wait_handle, VAddr wait_addres | 
		
	
		
			
				|  |  |  |  |     GetCurrentThread()->wait_address = wait_address; | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | /// Event type for the thread wake up event | 
		
	
		
			
				|  |  |  |  | static int ThreadWakeupEventType = -1; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | /// Callback that will wake up the thread it was scheduled for | 
		
	
		
			
				|  |  |  |  | static void ThreadWakeupCallback(u64 parameter, int cycles_late) { | 
		
	
		
			
				|  |  |  |  |     Handle handle = static_cast<Handle>(parameter); | 
		
	
		
			
				|  |  |  |  |     Thread* thread = Kernel::g_handle_table.Get<Thread>(handle); | 
		
	
		
			
				|  |  |  |  |     if (thread == nullptr) { | 
		
	
		
			
				|  |  |  |  |         LOG_ERROR(Kernel, "Thread doesn't exist %u", handle); | 
		
	
		
			
				|  |  |  |  |         return; | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |     Kernel::ResumeThreadFromWait(handle); | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | void WakeThreadAfterDelay(Handle handle, s64 nanoseconds) { | 
		
	
		
			
				|  |  |  |  |     // Don't schedule a wakeup if the thread wants to wait forever | 
		
	
		
			
				|  |  |  |  |     if (nanoseconds == -1) | 
		
	
		
			
				|  |  |  |  |         return; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |     Thread* thread = Kernel::g_handle_table.Get<Thread>(handle); | 
		
	
		
			
				|  |  |  |  |     if (thread == nullptr) { | 
		
	
		
			
				|  |  |  |  |         LOG_ERROR(Kernel, "Thread doesn't exist %u", handle); | 
		
	
		
			
				|  |  |  |  |         return; | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |     u64 microseconds = nanoseconds / 1000; | 
		
	
		
			
				|  |  |  |  |     CoreTiming::ScheduleEvent(usToCycles(microseconds), ThreadWakeupEventType, handle); | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | /// Resumes a thread from waiting by marking it as "ready" | 
		
	
		
			
				|  |  |  |  | void ResumeThreadFromWait(Handle handle) { | 
		
	
		
			
				|  |  |  |  |     Thread* thread = Kernel::g_handle_table.Get<Thread>(handle); | 
		
	
	
		
			
				
					
					|  |  |  | @@ -499,14 +530,6 @@ void Reschedule() { | 
		
	
		
			
				|  |  |  |  |                 thread->GetHandle(), thread->current_priority, thread->status, thread->wait_type, thread->wait_handle); | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |     // TODO(bunnei): Hack - There is no timing mechanism yet to wake up a thread if it has been put | 
		
	
		
			
				|  |  |  |  |     // to sleep. So, we'll just immediately set it to "ready" again after an attempted context | 
		
	
		
			
				|  |  |  |  |     // switch has occurred. This results in the current thread yielding on a sleep once, and then it | 
		
	
		
			
				|  |  |  |  |     // will immediately be placed back in the queue for execution. | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |     if (CheckWaitType(prev, WAITTYPE_SLEEP)) | 
		
	
		
			
				|  |  |  |  |         ResumeThreadFromWait(prev->GetHandle()); | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | bool IsIdleThread(Handle handle) { | 
		
	
	
		
			
				
					
					|  |  |  | @@ -533,6 +556,7 @@ ResultCode GetThreadId(u32* thread_id, Handle handle) { | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | void ThreadingInit() { | 
		
	
		
			
				|  |  |  |  |     next_thread_id = INITIAL_THREAD_ID; | 
		
	
		
			
				|  |  |  |  |     ThreadWakeupEventType = CoreTiming::RegisterEvent("ThreadWakeupCallback", ThreadWakeupCallback); | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | void ThreadingShutdown() { | 
		
	
	
		
			
				
					
					|  |  |  |   |