| 
									
										
										
										
											2017-05-29 15:45:30 -07:00
										 |  |  | // Copyright 2014 Citra Emulator Project
 | 
					
						
							|  |  |  | // Licensed under GPLv2 or any later version
 | 
					
						
							|  |  |  | // Refer to the license.txt file included.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #pragma once
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <vector>
 | 
					
						
							|  |  |  | #include <boost/smart_ptr/intrusive_ptr.hpp>
 | 
					
						
							| 
									
										
										
										
											2018-08-01 22:40:00 -04:00
										 |  |  | #include "core/hle/kernel/object.h"
 | 
					
						
							| 
									
										
										
										
											2017-05-29 15:45:30 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | namespace Kernel { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-28 12:30:33 -04:00
										 |  |  | class KernelCore; | 
					
						
							| 
									
										
										
										
											2017-05-29 15:45:30 -07:00
										 |  |  | class Thread; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /// Class that represents a Kernel object that a thread can be waiting on
 | 
					
						
							|  |  |  | class WaitObject : public Object { | 
					
						
							|  |  |  | public: | 
					
						
							| 
									
										
										
										
											2018-08-28 12:30:33 -04:00
										 |  |  |     explicit WaitObject(KernelCore& kernel); | 
					
						
							|  |  |  |     ~WaitObject() override; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-29 15:45:30 -07:00
										 |  |  |     /**
 | 
					
						
							|  |  |  |      * Check if the specified thread should wait until the object is available | 
					
						
							|  |  |  |      * @param thread The thread about which we're deciding. | 
					
						
							|  |  |  |      * @return True if the current thread should wait due to this object being unavailable | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2019-04-01 18:19:42 -04:00
										 |  |  |     virtual bool ShouldWait(const Thread* thread) const = 0; | 
					
						
							| 
									
										
										
										
											2017-05-29 15:45:30 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /// Acquire/lock the object for the specified thread if it is available
 | 
					
						
							|  |  |  |     virtual void Acquire(Thread* thread) = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /**
 | 
					
						
							|  |  |  |      * Add a thread to wait on this object | 
					
						
							|  |  |  |      * @param thread Pointer to thread to add | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2019-01-30 12:41:17 -05:00
										 |  |  |     void AddWaitingThread(SharedPtr<Thread> thread); | 
					
						
							| 
									
										
										
										
											2017-05-29 15:45:30 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /**
 | 
					
						
							|  |  |  |      * Removes a thread from waiting on this object (e.g. if it was resumed already) | 
					
						
							|  |  |  |      * @param thread Pointer to thread to remove | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2019-01-30 12:41:17 -05:00
										 |  |  |     void RemoveWaitingThread(Thread* thread); | 
					
						
							| 
									
										
										
										
											2017-05-29 15:45:30 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /**
 | 
					
						
							|  |  |  |      * Wake up all threads waiting on this object that can be awoken, in priority order, | 
					
						
							|  |  |  |      * and set the synchronization result and output of the thread. | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2019-01-30 12:41:17 -05:00
										 |  |  |     void WakeupAllWaitingThreads(); | 
					
						
							| 
									
										
										
										
											2017-05-29 15:45:30 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-07 16:33:41 -05:00
										 |  |  |     /**
 | 
					
						
							|  |  |  |      * Wakes up a single thread waiting on this object. | 
					
						
							|  |  |  |      * @param thread Thread that is waiting on this object to wakeup. | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     void WakeupWaitingThread(SharedPtr<Thread> thread); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-29 15:45:30 -07:00
										 |  |  |     /// Obtains the highest priority thread that is ready to run from this object's waiting list.
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:44:31 -04:00
										 |  |  |     SharedPtr<Thread> GetHighestPriorityReadyThread() const; | 
					
						
							| 
									
										
										
										
											2017-05-29 15:45:30 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /// Get a const reference to the waiting threads list for debug use
 | 
					
						
							|  |  |  |     const std::vector<SharedPtr<Thread>>& GetWaitingThreads() const; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | private: | 
					
						
							|  |  |  |     /// Threads waiting for this object to become available
 | 
					
						
							|  |  |  |     std::vector<SharedPtr<Thread>> waiting_threads; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Specialization of DynamicObjectCast for WaitObjects
 | 
					
						
							|  |  |  | template <> | 
					
						
							|  |  |  | inline SharedPtr<WaitObject> DynamicObjectCast<WaitObject>(SharedPtr<Object> object) { | 
					
						
							|  |  |  |     if (object != nullptr && object->IsWaitable()) { | 
					
						
							| 
									
										
										
										
											2018-09-28 02:10:22 -04:00
										 |  |  |         return boost::static_pointer_cast<WaitObject>(object); | 
					
						
							| 
									
										
										
										
											2017-05-29 15:45:30 -07:00
										 |  |  |     } | 
					
						
							|  |  |  |     return nullptr; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } // namespace Kernel
 |