From e66ce512d277eb647a81b785eb7401a51a18b867 Mon Sep 17 00:00:00 2001 From: DH Date: Mon, 6 Oct 2025 01:57:23 +0300 Subject: [PATCH] kernel: Add GlobalKernelObject utility --- CMakeLists.txt | 3 +- kernel/CMakeLists.txt | 10 ++ kernel/include/kernel/GlobalKernelObject.hpp | 139 ++++++++++++++++++ kernel/orbis/CMakeLists.txt | 2 +- .../include/orbis/GlobalKernelObject.hpp | 26 ++++ rpcsx/main.cpp | 3 + 6 files changed, 180 insertions(+), 3 deletions(-) create mode 100644 kernel/CMakeLists.txt create mode 100644 kernel/include/kernel/GlobalKernelObject.hpp create mode 100644 kernel/orbis/include/orbis/GlobalKernelObject.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index dff353bec..f446a2cf9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -272,14 +272,13 @@ target_compile_definitions(rx PRIVATE if (WITH_PS4) find_package(nlohmann_json CONFIG) add_subdirectory(tools) - add_subdirectory(kernel/orbis) endif() add_subdirectory(rpcsx) +add_subdirectory(kernel) if (WITH_PS3) include(ConfigureCompiler) - add_subdirectory(kernel/cellos) add_subdirectory(rpcs3) add_subdirectory(ps3fw) endif() diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt new file mode 100644 index 000000000..d488787fa --- /dev/null +++ b/kernel/CMakeLists.txt @@ -0,0 +1,10 @@ +add_library(kernel INTERFACE) +target_include_directories(kernel INTERFACE include) + +if (WITH_PS3) + add_subdirectory(cellos) +endif() + +if (WITH_PS4) + add_subdirectory(orbis) +endif() diff --git a/kernel/include/kernel/GlobalKernelObject.hpp b/kernel/include/kernel/GlobalKernelObject.hpp new file mode 100644 index 000000000..506cfbd24 --- /dev/null +++ b/kernel/include/kernel/GlobalKernelObject.hpp @@ -0,0 +1,139 @@ +#pragma once + +#include "rx/LinkedNode.hpp" +#include "rx/Serializer.hpp" +#include + +namespace kernel { + +namespace detail { +struct GlobalObjectCtl { + void (*construct)(); + void (*destruct)(); + void (*serialize)(rx::Serializer &); + void (*deserialize)(rx::Deserializer &); +}; + +template struct GlobalKernelObjectInstance { + static inline T *instance = nullptr; + + static inline rx::LinkedNode ctl = { + .object = { + .construct = +[] { instance->construct(); }, + .destruct = +[] { instance->destruct(); }, + .serialize = +[](rx::Serializer &s) { instance->serialize(s); }, + .deserialize = +[](rx::Deserializer &s) { instance->deserialize(s); }, + }, + }; +}; +} // namespace detail + +template struct GlobalKernelObjectStorage { + template static void AddObject() { + auto node = &detail::GlobalKernelObjectInstance::ctl; + auto head = GetHead(); + if (head) { + head->prev = node; + node->next = head; + } + + *GetHeadPtr() = node; + } + + static void ConstructAll() { + for (auto it = GetHead(); it != nullptr; it = it->next) { + it->object.construct(); + } + } + + static void DestructAll() { + for (auto it = GetHead(); it != nullptr; it = it->next) { + it->object.destruct(); + } + } + + static void SerializeAll(rx::Serializer &s) { + for (auto it = GetHead(); it != nullptr; it = it->next) { + it->object.serialize(s); + } + } + + static void DeserializeAll(rx::Deserializer &s) { + for (auto it = GetHead(); it != nullptr; it = it->next) { + it->object.deserialize(s); + } + } + +private: + static rx::LinkedNode *GetHead() { + return *GetHeadPtr(); + } + + static rx::LinkedNode **GetHeadPtr() { + static rx::LinkedNode *registry; + return ®istry; + } +}; + +template + requires std::is_default_constructible_v +class GlobalKernelObject { + union U { + T object; + + U() {} + ~U() {} + }; + + U mHolder; + +public: + template GlobalKernelObject() { + auto &instance = + detail::GlobalKernelObjectInstance::instance; + assert(instance == nullptr); + instance = this; + GlobalKernelObjectStorage::template AddObject< + GlobalKernelObject>(); + } + + T *operator->() { return &mHolder.object; } + const T *operator->() const { return &mHolder.object; } + T &operator*() { return mHolder.object; } + const T &operator*() const { return mHolder.object; } + operator T &() { return mHolder.object; } + operator const T &() const { return mHolder.object; } + + void serialize(rx::Serializer &s) + requires rx::Serializable + { + s.serialize(mHolder.object); + } + + void deserialize(rx::Deserializer &s) + requires rx::Serializable + { + std::construct_at(&mHolder.object); + s.deserialize(mHolder.object); + } + + T &get() { return mHolder.object; } + const T &get() const { return mHolder.object; } + +private: + template + requires(std::is_constructible_v) + void construct(Args &&...args) noexcept( + std::is_nothrow_constructible_v) { + std::construct_at(&mHolder.object, std::forward(args)...); + } + + template + void destruct() noexcept(std::is_nothrow_destructible_v) { + mHolder.object.~T(); + } + + friend detail::GlobalKernelObjectInstance; +}; +} // namespace kernel diff --git a/kernel/orbis/CMakeLists.txt b/kernel/orbis/CMakeLists.txt index 5b5d4c584..003b91709 100644 --- a/kernel/orbis/CMakeLists.txt +++ b/kernel/orbis/CMakeLists.txt @@ -67,7 +67,7 @@ add_library(obj.orbis-kernel OBJECT src/utils/Logs.cpp ) -target_link_libraries(obj.orbis-kernel PUBLIC orbis::kernel::config rx) +target_link_libraries(obj.orbis-kernel PUBLIC orbis::kernel::config rx kernel) target_include_directories(obj.orbis-kernel PUBLIC diff --git a/kernel/orbis/include/orbis/GlobalKernelObject.hpp b/kernel/orbis/include/orbis/GlobalKernelObject.hpp new file mode 100644 index 000000000..755b55d41 --- /dev/null +++ b/kernel/orbis/include/orbis/GlobalKernelObject.hpp @@ -0,0 +1,26 @@ +#pragma once +#include + +namespace orbis { +struct OrbisNamespace; + +template +using GlobalKernelObject = kernel::GlobalKernelObject; + +template GlobalKernelObject createGlobalObject() { + return {}; +} + +inline void constructAllGlobals() { + kernel::GlobalKernelObjectStorage::ConstructAll(); +} +inline void destructAllGlobals() { + kernel::GlobalKernelObjectStorage::DestructAll(); +} + +template T &getGlobalObject() { + assert(detail::GlobalKernelObjectInstance>::instance); + return kernel::detail::GlobalKernelObjectInstance< + OrbisNamespace, GlobalKernelObject>::instance->get(); +} +} // namespace orbis diff --git a/rpcsx/main.cpp b/rpcsx/main.cpp index fec2f65a3..84de7eaed 100644 --- a/rpcsx/main.cpp +++ b/rpcsx/main.cpp @@ -26,6 +26,7 @@ #include #include +#include #include #include #include @@ -1265,6 +1266,8 @@ int main(int argc, const char *argv[]) { guestInitDev(); guestInitFd(mainThread); + orbis::constructAllGlobals(); + // data transfer mode // 0 - normal // 1 - source