kernel: split context and allocator & initial implementation of process/thread local objects
Some checks are pending
Formatting check / formatting-check (push) Waiting to run
Build RPCSX / build-linux (push) Waiting to run
Build RPCSX / build-android (arm64-v8a, armv8-a) (push) Waiting to run
Build RPCSX / build-android (arm64-v8a, armv8.1-a) (push) Waiting to run
Build RPCSX / build-android (arm64-v8a, armv8.2-a) (push) Waiting to run
Build RPCSX / build-android (arm64-v8a, armv8.4-a) (push) Waiting to run
Build RPCSX / build-android (arm64-v8a, armv8.5-a) (push) Waiting to run
Build RPCSX / build-android (arm64-v8a, armv9-a) (push) Waiting to run
Build RPCSX / build-android (arm64-v8a, armv9.1-a) (push) Waiting to run
Build RPCSX / build-android (x86_64, x86-64) (push) Waiting to run

This commit is contained in:
DH 2025-10-10 19:56:11 +03:00
parent b358d6b2c9
commit 2589143798
34 changed files with 774 additions and 597 deletions

View file

@ -1,26 +0,0 @@
#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

View file

@ -10,7 +10,6 @@
#include <vector>
namespace orbis {
inline namespace utils {
void *kalloc(std::size_t size, std::size_t align);
void kfree(void *ptr, std::size_t size);
template <typename T> struct kallocator {
@ -51,7 +50,6 @@ template <typename K, typename T, typename Hash = std::hash<K>,
typename Pred = std::equal_to<K>>
using kunmap =
std::unordered_map<K, T, Hash, Pred, kallocator<std::pair<const K, T>>>;
} // namespace utils
template <typename T, typename... Args>
requires(std::is_constructible_v<T, Args...>)
@ -61,17 +59,17 @@ T *knew(Args &&...args) {
struct DynamicObject final : T {
using T::T;
void operator delete(void *pointer) { utils::kfree(pointer, sizeof(T)); }
void operator delete(void *pointer) { kfree(pointer, sizeof(T)); }
};
auto loc = static_cast<DynamicObject *>(
utils::kalloc(sizeof(DynamicObject), alignof(DynamicObject)));
kalloc(sizeof(DynamicObject), alignof(DynamicObject)));
return std::construct_at(loc, std::forward<Args>(args)...);
} else {
static_assert(!std::is_polymorphic_v<T>,
"Polymorphic type should be derived from rx::RcBase");
auto loc = static_cast<T *>(utils::kalloc(sizeof(T), alignof(T)));
auto loc = static_cast<T *>(kalloc(sizeof(T), alignof(T)));
return std::construct_at(loc, std::forward<Args>(args)...);
}
}
@ -80,8 +78,10 @@ T *knew(Args &&...args) {
template <typename T> void kdelete(T *ptr) {
static_assert(std::is_final_v<T>, "Uncertain type size");
ptr->~T();
utils::kfree(ptr, sizeof(T));
kfree(ptr, sizeof(T));
}
// clang-format on
void initializeAllocator();
void deinitializeAllocator();
} // namespace orbis

View file

