diff --git a/kernel/include/kernel/KernelObject.hpp b/kernel/include/kernel/KernelObject.hpp index 5fe28f3ce..d36814ec4 100644 --- a/kernel/include/kernel/KernelObject.hpp +++ b/kernel/include/kernel/KernelObject.hpp @@ -3,6 +3,7 @@ #include "rx/Rc.hpp" #include "rx/Serializer.hpp" #include "rx/TypeId.hpp" +#include #include #include @@ -75,8 +76,6 @@ struct ProcessScope; struct ThreadScope; } // namespace detail -template std::byte *getScopeStorage(); - template struct StaticKernelObjectStorage { template static std::uint32_t Allocate() { @@ -91,41 +90,30 @@ struct StaticKernelObjectStorage { instance.m_size = offset + sizeof(T); instance.m_alignment = std::max(alignof(T), instance.m_alignment); - // std::printf( - // "%s::Allocate(%s, %zu, %zu) -> %zu\n", - // rx::TypeId::get>().getName().data(), rx::TypeId::get().getName().data(), - // sizeof(T), alignof(T), offset); return offset; } static std::size_t GetSize() { return GetInstance().m_size; } static std::size_t GetAlignment() { return GetInstance().m_alignment; } - static std::byte *getScopeStorage() { - return kernel::getScopeStorage(); - } - static void ConstructAll() { + static void ConstructAll(std::byte *storage) { auto &instance = GetInstance(); - auto storage = getScopeStorage(); for (auto objectCtl : instance.m_registry) { objectCtl.construct(storage + objectCtl.offset); } } - static void DestructAll() { + static void DestructAll(std::byte *storage) { auto &instance = GetInstance(); - auto storage = getScopeStorage(); for (auto objectCtl : instance.m_registry) { objectCtl.destruct(storage + objectCtl.offset); } } - static void SerializeAll(rx::Serializer &s) { + static void SerializeAll(std::byte *storage, rx::Serializer &s) { auto &instance = GetInstance(); - auto storage = getScopeStorage(); s.serialize(instance.m_size); s.serialize(instance.m_registry.size()); @@ -135,9 +123,8 @@ struct StaticKernelObjectStorage { } } - static void DeserializeAll(rx::Deserializer &s) { + static void DeserializeAll(std::byte *storage, rx::Deserializer &s) { auto &instance = GetInstance(); - auto storage = getScopeStorage(); auto size = s.deserialize(); auto registrySize = s.deserialize(); @@ -163,18 +150,11 @@ private: std::size_t m_alignment = 1; }; -template -class StaticObjectRef { - std::uint32_t mOffset; +template +struct StaticObjectRef { + std::uint32_t offset; -public: - explicit StaticObjectRef(std::uint32_t offset) : mOffset(offset) {} - - T *get() { - return reinterpret_cast(getScopeStorage() + - mOffset); - } - - T *operator->() { return get(); } + T *get(std::byte *storage) { return reinterpret_cast(storage + offset); } }; + } // namespace kernel diff --git a/kernel/orbis/include/orbis/KernelContext.hpp b/kernel/orbis/include/orbis/KernelContext.hpp index 9053596bf..ee4338992 100644 --- a/kernel/orbis/include/orbis/KernelContext.hpp +++ b/kernel/orbis/include/orbis/KernelContext.hpp @@ -32,7 +32,7 @@ struct RcAppInfo : rx::RcBase, AppInfoEx { orbis::uint32_t appState = 0; }; -class alignas(__STDCPP_DEFAULT_NEW_ALIGNMENT__) KernelContext final { +class KernelContext final { public: KernelContext(); ~KernelContext(); diff --git a/kernel/orbis/include/orbis/KernelObject.hpp b/kernel/orbis/include/orbis/KernelObject.hpp index cdd6714f2..ba9cfbdce 100644 --- a/kernel/orbis/include/orbis/KernelObject.hpp +++ b/kernel/orbis/include/orbis/KernelObject.hpp @@ -1,23 +1,21 @@ #pragma once +#include "rx/Serializer.hpp" +#include #include namespace orbis { struct OrbisNamespace; -template -using GlobalObjectRef = - kernel::StaticObjectRef; +extern std::byte *g_globalStorage; -template -using ProcessLocalObjectRef = - kernel::StaticObjectRef; +template class GlobalObjectRef { + std::uint32_t mOffset; -template -using ThreadLocalObjectRef = - kernel::StaticObjectRef; +public: + explicit GlobalObjectRef(std::uint32_t offset) : mOffset(offset) {} + T *get() { return reinterpret_cast(g_globalStorage + mOffset); } + T *operator->() { return get(); } +}; template GlobalObjectRef createGlobalObject() { @@ -33,8 +31,7 @@ createProcessLocalObject() { auto layoutOffset = kernel::StaticKernelObjectStorage< OrbisNamespace, kernel::detail::ProcessScope>::template Allocate(); - return kernel::StaticObjectRef(layoutOffset); + return {layoutOffset}; } template @@ -42,67 +39,30 @@ kernel::StaticObjectRef createThreadLocalObject() { auto layoutOffset = kernel::StaticKernelObjectStorage< OrbisNamespace, kernel::detail::ThreadScope>::template Allocate(); - return kernel::StaticObjectRef(layoutOffset); + return {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(); + OrbisNamespace, + kernel::detail::GlobalScope>::ConstructAll(g_globalStorage); } inline void destructAllGlobals() { - kernel::StaticKernelObjectStorage::DestructAll(); -} - -inline void destructAllProcessLocals() { kernel::StaticKernelObjectStorage< - OrbisNamespace, kernel::detail::ProcessScope>::DestructAll(); -} - -inline void destructAllThreadLocals() { - kernel::StaticKernelObjectStorage::DestructAll(); + OrbisNamespace, + kernel::detail::GlobalScope>::DestructAll(g_globalStorage); } 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); + OrbisNamespace, + kernel::detail::GlobalScope>::SerializeAll(g_globalStorage, 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); + OrbisNamespace, + kernel::detail::GlobalScope>::DeserializeAll(g_globalStorage, s); } } // namespace orbis diff --git a/kernel/orbis/include/orbis/thread/Process.hpp b/kernel/orbis/include/orbis/thread/Process.hpp index ed3c0e36e..8fef4927f 100644 --- a/kernel/orbis/include/orbis/thread/Process.hpp +++ b/kernel/orbis/include/orbis/thread/Process.hpp @@ -1,4 +1,7 @@ #pragma once +#include "KernelAllocator.hpp" +#include "KernelObject.hpp" +#include "kernel/KernelObject.hpp" #include "orbis-config.hpp" #include "../event.hpp" @@ -15,6 +18,7 @@ #include "orbis/file.hpp" #include "orbis/module/Module.hpp" #include "rx/IdMap.hpp" +#include "rx/Serializer.hpp" #include "rx/SharedMutex.hpp" #include @@ -52,7 +56,13 @@ enum class ProcessType : std::uint8_t { }; struct Process final { + using Storage = + kernel::StaticKernelObjectStorage; + KernelContext *context = nullptr; + std::byte *storage = nullptr; + pid_t pid = -1; int gfxRing = 0; std::uint64_t hostPid = -1; @@ -101,5 +111,29 @@ struct Process final { // Named memory ranges for debugging rx::shared_mutex namedMemMutex; kmap namedMem; + + // FIXME: implement process destruction + void incRef() {} + void decRef() {} + + void allocate() { + if (auto size = Storage::GetSize()) { + storage = (std::byte *)kalloc(size, Storage::GetAlignment()); + } + } + + void deallocate() { + if (auto size = Storage::GetSize()) { + kfree(storage, size); + storage = nullptr; + } + } + + template + T *get( + kernel::StaticObjectRef + ref) { + return ref.get(storage); + } }; } // namespace orbis diff --git a/kernel/orbis/include/orbis/thread/Thread.hpp b/kernel/orbis/include/orbis/thread/Thread.hpp index ae53e4f50..e8a012608 100644 --- a/kernel/orbis/include/orbis/thread/Thread.hpp +++ b/kernel/orbis/include/orbis/thread/Thread.hpp @@ -1,8 +1,10 @@ #pragma once +#include "KernelObject.hpp" #include "ThreadState.hpp" #include "cpuset.hpp" #include "orbis-config.hpp" +#include "rx/Serializer.hpp" #include "types.hpp" #include "../KernelAllocator.hpp" @@ -16,9 +18,14 @@ namespace orbis { struct Process; static constexpr std::uint32_t kThreadSuspendFlag = 1 << 31; -struct Thread { +struct Thread final { + using Storage = + kernel::StaticKernelObjectStorage; + rx::shared_mutex mtx; Process *tproc = nullptr; + std::byte *storage = nullptr; uint64_t retval[2]{}; void *context{}; kvector altStack; @@ -75,6 +82,25 @@ struct Thread { void notifyUnblockedSignal(int signo); void setSigMask(SigSet newSigMask); + void allocate() { + if (auto size = Storage::GetSize()) { + storage = (std::byte *)kalloc(size, Storage::GetAlignment()); + } + } + + void deallocate() { + if (auto size = Storage::GetSize()) { + kfree(storage, size); + storage = nullptr; + } + } + + template + T *get(kernel::StaticObjectRef + ref) { + return ref.get(storage); + } + // FIXME: implement thread destruction void incRef() {} void decRef() {} diff --git a/kernel/orbis/src/KernelAllocator.cpp b/kernel/orbis/src/KernelAllocator.cpp index 1e46dea86..812f35899 100644 --- a/kernel/orbis/src/KernelAllocator.cpp +++ b/kernel/orbis/src/KernelAllocator.cpp @@ -39,7 +39,8 @@ struct KernelMemoryResource { }; static KernelMemoryResource *sMemoryResource; -static std::byte *sGlobalStorage; +std::byte *g_globalStorage; + using GlobalStorage = kernel::StaticKernelObjectStorage; @@ -69,15 +70,15 @@ void initializeAllocator() { rx::print(stderr, "global: size {}, alignment {}\n", GlobalStorage::GetSize(), GlobalStorage::GetAlignment()); // allocate whole global storage - sGlobalStorage = (std::byte *)sMemoryResource->kalloc( + g_globalStorage = (std::byte *)sMemoryResource->kalloc( GlobalStorage::GetSize(), GlobalStorage::GetAlignment()); } void deinitializeAllocator() { - sMemoryResource->kfree(sGlobalStorage, GlobalStorage::GetSize()); + sMemoryResource->kfree(g_globalStorage, GlobalStorage::GetSize()); delete sMemoryResource; sMemoryResource = nullptr; - sGlobalStorage = nullptr; + g_globalStorage = nullptr; } void *KernelMemoryResource::kalloc(std::size_t size, std::size_t align) { @@ -213,9 +214,3 @@ void *kalloc(std::size_t size, std::size_t align) { return sMemoryResource->kalloc(size, align); } } // namespace orbis - -template <> -std::byte * -kernel::getScopeStorage() { - return orbis::sGlobalStorage; -}