Started IPC services serialization

This commit is contained in:
Hamish Milne 2019-12-24 17:49:56 +00:00 committed by zhupengfei
parent 7a5bde0b44
commit ac0337d8df
8 changed files with 112 additions and 7 deletions

8
TODO
View file

@ -1,9 +1,11 @@
☐ Save/load UI ☐ Save/load UI
✔ CPU @done(19-08-13 15:41) ✔ CPU @done(19-08-13 15:41)
✔ Memory @done(19-08-13 15:41) ✔ Memory @done(19-08-13 15:41)
☐ Page tables
☐ Skip N3DS RAM if unused
✔ DSP @done(19-08-13 15:41) ✔ DSP @done(19-08-13 15:41)
✔ Service manager @started(19-12-23 00:36) @done(19-12-23 11:38) @lasted(11h2m3s) ✔ Service manager @started(19-12-23 00:36) @done(19-12-23 11:38) @lasted(11h2m3s)
☐ Fix or ignore inverse map ✔ Fix or ignore inverse map @done(19-12-23 12:46)
☐ App loader ☐ App loader
☐ Archive manager ☐ Archive manager
☐ Custom texture cache ☐ Custom texture cache
@ -58,8 +60,8 @@
☐ VM Manager @started(19-08-13 16:46) ☐ VM Manager @started(19-08-13 16:46)
Just need to figure out backing_mem (a u8*) Just need to figure out backing_mem (a u8*)
✔ Wait object @done(19-08-13 16:46) ✔ Wait object @done(19-08-13 16:46)
☐ Service ☐ Service @started(19-12-23 12:49)
☐ AC ☐ AC @started(19-12-23 12:48)
☐ ACT ☐ ACT
☐ AM ☐ AM
☐ APT ☐ APT

35
src/common/construct.h Normal file
View file

@ -0,0 +1,35 @@
#include <boost/serialization/serialization.hpp>
#define BOOST_SERIALIZATION_FRIENDS \
friend class boost::serialization::access; \
friend class construct_access;
class construct_access {
public:
template<class Archive, class T>
static inline void save_construct(Archive & ar, const T * t, const unsigned int file_version) {
t->save_construct(ar, file_version);
}
template<class Archive, class T>
static inline void load_construct(Archive & ar, T * t, const unsigned int file_version) {
T::load_construct(ar, t, file_version);
}
};
#define BOOST_SERIALIZATION_CONSTRUCT(T) \
namespace boost { namespace serialization { \
\
template<class Archive> \
inline void save_construct_data( \
Archive & ar, const T * t, const unsigned int file_version \
){ \
construct_access::save_construct(ar, t, file_version); \
} \
\
template<class Archive> \
inline void load_construct_data( \
Archive & ar, T * t, const unsigned int file_version \
){ \
construct_access::load_construct(ar, t, file_version); \
} \
}}

View file

