diff options
| author | Amlal El Mahrouss <amlal.elmahrouss@icloud.com> | 2024-09-05 11:54:27 +0200 |
|---|---|---|
| committer | Amlal El Mahrouss <amlal.elmahrouss@icloud.com> | 2024-09-05 11:54:27 +0200 |
| commit | 3e2b931d65582284e9716c42a902cab6d279c7f0 (patch) | |
| tree | c3514953c6930e1eb465dcfb5ff1300154ade965 /dev/ZKA/Sources/HardwareThreadScheduler.cxx | |
| parent | 270223aea3a48f2d250525869c30fff418356ef3 (diff) | |
[ IMP ] Add Interrupt for scheduler (for APIC, maybe PIT?)
[ IMP ] Fixed user scheduler context switching.
Signed-off-by: Amlal El Mahrouss <amlal.elmahrouss@icloud.com>
Diffstat (limited to 'dev/ZKA/Sources/HardwareThreadScheduler.cxx')
| -rw-r--r-- | dev/ZKA/Sources/HardwareThreadScheduler.cxx | 200 |
1 files changed, 200 insertions, 0 deletions
diff --git a/dev/ZKA/Sources/HardwareThreadScheduler.cxx b/dev/ZKA/Sources/HardwareThreadScheduler.cxx new file mode 100644 index 00000000..b130ef63 --- /dev/null +++ b/dev/ZKA/Sources/HardwareThreadScheduler.cxx @@ -0,0 +1,200 @@ +/* ------------------------------------------- + + Copyright ZKA Technologies. + +------------------------------------------- */ + +#include <ArchKit/ArchKit.hxx> +#include <KernelKit/UserProcessScheduler.hxx> +#include <KernelKit/HardwareThreadScheduler.hxx> +#include <CFKit/Property.hxx> + +///! BUGS: 0 + +///! @file MP.cxx +///! @brief This file handles multi processing in the Kernel. +///! @brief Multi processing is needed for multi-tasking operations. + +namespace Kernel +{ + ///! A HardwareThread class takes care of it's owned hardware thread. + ///! It has a stack for it's core. + + ///! @brief C++ constructor. + HardwareThread::HardwareThread() = default; + + ///! @brief C++ destructor. + HardwareThread::~HardwareThread() = default; + + //! @brief returns the id of the thread. + const ThreadID& HardwareThread::ID() noexcept + { + return fID; + } + + //! @brief returns the kind of thread we have. + const ThreadKind& HardwareThread::Kind() noexcept + { + return fKind; + } + + //! @brief is the thread busy? + Bool HardwareThread::IsBusy() noexcept + { + return fBusy; + } + + /// @brief Get processor stack frame. + + HAL::StackFramePtr HardwareThread::StackFrame() noexcept + { + MUST_PASS(fStack); + return fStack; + } + + Void HardwareThread::Busy(const Bool busy) noexcept + { + fBusy = busy; + } + + HardwareThread::operator bool() + { + return fStack; + } + + /// @brief Wakeup the processor. + + Void HardwareThread::Wake(const bool wakeup) noexcept + { + fWakeup = wakeup; + + if (!fWakeup) + mp_hang_thread(fStack); + else + mp_wakeup_thread(fStack); + } + + /// @note Those symbols are needed in order to switch and validate the stack. + + EXTERN Bool hal_check_stack(HAL::StackFramePtr stackPtr); + EXTERN_C Bool mp_register_process(HAL::StackFramePtr stackPtr); + + /// @brief Switch to hardware thread. + /// @param stack the new hardware thread. + /// @retval true stack was changed, code is running. + /// @retval false stack is invalid, previous code is running. + Bool HardwareThread::Switch(VoidPtr image, UInt8* stack_ptr, HAL::StackFramePtr frame) + { + if (!frame || + !image || + !stack_ptr) + return false; + + if (this->IsBusy()) + return false; + + fStack = frame; + + if (kHandoverHeader->f_HardwareTables.f_MultiProcessingEnabled) + { + this->Busy(true); + Bool ret = mp_register_process(fStack); + this->Busy(true); + + return ret; + } + else + { + mp_do_context_switch_pre(); + mp_do_context_switch(image, stack_ptr, fStack); + + return true; + } + } + + ///! @brief Tells if processor is waked up. + bool HardwareThread::IsWakeup() noexcept + { + return fWakeup; + } + + ///! @brief Internal Hardware Thread list. + STATIC HardwareThread cThreadList[cMaxHWThreads]; + + ///! @brief Constructor and destructors. + + ///! @brief Default constructor. + HardwareThreadScheduler::HardwareThreadScheduler() = default; + + ///! @brief Default destructor. + HardwareThreadScheduler::~HardwareThreadScheduler() = default; + + /// @brief Shared singleton function + HardwareThreadScheduler& HardwareThreadScheduler::The() + { + STATIC HardwareThreadScheduler sched; + return sched; + } + + /// @brief Get Stack Frame of Core + HAL::StackFramePtr HardwareThreadScheduler::Leak() noexcept + { + return fThreadList[fCurrentThread].fStack; + } + + /** + * Get Hardware thread at index. + * @param idx the index + * @return the reference to the hardware thread. + */ + Ref<HardwareThread*> HardwareThreadScheduler::operator[](const SizeT& idx) + { + if (idx == 0) + { + if (fThreadList[idx].Kind() != kHartSystemReserved) + { + fThreadList[idx].fKind = kHartBoot; + } + } + else if (idx >= cMaxHWThreads) + { + static HardwareThread* fakeThread = new HardwareThread(); + + if (!fakeThread) + { + fakeThread = new HardwareThread(); + } + + fakeThread->fKind = kInvalidHart; + + return {fakeThread}; + } + + return &fThreadList[idx]; + } + + /** + * Check if thread pool isn't empty. + * @return + */ + HardwareThreadScheduler::operator bool() noexcept + { + return !fThreadList.Empty(); + } + + /** + * Reverse operator bool + * @return + */ + bool HardwareThreadScheduler::operator!() noexcept + { + return fThreadList.Empty(); + } + + /// @brief Returns the amount of core present. + /// @return the number of cores. + SizeT HardwareThreadScheduler::Count() noexcept + { + return fThreadList.Count(); + } +} // namespace Kernel |