@ -1,7 +1,7 @@
#pragma once
#include "AppInfo.hpp"
#include "Budget.hpp"
#include "KernelAllocator.hpp"
#include "KernelObject.hpp"
#include "evf.hpp"
#include "ipmi.hpp"
#include "orbis/note.hpp"
@ -50,12 +50,7 @@ public:
long getTscFreq();
void *kalloc(std::size_t size,
std::size_t align = __STDCPP_DEFAULT_NEW_ALIGNMENT__);
void kfree(void *ptr, std::size_t size);
std::pair<EventFlag *, bool> createEventFlag(utils::kstring name,
std::int32_t flags,
std::pair<EventFlag *, bool> createEventFlag(kstring name, std::int32_t flags,
std::uint64_t initPattern) {
std::lock_guard lock(m_evf_mtx);
@ -78,7 +73,7 @@ public:
return {};
}
std::pair<Semaphore *, bool> createSemaphore(utils::kstring name,
std::pair<Semaphore *, bool> createSemaphore(kstring name,
std::uint32_t attrs,
std::int32_t initCount,
std::int32_t maxCount) {
@ -100,8 +95,7 @@ public:
return {};
}
std::pair<rx::Ref<IpmiServer>, ErrorCode>
createIpmiServer(utils::kstring name) {
std::pair<rx::Ref<IpmiServer>, ErrorCode> createIpmiServer(kstring name) {
std::lock_guard lock(m_sem_mtx);
auto [it, inserted] = mIpmiServers.try_emplace(std::move(name), nullptr);
@ -128,15 +122,14 @@ public:
return {};
}
std::tuple<utils::kmap<utils::kstring, char[128]> &,
std::unique_lock<rx::shared_mutex>>
std::tuple<kmap<kstring, char[128]> &, std::unique_lock<rx::shared_mutex>>
getKernelEnv() {
std::unique_lock lock(m_kenv_mtx);
return {m_kenv, std::move(lock)};
}
void setKernelEnv(std::string_view key, std::string_view value) {
auto &kenvValue = m_kenv[utils::kstring(key)];
auto &kenvValue = m_kenv[kstring(key)];
auto len = std::min(sizeof(kenvValue) - 1, value.size());
std::memcpy(kenvValue, value.data(), len);
kenvValue[len] = '0';
@ -177,14 +170,10 @@ public:
return processTypeBudgets[static_cast<int>(processType)];
}
void serialize(rx::Serializer &) const {}
void deserialize(rx::Deserializer &) {}
private:
rx::shared_mutex m_heap_mtx;
rx::shared_mutex m_heap_map_mtx;
void *m_heap_next = this + 1;
utils::kmultimap<std::size_t, void *> m_free_heap;
utils::kmultimap<std::size_t, void *> m_used_node;
std::atomic<long> m_tsc_freq{0};
rx::shared_mutex m_thread_id_mtx;
@ -193,17 +182,17 @@ private:
rx::LinkedNode<Process> *m_processes = nullptr;
rx::shared_mutex m_evf_mtx;
utils::kmap<utils::kstring, rx::Ref<EventFlag>> m_event_flags;
kmap<kstring, rx::Ref<EventFlag>> m_event_flags;
rx::shared_mutex m_sem_mtx;
utils::kmap<utils::kstring, rx::Ref<Semaphore>> m_semaphores;
kmap<kstring, rx::Ref<Semaphore>> m_semaphores;
rx::shared_mutex mIpmiServerMtx;
utils::kmap<utils::kstring, rx::Ref<IpmiServer>> mIpmiServers;
kmap<kstring, rx::Ref<IpmiServer>> mIpmiServers;
rx::shared_mutex m_kenv_mtx;
utils::kmap<utils::kstring, char[128]> m_kenv; // max size: 127 + '\0'
kmap<kstring, char[128]> m_kenv; // max size: 127 + '\0'
};
extern KernelContext &g_context;
extern GlobalObjectRef<KernelContext> g_context;
} // namespace orbis

View file

@ -0,0 +1,108 @@
#pragma once
#include <kernel/KernelObject.hpp>
namespace orbis {
struct OrbisNamespace;
template <rx::Serializable StateT>
using GlobalObjectRef =
kernel::StaticObjectRef<OrbisNamespace, kernel::detail::GlobalScope,
StateT>;
template <rx::Serializable StateT>
using ProcessLocalObjectRef =
kernel::StaticObjectRef<OrbisNamespace, kernel::detail::ProcessScope,
StateT>;
template <rx::Serializable StateT>
using ThreadLocalObjectRef =
kernel::StaticObjectRef<OrbisNamespace, kernel::detail::ThreadScope,
StateT>;
template <rx::Serializable StateT>
GlobalObjectRef<StateT> createGlobalObject() {
auto layoutOffset = kernel::StaticKernelObjectStorage<
OrbisNamespace, kernel::detail::GlobalScope>::template Allocate<StateT>();
return GlobalObjectRef<StateT>(layoutOffset);
}
template <rx::Serializable StateT>
kernel::StaticObjectRef<OrbisNamespace, kernel::detail::ProcessScope, StateT>
createProcessLocalObject() {
auto layoutOffset = kernel::StaticKernelObjectStorage<
OrbisNamespace,
kernel::detail::ProcessScope>::template Allocate<StateT>();
return kernel::StaticObjectRef<OrbisNamespace, kernel::detail::ProcessScope,
StateT>(layoutOffset);
}
template <rx::Serializable StateT>
kernel::StaticObjectRef<OrbisNamespace, kernel::detail::ThreadScope, StateT>
createThreadLocalObject() {
auto layoutOffset = kernel::StaticKernelObjectStorage<
OrbisNamespace, kernel::detail::ThreadScope>::template Allocate<StateT>();
return kernel::StaticObjectRef<OrbisNamespace, kernel::detail::ThreadScope,
StateT>(layoutOffset);
}
inline void constructAllGlobals() {
kernel::StaticKernelObjectStorage<
OrbisNamespace, kernel::detail::GlobalScope>::ConstructAll();
}
inline void constructAllProcessLocals() {
kernel::StaticKernelObjectStorage<
OrbisNamespace, kernel::detail::ProcessScope>::ConstructAll();
}
inline void constructAllThreadLocals() {
kernel::StaticKernelObjectStorage<
OrbisNamespace, kernel::detail::ThreadScope>::ConstructAll();
}
inline void destructAllGlobals() {
kernel::StaticKernelObjectStorage<OrbisNamespace,
kernel::detail::GlobalScope>::DestructAll();
}
inline void destructAllProcessLocals() {
kernel::StaticKernelObjectStorage<
OrbisNamespace, kernel::detail::ProcessScope>::DestructAll();
}
inline void destructAllThreadLocals() {
kernel::StaticKernelObjectStorage<OrbisNamespace,
kernel::detail::ThreadScope>::DestructAll();
}
inline void serializeAllGlobals(rx::Serializer &s) {
kernel::StaticKernelObjectStorage<
OrbisNamespace, kernel::detail::GlobalScope>::SerializeAll(s);
}
inline void serializeAllProcessLocals(rx::Serializer &s) {
kernel::StaticKernelObjectStorage<
OrbisNamespace, kernel::detail::ProcessScope>::SerializeAll(s);
}
inline void serializeAllThreadLocals(rx::Serializer &s) {
kernel::StaticKernelObjectStorage<
OrbisNamespace, kernel::detail::ThreadScope>::SerializeAll(s);
}
inline void deserializeAllGlobals(rx::Deserializer &s) {
kernel::StaticKernelObjectStorage<
OrbisNamespace, kernel::detail::GlobalScope>::DeserializeAll(s);
}
inline void deserializeAllProcessLocals(rx::Deserializer &s) {
kernel::StaticKernelObjectStorage<
OrbisNamespace, kernel::detail::ProcessScope>::DeserializeAll(s);
}
inline void deserializeAllThreadLocals(rx::Deserializer &s) {
kernel::StaticKernelObjectStorage<
OrbisNamespace, kernel::detail::ThreadScope>::DeserializeAll(s);
}
} // namespace orbis

View file

@ -57,7 +57,7 @@ struct EventFlag final {
};
rx::shared_mutex queueMtx;
utils::kvector<WaitingThread> waitingThreads;
kvector<WaitingThread> waitingThreads;
enum class NotifyType { Set, Cancel, Destroy };

View file

@ -82,7 +82,7 @@ struct File : rx::RcBase {
int flags = 0;
int mode = 0;
int hostFd = -1;
utils::kvector<Dirent> dirEntries;
kvector<Dirent> dirEntries;
bool noBlock() const { return (flags & 4) != 0; }
};

View file

@ -21,7 +21,7 @@ enum class DynType : std::uint8_t {
};
struct ModuleNeeded {
utils::kstring name;
kstring name;
std::uint16_t version;
std::uint64_t attr;
bool isExport;
@ -67,7 +67,7 @@ struct Relocation {
struct Module final {
Process *proc{};
utils::kstring vfsPath;
kstring vfsPath;
char moduleName[256]{};
char soName[256]{};
ModuleHandle id{};
@ -110,15 +110,15 @@ struct Module final {
bool isTlsDone = false;
utils::kstring interp;
utils::kvector<Symbol> symbols;
utils::kvector<Relocation> pltRelocations;
utils::kvector<Relocation> nonPltRelocations;
utils::kvector<ModuleNeeded> neededModules;
utils::kvector<ModuleNeeded> neededLibraries;
utils::kvector<rx::Ref<Module>> importedModules;
utils::kvector<rx::Ref<Module>> namespaceModules;
utils::kvector<utils::kstring> needed;
kstring interp;
kvector<Symbol> symbols;
kvector<Relocation> pltRelocations;
kvector<Relocation> nonPltRelocations;
kvector<ModuleNeeded> neededModules;
kvector<ModuleNeeded> neededLibraries;
kvector<rx::Ref<Module>> importedModules;
kvector<rx::Ref<Module>> namespaceModules;
kvector<kstring> needed;
std::atomic<unsigned> references{0};

View file

@ -93,13 +93,13 @@ struct Process final {
// Named objects for debugging
rx::shared_mutex namedObjMutex;
utils::kmap<void *, utils::kstring> namedObjNames;
kmap<void *, kstring> namedObjNames;
rx::OwningIdMap<NamedObjInfo, uint, 65535, 1> namedObjIds;
utils::kmap<std::int32_t, SigAction> sigActions;
kmap<std::int32_t, SigAction> sigActions;
// Named memory ranges for debugging
rx::shared_mutex namedMemMutex;
utils::kmap<NamedMemoryRange, utils::kstring> namedMem;
kmap<NamedMemoryRange, kstring> namedMem;
};
} // namespace orbis