@ -75,6 +75,10 @@ public:
/// in each service must inherit from this. /// in each service must inherit from this.
struct SessionDataBase { struct SessionDataBase {
virtual ~SessionDataBase() = default; virtual ~SessionDataBase() = default;
private:
template <class Archive>
void serialize(Archive& ar, const unsigned int file_version) { }
friend class boost::serialization::access;
}; };
protected: protected:
@ -94,6 +98,7 @@ protected:
struct SessionInfo { struct SessionInfo {
SessionInfo(std::shared_ptr<ServerSession> session, std::unique_ptr<SessionDataBase> data); SessionInfo(std::shared_ptr<ServerSession> session, std::unique_ptr<SessionDataBase> data);
SessionInfo() = default;
std::shared_ptr<ServerSession> session; std::shared_ptr<ServerSession> session;
std::unique_ptr<SessionDataBase> data; std::unique_ptr<SessionDataBase> data;

View file

@ -5,6 +5,7 @@
#include <vector> #include <vector>
#include "common/common_types.h" #include "common/common_types.h"
#include "common/logging/log.h" #include "common/logging/log.h"
#include "common/archives.h"
#include "core/core.h" #include "core/core.h"
#include "core/hle/ipc.h" #include "core/hle/ipc.h"
#include "core/hle/ipc_helpers.h" #include "core/hle/ipc_helpers.h"
@ -16,6 +17,8 @@
#include "core/hle/service/ac/ac_u.h" #include "core/hle/service/ac/ac_u.h"
#include "core/memory.h" #include "core/memory.h"
SERIALIZE_EXPORT_IMPL(Service::AC::Module::Interface)
namespace Service::AC { namespace Service::AC {
void Module::Interface::CreateDefaultConfig(Kernel::HLERequestContext& ctx) { void Module::Interface::CreateDefaultConfig(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx, 0x1, 0, 0); IPC::RequestParser rp(ctx, 0x1, 0, 0);

View file

@ -6,6 +6,9 @@
#include <array> #include <array>
#include <memory> #include <memory>
#include <boost/serialization/base_object.hpp>
#include <boost/serialization/shared_ptr.hpp>
#include "common/construct.h"
#include "core/hle/service/service.h" #include "core/hle/service/service.h"
namespace Core { namespace Core {
@ -139,6 +142,34 @@ public:
protected: protected:
std::shared_ptr<Module> ac; std::shared_ptr<Module> ac;
private:
template <class Archive>
void save_construct(Archive& ar, const unsigned int file_version) const
{
ar << ac;
ar << GetServiceName();
ar << GetMaxSessions();
}
template <class Archive>
static void load_construct(Archive& ar, Interface* t, const unsigned int file_version)
{
std::shared_ptr<Module> ac;
std::string name;
u32 max_sessions;
ar >> ac;
ar >> name;
ar >> max_sessions;
::new(t)Interface(ac, name.c_str(), max_sessions);
}
template <class Archive>
void serialize(Archive& ar, const unsigned int file_version)
{
ar & boost::serialization::base_object<Kernel::SessionRequestHandler>(*this);
}
BOOST_SERIALIZATION_FRIENDS
}; };
protected: protected:
@ -153,8 +184,23 @@ protected:
std::shared_ptr<Kernel::Event> close_event; std::shared_ptr<Kernel::Event> close_event;
std::shared_ptr<Kernel::Event> connect_event; std::shared_ptr<Kernel::Event> connect_event;
std::shared_ptr<Kernel::Event> disconnect_event; std::shared_ptr<Kernel::Event> disconnect_event;
private:
template <class Archive>
void serialize(Archive& ar, const unsigned int file_version)
{
ar & ac_connected;
ar & close_event;
ar & connect_event;
ar & disconnect_event;
// default_config is never written to
}
friend class boost::serialization::access;
}; };
void InstallInterfaces(Core::System& system); void InstallInterfaces(Core::System& system);
} // namespace Service::AC } // namespace Service::AC
BOOST_SERIALIZATION_CONSTRUCT(Service::AC::Module::Interface)
BOOST_CLASS_EXPORT_KEY(Service::AC::Module::Interface)

View file

@ -85,6 +85,7 @@ private:
using InvokerFn = void(ServiceFrameworkBase* object, HandlerFnP<ServiceFrameworkBase> member, using InvokerFn = void(ServiceFrameworkBase* object, HandlerFnP<ServiceFrameworkBase> member,
Kernel::HLERequestContext& ctx); Kernel::HLERequestContext& ctx);
// TODO: Replace all these with virtual functions!
ServiceFrameworkBase(const char* service_name, u32 max_sessions, InvokerFn* handler_invoker); ServiceFrameworkBase(const char* service_name, u32 max_sessions, InvokerFn* handler_invoker);
~ServiceFrameworkBase() override; ~ServiceFrameworkBase() override;

View file

@ -11,6 +11,7 @@
#include <boost/serialization/shared_ptr.hpp> #include <boost/serialization/shared_ptr.hpp>
#include <boost/serialization/string.hpp> #include <boost/serialization/string.hpp>
#include <boost/serialization/unordered_map.hpp> #include <boost/serialization/unordered_map.hpp>
#include <boost/serialization/split_member.hpp>
#include "core/hle/kernel/client_port.h" #include "core/hle/kernel/client_port.h"
#include "core/hle/kernel/object.h" #include "core/hle/kernel/object.h"
#include "core/hle/kernel/server_port.h" #include "core/hle/kernel/server_port.h"
@ -85,11 +86,23 @@ private:
std::unordered_map<u32, std::string> registered_services_inverse; std::unordered_map<u32, std::string> registered_services_inverse;
template <class Archive> template <class Archive>
void serialize(Archive& ar, const unsigned int file_version) void save(Archive& ar, const unsigned int file_version) const
{ {
ar & registered_services; ar << registered_services;
ar & registered_services_inverse; // TODO: Instead, compute this from registered_services
} }
template <class Archive>
void load(Archive& ar, const unsigned int file_version)
{
ar >> registered_services;
registered_services_inverse.clear();
for (const auto& pair : registered_services) {
registered_services_inverse.emplace(pair.second->GetObjectId(), pair.first);
}
}
BOOST_SERIALIZATION_SPLIT_MEMBER()
friend class boost::serialization::access; friend class boost::serialization::access;
}; };

View file

@ -56,7 +56,7 @@ private:
std::array<bool, LINEAR_HEAP_SIZE / PAGE_SIZE> linear_heap{}; std::array<bool, LINEAR_HEAP_SIZE / PAGE_SIZE> linear_heap{};
std::array<bool, NEW_LINEAR_HEAP_SIZE / PAGE_SIZE> new_linear_heap{}; std::array<bool, NEW_LINEAR_HEAP_SIZE / PAGE_SIZE> new_linear_heap{};
static_assert(sizeof(bool) == 1); // TODO: Maybe this isn't true? static_assert(sizeof(bool) == 1);
friend class boost::serialization::access; friend class boost::serialization::access;
template<typename Archive> template<typename Archive>
void serialize(Archive & ar, const unsigned int file_version) void serialize(Archive & ar, const unsigned int file_version)