diff options
| author | Amlal El Mahrouss <amlal.elmahrouss@icloud.com> | 2024-01-06 09:14:11 +0100 |
|---|---|---|
| committer | Amlal El Mahrouss <amlal.elmahrouss@icloud.com> | 2024-01-06 09:14:11 +0100 |
| commit | 5339d016c07bf717ee388f4feb73544087324af0 (patch) | |
| tree | 94be6f67ed626091f24aee24ec3b3be03d01e4e7 /Source/SMPManager.cxx | |
git: port from mercurial repo.
Signed-off-by: Amlal El Mahrouss <amlal.elmahrouss@icloud.com>
Diffstat (limited to 'Source/SMPManager.cxx')
| -rw-r--r-- | Source/SMPManager.cxx | 134 |
1 files changed, 134 insertions, 0 deletions
diff --git a/Source/SMPManager.cxx b/Source/SMPManager.cxx new file mode 100644 index 00000000..25dbc0cf --- /dev/null +++ b/Source/SMPManager.cxx @@ -0,0 +1,134 @@ +/* + * ======================================================== + * + * hCore + * Copyright Mahrouss Logic, all rights reserved. + * + * ======================================================== + */ + +#include <KernelKit/SMPManager.hpp> +#include <KernelKit/ProcessManager.hpp> +#include <ArchKit/Arch.hpp> + +//! This file handles multi processing in hCore. + +namespace hCore +{ + // @brief wakes up thread. + // wakes up thread from hang. + extern void rt_wakeup_thread(HAL::StackFrame* stack); + + // @brief makes thread sleep. + // hooks and hangs thread to prevent code from executing. + extern void rt_hang_thread(HAL::StackFrame* stack); + + // A ProcessorCore class takes care of it's owned hardware thread. + // It has a stack for it's core. + + // @brief constructor + ProcessorCore::ProcessorCore() = default; + + // @brief destructor + ProcessorCore::~ProcessorCore() = default; + + //! @brief returns the id + + const ThreadID& ProcessorCore::ID() noexcept { return m_ID; } + + //! @brief returns the kind + + const ThreadKind& ProcessorCore::Kind() noexcept { return m_Kind; } + + //! @brief is the core busy? + + bool ProcessorCore::IsBusy() noexcept { return m_Busy; } + + HAL::StackFrame* ProcessorCore::StackFrame() noexcept + { + MUST_PASS(m_Stack); + return m_Stack; + } + + void ProcessorCore::Busy(const bool busy) noexcept { m_Busy = busy; } + + ProcessorCore::operator bool() { return m_Stack; } + + void ProcessorCore::Wake(const bool wakeup) noexcept + { + m_Wakeup = wakeup; + + if (!m_Wakeup) + rt_hang_thread(m_Stack); + else + rt_wakeup_thread(m_Stack); + } + + bool ProcessorCore::Switch(HAL::StackFrame* stack) + { + if (stack == nullptr) + return false; + + return rt_do_context_switch(m_Stack, stack) == 0; + } + + ///! @brief Tells if processor is waked up. + bool ProcessorCore::IsWakeup() noexcept { return m_Wakeup; } + + //! @brief Constructor and destructor + + ///! @brief Default constructor. + SMPManager::SMPManager() = default; + + ///! @brief Default destructor. + SMPManager::~SMPManager() = default; + + Ref<SMPManager> SMPManager::Shared() + { + static SMPManager manager; + return { manager }; + } + + HAL::StackFramePtr SMPManager::GetStack() noexcept + { + if (m_ThreadList[m_CurrentThread].Leak() && + ProcessHelper::GetCurrentPID() == m_ThreadList[m_CurrentThread].Leak().Leak().m_PID) + return m_ThreadList[m_CurrentThread].Leak().Leak().m_Stack; + + return nullptr; + } + + // @brief Finds and switch to a free core. + bool SMPManager::Switch(HAL::StackFrame* stack) + { + if (stack == nullptr) + return false; + + for (SizeT idx = 0; idx < kMaxHarts; ++idx) + { + // stack != nullptr -> if core is used, then continue. + if (!m_ThreadList[idx].Leak() || + !m_ThreadList[idx].Leak().Leak().IsWakeup() || + !m_ThreadList[idx].Leak().Leak().IsBusy()) + continue; + + m_ThreadList[idx].Leak().Leak().m_ID = idx; + m_ThreadList[idx].Leak().Leak().m_Stack = stack; + m_ThreadList[idx].Leak().Leak().m_PID = ProcessHelper::GetCurrentPID(); + + m_ThreadList[idx].Leak().Leak().Busy(true); + + bool ret = rt_do_context_switch(rt_get_current_context(), stack) == 0; + + m_ThreadList[idx].Leak().Leak().Busy(false); + } + + return false; + } + + Ref<ProcessorCore> SMPManager::operator[](const SizeT& idx) { return m_ThreadList[idx].Leak(); } + + SMPManager::operator bool() noexcept { return !m_ThreadList.Empty(); } + + bool SMPManager::operator!() noexcept { return m_ThreadList.Empty(); } +} // namespace hCore |
