mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 05:40:04 +00:00 
			
		
		
		
	Merge pull request #3091 from Subv/hle_request_delat
Kernel/IPC: Add a small delay after each SyncRequest to prevent thread starvation.
This commit is contained in:
		
						commit
						2146311ad1
					
				
					 1 changed files with 23 additions and 5 deletions
				
			
		|  | @ -67,14 +67,32 @@ ResultCode ServerSession::HandleSyncRequest(SharedPtr<Thread> thread) { | ||||||
|     // If this ServerSession has an associated HLE handler, forward the request to it.
 |     // If this ServerSession has an associated HLE handler, forward the request to it.
 | ||||||
|     if (hle_handler != nullptr) { |     if (hle_handler != nullptr) { | ||||||
|         hle_handler->HandleSyncRequest(SharedPtr<ServerSession>(this)); |         hle_handler->HandleSyncRequest(SharedPtr<ServerSession>(this)); | ||||||
|     } else { |     } | ||||||
|  | 
 | ||||||
|  |     if (thread->status == THREADSTATUS_RUNNING) { | ||||||
|         // Put the thread to sleep until the server replies, it will be awoken in
 |         // Put the thread to sleep until the server replies, it will be awoken in
 | ||||||
|         // svcReplyAndReceive.
 |         // svcReplyAndReceive for LLE servers.
 | ||||||
|         thread->status = THREADSTATUS_WAIT_IPC; |         thread->status = THREADSTATUS_WAIT_IPC; | ||||||
|  | 
 | ||||||
|  |         if (hle_handler != nullptr) { | ||||||
|  |             // For HLE services, we put the request threads to sleep for a short duration to
 | ||||||
|  |             // simulate IPC overhead, but only if the HLE handler didn't put the thread to sleep for
 | ||||||
|  |             // other reasons like an async callback. The IPC overhead is needed to prevent
 | ||||||
|  |             // starvation when a thread only does sync requests to HLE services while a
 | ||||||
|  |             // lower-priority thread is waiting to run.
 | ||||||
|  | 
 | ||||||
|  |             // This delay was approximated in a homebrew application by measuring the average time
 | ||||||
|  |             // it takes for svcSendSyncRequest to return when performing the SetLcdForceBlack IPC
 | ||||||
|  |             // request to the GSP:GPU service in a n3DS with firmware 11.6. The measured values have
 | ||||||
|  |             // a high variance and vary between models.
 | ||||||
|  |             static constexpr u64 IPCDelayNanoseconds = 39000; | ||||||
|  |             thread->WakeAfterDelay(IPCDelayNanoseconds); | ||||||
|  |         } else { | ||||||
|             // Add the thread to the list of threads that have issued a sync request with this
 |             // Add the thread to the list of threads that have issued a sync request with this
 | ||||||
|             // server.
 |             // server.
 | ||||||
|             pending_requesting_threads.push_back(std::move(thread)); |             pending_requesting_threads.push_back(std::move(thread)); | ||||||
|         } |         } | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|     // If this ServerSession does not have an HLE implementation, just wake up the threads waiting
 |     // If this ServerSession does not have an HLE implementation, just wake up the threads waiting
 | ||||||
|     // on it.
 |     // on it.
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue