mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 05:40:04 +00:00 
			
		
		
		
	Merge pull request #5231 from hamish-milne/fix-address-arbiter-serialization
Fix Address Arbiter serialization
This commit is contained in:
		
						commit
						8a69172570
					
				
					 2 changed files with 64 additions and 11 deletions
				
			
		|  | @ -16,8 +16,6 @@ | ||||||
| ////////////////////////////////////////////////////////////////////////////////////////////////////
 | ////////////////////////////////////////////////////////////////////////////////////////////////////
 | ||||||
| // Kernel namespace
 | // Kernel namespace
 | ||||||
| 
 | 
 | ||||||
| SERIALIZE_EXPORT_IMPL(Kernel::AddressArbiter) |  | ||||||
| 
 |  | ||||||
| namespace Kernel { | namespace Kernel { | ||||||
| 
 | 
 | ||||||
| void AddressArbiter::WaitThread(std::shared_ptr<Thread> thread, VAddr wait_address) { | void AddressArbiter::WaitThread(std::shared_ptr<Thread> thread, VAddr wait_address) { | ||||||
|  | @ -69,7 +67,8 @@ std::shared_ptr<Thread> AddressArbiter::ResumeHighestPriorityThread(VAddr addres | ||||||
|     return thread; |     return thread; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| AddressArbiter::AddressArbiter(KernelSystem& kernel) : Object(kernel), kernel(kernel) {} | AddressArbiter::AddressArbiter(KernelSystem& kernel) | ||||||
|  |     : Object(kernel), kernel(kernel), timeout_callback(std::make_shared<Callback>(*this)) {} | ||||||
| AddressArbiter::~AddressArbiter() {} | AddressArbiter::~AddressArbiter() {} | ||||||
| 
 | 
 | ||||||
| std::shared_ptr<AddressArbiter> KernelSystem::CreateAddressArbiter(std::string name) { | std::shared_ptr<AddressArbiter> KernelSystem::CreateAddressArbiter(std::string name) { | ||||||
|  | @ -80,6 +79,24 @@ std::shared_ptr<AddressArbiter> KernelSystem::CreateAddressArbiter(std::string n | ||||||
|     return address_arbiter; |     return address_arbiter; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | class AddressArbiter::Callback : public WakeupCallback { | ||||||
|  | public: | ||||||
|  |     explicit Callback(AddressArbiter& _parent) : parent(_parent) {} | ||||||
|  |     AddressArbiter& parent; | ||||||
|  | 
 | ||||||
|  |     void WakeUp(ThreadWakeupReason reason, std::shared_ptr<Thread> thread, | ||||||
|  |                 std::shared_ptr<WaitObject> object) override { | ||||||
|  |         parent.WakeUp(reason, std::move(thread), std::move(object)); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | private: | ||||||
|  |     template <class Archive> | ||||||
|  |     void serialize(Archive& ar, const unsigned int) { | ||||||
|  |         ar& boost::serialization::base_object<WakeupCallback>(*this); | ||||||
|  |     } | ||||||
|  |     friend class boost::serialization::access; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
| void AddressArbiter::WakeUp(ThreadWakeupReason reason, std::shared_ptr<Thread> thread, | void AddressArbiter::WakeUp(ThreadWakeupReason reason, std::shared_ptr<Thread> thread, | ||||||
|                             std::shared_ptr<WaitObject> object) { |                             std::shared_ptr<WaitObject> object) { | ||||||
|     ASSERT(reason == ThreadWakeupReason::Timeout); |     ASSERT(reason == ThreadWakeupReason::Timeout); | ||||||
|  | @ -90,9 +107,6 @@ void AddressArbiter::WakeUp(ThreadWakeupReason reason, std::shared_ptr<Thread> t | ||||||
| 
 | 
 | ||||||
| ResultCode AddressArbiter::ArbitrateAddress(std::shared_ptr<Thread> thread, ArbitrationType type, | ResultCode AddressArbiter::ArbitrateAddress(std::shared_ptr<Thread> thread, ArbitrationType type, | ||||||
|                                             VAddr address, s32 value, u64 nanoseconds) { |                                             VAddr address, s32 value, u64 nanoseconds) { | ||||||
| 
 |  | ||||||
|     auto timeout_callback = std::dynamic_pointer_cast<WakeupCallback>(shared_from_this()); |  | ||||||
| 
 |  | ||||||
|     switch (type) { |     switch (type) { | ||||||
| 
 | 
 | ||||||
|     // Signal thread(s) waiting for arbitrate address...
 |     // Signal thread(s) waiting for arbitrate address...
 | ||||||
|  | @ -157,3 +171,23 @@ ResultCode AddressArbiter::ArbitrateAddress(std::shared_ptr<Thread> thread, Arbi | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| } // namespace Kernel
 | } // namespace Kernel
 | ||||||
|  | 
 | ||||||
|  | namespace boost::serialization { | ||||||
|  | 
 | ||||||
|  | template <class Archive> | ||||||
|  | void save_construct_data(Archive& ar, const Kernel::AddressArbiter::Callback* t, | ||||||
|  |                          const unsigned int) { | ||||||
|  |     ar << Kernel::SharedFrom(&t->parent); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | template <class Archive> | ||||||
|  | void load_construct_data(Archive& ar, Kernel::AddressArbiter::Callback* t, const unsigned int) { | ||||||
|  |     std::shared_ptr<Kernel::AddressArbiter> parent; | ||||||
|  |     ar >> parent; | ||||||
|  |     ::new (t) Kernel::AddressArbiter::Callback(*parent); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | } // namespace boost::serialization
 | ||||||
|  | 
 | ||||||
|  | SERIALIZE_EXPORT_IMPL(Kernel::AddressArbiter) | ||||||
|  | SERIALIZE_EXPORT_IMPL(Kernel::AddressArbiter::Callback) | ||||||
|  |  | ||||||
|  | @ -59,8 +59,7 @@ public: | ||||||
|     ResultCode ArbitrateAddress(std::shared_ptr<Thread> thread, ArbitrationType type, VAddr address, |     ResultCode ArbitrateAddress(std::shared_ptr<Thread> thread, ArbitrationType type, VAddr address, | ||||||
|                                 s32 value, u64 nanoseconds); |                                 s32 value, u64 nanoseconds); | ||||||
| 
 | 
 | ||||||
|     void WakeUp(ThreadWakeupReason reason, std::shared_ptr<Thread> thread, |     class Callback; | ||||||
|                 std::shared_ptr<WaitObject> object); |  | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
|     KernelSystem& kernel; |     KernelSystem& kernel; | ||||||
|  | @ -78,20 +77,40 @@ private: | ||||||
|     /// Threads waiting for the address arbiter to be signaled.
 |     /// Threads waiting for the address arbiter to be signaled.
 | ||||||
|     std::vector<std::shared_ptr<Thread>> waiting_threads; |     std::vector<std::shared_ptr<Thread>> waiting_threads; | ||||||
| 
 | 
 | ||||||
|  |     std::shared_ptr<Callback> timeout_callback; | ||||||
|  | 
 | ||||||
|  |     void WakeUp(ThreadWakeupReason reason, std::shared_ptr<Thread> thread, | ||||||
|  |                 std::shared_ptr<WaitObject> object); | ||||||
|  | 
 | ||||||
|  |     class DummyCallback : public WakeupCallback { | ||||||
|  |     public: | ||||||
|  |         void WakeUp(ThreadWakeupReason reason, std::shared_ptr<Thread> thread, | ||||||
|  |                     std::shared_ptr<WaitObject> object) override {} | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|     friend class boost::serialization::access; |     friend class boost::serialization::access; | ||||||
|     template <class Archive> |     template <class Archive> | ||||||
|     void serialize(Archive& ar, const unsigned int file_version) { |     void serialize(Archive& ar, const unsigned int file_version) { | ||||||
|         ar& boost::serialization::base_object<Object>(*this); |         ar& boost::serialization::base_object<Object>(*this); | ||||||
|         if (file_version > 0) { |         if (file_version == 1) { | ||||||
|             ar& boost::serialization::base_object<WakeupCallback>(*this); |             // This rigmarole is needed because in past versions, AddressArbiter inherited
 | ||||||
|  |             // WakeupCallback But it turns out this breaks shared_from_this, so we split it out.
 | ||||||
|  |             // Using a dummy class to deserialize a base_object allows compatibility to be
 | ||||||
|  |             // maintained.
 | ||||||
|  |             DummyCallback x; | ||||||
|  |             ar& boost::serialization::base_object<WakeupCallback>(x); | ||||||
|         } |         } | ||||||
|         ar& name; |         ar& name; | ||||||
|         ar& waiting_threads; |         ar& waiting_threads; | ||||||
|  |         if (file_version > 1) { | ||||||
|  |             ar& timeout_callback; | ||||||
|  |         } | ||||||
|     } |     } | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| } // namespace Kernel
 | } // namespace Kernel
 | ||||||
| 
 | 
 | ||||||
| BOOST_CLASS_EXPORT_KEY(Kernel::AddressArbiter) | BOOST_CLASS_EXPORT_KEY(Kernel::AddressArbiter) | ||||||
| BOOST_CLASS_VERSION(Kernel::AddressArbiter, 1) | BOOST_CLASS_EXPORT_KEY(Kernel::AddressArbiter::Callback) | ||||||
|  | BOOST_CLASS_VERSION(Kernel::AddressArbiter, 2) | ||||||
| CONSTRUCT_KERNEL_OBJECT(Kernel::AddressArbiter) | CONSTRUCT_KERNEL_OBJECT(Kernel::AddressArbiter) | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue