Clean up the Callback (don't store a shared_ptr to parent)

This commit is contained in:
Hamish Milne 2020-04-20 16:29:50 +01:00
parent c5a3bf9728
commit 55c9162d02

View file

@ -67,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,20 +81,18 @@ std::shared_ptr<AddressArbiter> KernelSystem::CreateAddressArbiter(std::string n
class AddressArbiter::Callback : public WakeupCallback { class AddressArbiter::Callback : public WakeupCallback {
public: public:
Callback(AddressArbiter& _parent) : parent(SharedFrom(&_parent)) {} Callback(AddressArbiter& _parent) : parent(_parent) {}
std::shared_ptr<AddressArbiter> parent; AddressArbiter& parent;
void WakeUp(ThreadWakeupReason reason, std::shared_ptr<Thread> thread, void WakeUp(ThreadWakeupReason reason, std::shared_ptr<Thread> thread,
std::shared_ptr<WaitObject> object) override { std::shared_ptr<WaitObject> object) override {
parent->WakeUp(reason, thread, object); parent.WakeUp(reason, thread, object);
} }
private: private:
Callback() = default;
template <class Archive> template <class Archive>
void serialize(Archive& ar, const unsigned int) { void serialize(Archive& ar, const unsigned int) {
ar& boost::serialization::base_object<WakeupCallback>(*this); ar& boost::serialization::base_object<WakeupCallback>(*this);
ar& parent;
} }
friend class boost::serialization::access; friend class boost::serialization::access;
}; };
@ -129,9 +128,6 @@ ResultCode AddressArbiter::ArbitrateAddress(std::shared_ptr<Thread> thread, Arbi
} }
break; break;
case ArbitrationType::WaitIfLessThanWithTimeout: case ArbitrationType::WaitIfLessThanWithTimeout:
if (!timeout_callback) {
timeout_callback = std::make_shared<Callback>(*this);
}
if ((s32)kernel.memory.Read32(address) < value) { if ((s32)kernel.memory.Read32(address) < value) {
thread->wakeup_callback = timeout_callback; thread->wakeup_callback = timeout_callback;
thread->WakeAfterDelay(nanoseconds); thread->WakeAfterDelay(nanoseconds);
@ -148,9 +144,6 @@ ResultCode AddressArbiter::ArbitrateAddress(std::shared_ptr<Thread> thread, Arbi
break; break;
} }
case ArbitrationType::DecrementAndWaitIfLessThanWithTimeout: { case ArbitrationType::DecrementAndWaitIfLessThanWithTimeout: {
if (!timeout_callback) {
timeout_callback = std::make_shared<Callback>(*this);
}
s32 memory_value = kernel.memory.Read32(address); s32 memory_value = kernel.memory.Read32(address);
if (memory_value < value) { if (memory_value < value) {
// Only change the memory value if the thread should wait // Only change the memory value if the thread should wait
@ -179,5 +172,22 @@ 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)
SERIALIZE_EXPORT_IMPL(Kernel::AddressArbiter::Callback) SERIALIZE_EXPORT_IMPL(Kernel::AddressArbiter::Callback)