mirror of
https://github.com/RPCSX/rpcsx.git
synced 2025-12-05 23:02:07 +01:00
kernel: Add GlobalKernelObject utility
This commit is contained in:
parent
fd9bf42538
commit
e66ce512d2
|
|
@ -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()
|
||||
|
|
|
|||
10
kernel/CMakeLists.txt
Normal file
10
kernel/CMakeLists.txt
Normal file
|
|
@ -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()
|
||||
139
kernel/include/kernel/GlobalKernelObject.hpp
Normal file
139
kernel/include/kernel/GlobalKernelObject.hpp
Normal file
|
|
@ -0,0 +1,139 @@
|
|||
#pragma once
|
||||
|
||||
#include "rx/LinkedNode.hpp"
|
||||
#include "rx/Serializer.hpp"
|
||||
#include <cassert>
|
||||
|
||||
namespace kernel {
|
||||
|
||||
namespace detail {
|
||||
struct GlobalObjectCtl {
|
||||
void (*construct)();
|
||||
void (*destruct)();
|
||||
void (*serialize)(rx::Serializer &);
|
||||
void (*deserialize)(rx::Deserializer &);
|
||||
};
|
||||
|
||||
template <typename NamespaceT, typename T> struct GlobalKernelObjectInstance {
|
||||
static inline T *instance = nullptr;
|
||||
|
||||
static inline rx::LinkedNode<GlobalObjectCtl> 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 <typename NamespaceT> struct GlobalKernelObjectStorage {
|
||||
template <typename T> static void AddObject() {
|
||||
auto node = &detail::GlobalKernelObjectInstance<NamespaceT, T>::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<detail::GlobalObjectCtl> *GetHead() {
|
||||
return *GetHeadPtr();
|
||||
}
|
||||
|
||||
static rx::LinkedNode<detail::GlobalObjectCtl> **GetHeadPtr() {
|
||||
static rx::LinkedNode<detail::GlobalObjectCtl> *registry;
|
||||
return ®istry;
|
||||
}
|
||||
};
|
||||
|
||||
template <rx::Serializable T, typename NamespaceT>
|
||||
requires std::is_default_constructible_v<T>
|
||||
class GlobalKernelObject {
|
||||
union U {
|
||||
T object;
|
||||
|
||||
U() {}
|
||||
~U() {}
|
||||
};
|
||||
|
||||
U mHolder;
|
||||
|
||||
public:
|
||||
template <typename = void> GlobalKernelObject() {
|
||||
auto &instance =
|
||||
detail::GlobalKernelObjectInstance<NamespaceT,
|
||||
GlobalKernelObject>::instance;
|
||||
assert(instance == nullptr);
|
||||
instance = this;
|
||||
GlobalKernelObjectStorage<NamespaceT>::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<T>
|
||||
{
|
||||
s.serialize(mHolder.object);
|
||||
}
|
||||
|
||||
void deserialize(rx::Deserializer &s)
|
||||
requires rx::Serializable<T>
|
||||
{
|
||||
std::construct_at(&mHolder.object);
|
||||
s.deserialize(mHolder.object);
|
||||
}
|
||||
|
||||
T &get() { return mHolder.object; }
|
||||
const T &get() const { return mHolder.object; }
|
||||
|
||||
private:
|
||||
template <typename... Args>
|
||||
requires(std::is_constructible_v<T, Args && ...>)
|
||||
void construct(Args &&...args) noexcept(
|
||||
std::is_nothrow_constructible_v<T, Args &&...>) {
|
||||
std::construct_at(&mHolder.object, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
void destruct() noexcept(std::is_nothrow_destructible_v<T>) {
|
||||
mHolder.object.~T();
|
||||
}
|
||||
|
||||
friend detail::GlobalKernelObjectInstance<NamespaceT, GlobalKernelObject>;
|
||||
};
|
||||
} // namespace kernel
|
||||
|
|
@ -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
|
||||
|
|
|
|||
26
kernel/orbis/include/orbis/GlobalKernelObject.hpp
Normal file
26
kernel/orbis/include/orbis/GlobalKernelObject.hpp
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
#pragma once
|
||||
#include <kernel/GlobalKernelObject.hpp>
|
||||
|
||||
namespace orbis {
|
||||
struct OrbisNamespace;
|
||||
|
||||
template <rx::Serializable T>
|
||||
using GlobalKernelObject = kernel::GlobalKernelObject<T, OrbisNamespace>;
|
||||
|
||||
template <rx::Serializable T> GlobalKernelObject<T> createGlobalObject() {
|
||||
return {};
|
||||
}
|
||||
|
||||
inline void constructAllGlobals() {
|
||||
kernel::GlobalKernelObjectStorage<OrbisNamespace>::ConstructAll();
|
||||
}
|
||||
inline void destructAllGlobals() {
|
||||
kernel::GlobalKernelObjectStorage<OrbisNamespace>::DestructAll();
|
||||
}
|
||||
|
||||
template <typename T> T &getGlobalObject() {
|
||||
assert(detail::GlobalKernelObjectInstance<GlobalKernelObject<T>>::instance);
|
||||
return kernel::detail::GlobalKernelObjectInstance<
|
||||
OrbisNamespace, GlobalKernelObject<T>>::instance->get();
|
||||
}
|
||||
} // namespace orbis
|
||||
|
|
@ -26,6 +26,7 @@
|
|||
|
||||
#include <elf.h>
|
||||
#include <linux/prctl.h>
|
||||
#include <orbis/GlobalKernelObject.hpp>
|
||||
#include <orbis/KernelContext.hpp>
|
||||
#include <orbis/module.hpp>
|
||||
#include <orbis/module/Module.hpp>
|
||||
|
|
@ -1265,6 +1266,8 @@ int main(int argc, const char *argv[]) {
|
|||
guestInitDev();
|
||||
guestInitFd(mainThread);
|
||||
|
||||
orbis::constructAllGlobals();
|
||||
|
||||
// data transfer mode
|
||||
// 0 - normal
|
||||
// 1 - source
|
||||
|
|
|
|||
Loading…
Reference in a new issue