Serialize core timing

This commit is contained in:
Hamish Milne 2020-01-12 20:01:29 +00:00 committed by zhupengfei
parent 8abc5525be
commit c24ea0f0ee
5 changed files with 54 additions and 3 deletions

3
TODO
View file

@ -1,9 +1,10 @@
☐ Save/load UI ☐ Save/load UI
✔ Basic version @done(20-01-03 15:27) ✔ Basic version @done(20-01-03 15:27)
☐ Multiple slots etc. ☐ Multiple slots etc.
☐ Add 'force flush all' to Rasterizer interface + impls
☐ Custom texture cache ☐ Custom texture cache
☐ Review constructor/initialization code ☐ Review constructor/initialization code
☐ Core timing events ✔ Core timing events @done(20-01-12 15:14)
☐ Serialize codeset with an apploader reference instead ☐ Serialize codeset with an apploader reference instead
✔ Review base class serialization everywhere @done(20-01-10 23:47) ✔ Review base class serialization everywhere @done(20-01-10 23:47)
Make sure that all base/derived relationships are registered Make sure that all base/derived relationships are registered

View file

@ -434,6 +434,7 @@ void System::Reset() {
template <class Archive> template <class Archive>
void System::serialize(Archive& ar, const unsigned int file_version) { void System::serialize(Archive& ar, const unsigned int file_version) {
Memory::RasterizerFlushAndInvalidateRegion(0, 0xFFFFFFFF); Memory::RasterizerFlushAndInvalidateRegion(0, 0xFFFFFFFF);
ar&* timing.get();
ar&* cpu_core.get(); ar&* cpu_core.get();
ar&* service_manager.get(); ar&* service_manager.get();
ar& GPU::g_regs; ar& GPU::g_regs;

View file

@ -11,6 +11,8 @@
namespace Core { namespace Core {
Timing* Timing::deserializing = nullptr;
// Sort by time, unless the times are the same, in which case sort by the order added to the queue // Sort by time, unless the times are the same, in which case sort by the order added to the queue
bool Timing::Event::operator>(const Event& right) const { bool Timing::Event::operator>(const Event& right) const {
return std::tie(time, fifo_order) > std::tie(right.time, right.fifo_order); return std::tie(time, fifo_order) > std::tie(right.time, right.fifo_order);
@ -26,7 +28,9 @@ TimingEventType* Timing::RegisterEvent(const std::string& name, TimedCallback ca
auto info = event_types.emplace(name, TimingEventType{}); auto info = event_types.emplace(name, TimingEventType{});
TimingEventType* event_type = &info.first->second; TimingEventType* event_type = &info.first->second;
event_type->name = &info.first->first; event_type->name = &info.first->first;
event_type->callback = callback; if (callback != nullptr) {
event_type->callback = callback;
}
return event_type; return event_type;
} }
@ -129,7 +133,9 @@ void Timing::Advance() {
LOG_ERROR(Core, "Unknown queued event"); LOG_ERROR(Core, "Unknown queued event");
continue; continue;
} }
evt.type->callback(evt.userdata, global_timer - evt.time); if (evt.type->callback != nullptr) {
evt.type->callback(evt.userdata, global_timer - evt.time);
}
} }
is_global_timer_sane = false; is_global_timer_sane = false;

View file

@ -23,6 +23,8 @@
#include <string> #include <string>
#include <unordered_map> #include <unordered_map>
#include <vector> #include <vector>
#include <boost/serialization/split_member.hpp>
#include <boost/serialization/vector.hpp>
#include "common/common_types.h" #include "common/common_types.h"
#include "common/logging/log.h" #include "common/logging/log.h"
#include "common/threadsafe_queue.h" #include "common/threadsafe_queue.h"
@ -190,6 +192,8 @@ public:
s64 GetDowncount() const; s64 GetDowncount() const;
private: private:
static Timing* deserializing;
struct Event { struct Event {
s64 time; s64 time;
u64 fifo_order; u64 fifo_order;
@ -198,6 +202,29 @@ private:
bool operator>(const Event& right) const; bool operator>(const Event& right) const;
bool operator<(const Event& right) const; bool operator<(const Event& right) const;
private:
template <class Archive>
void save(Archive& ar, const unsigned int) const {
ar& time;
ar& fifo_order;
ar& userdata;
std::string name = *(type->name);
ar << name;
}
template <class Archive>
void load(Archive& ar, const unsigned int) {
ar& time;
ar& fifo_order;
ar& userdata;
std::string name;
ar >> name;
type = Timing::deserializing->RegisterEvent(name, nullptr);
}
friend class boost::serialization::access;
BOOST_SERIALIZATION_SPLIT_MEMBER()
}; };
static constexpr int MAX_SLICE_LENGTH = 20000; static constexpr int MAX_SLICE_LENGTH = 20000;
@ -229,6 +256,21 @@ private:
// executing the first cycle of each slice to prepare the slice length and downcount for // executing the first cycle of each slice to prepare the slice length and downcount for
// that slice. // that slice.
bool is_global_timer_sane = true; bool is_global_timer_sane = true;
template <class Archive>
void serialize(Archive& ar, const unsigned int) {
// event_types set during initialization of other things
deserializing = this;
MoveEvents();
ar& global_timer;
ar& slice_length;
ar& downcount;
ar& event_queue;
ar& event_fifo_id;
ar& idled_cycles;
deserializing = nullptr;
}
friend class boost::serialization::access;
}; };
} // namespace Core } // namespace Core

View file

@ -172,6 +172,7 @@ private:
ar& ready_queue; ar& ready_queue;
ar& wakeup_callback_table; ar& wakeup_callback_table;
ar& thread_list; ar& thread_list;
SwitchContext(current_thread.get());
} }
}; };