diff options
| -rw-r--r-- | dev/Kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc | 71 | ||||
| -rw-r--r-- | dev/Kernel/HALKit/AMD64/HalDescriptorLoader.cc | 6 | ||||
| -rw-r--r-- | dev/Kernel/HALKit/AMD64/HalInterruptAPI.asm | 95 | ||||
| -rw-r--r-- | dev/Kernel/HALKit/AMD64/HalKernelMain.cc | 13 | ||||
| -rw-r--r-- | dev/Kernel/HALKit/AMD64/HalUtils.asm | 1 | ||||
| -rw-r--r-- | dev/Kernel/KernelKit/Defines.h | 2 | ||||
| -rw-r--r-- | dev/Kernel/KernelKit/IPEFDLLObject.h | 4 | ||||
| -rw-r--r-- | dev/Kernel/KernelKit/Semaphore.h | 10 | ||||
| -rw-r--r-- | dev/Kernel/KernelKit/UserProcessScheduler.h | 30 | ||||
| -rw-r--r-- | dev/Kernel/KernelKit/UserProcessScheduler.inl | 2 | ||||
| -rw-r--r-- | dev/Kernel/NewKit/Array.h | 20 | ||||
| -rw-r--r-- | dev/Kernel/src/CodeMgr.cc | 16 | ||||
| -rw-r--r-- | dev/Kernel/src/IPEFDLLObject.cc | 14 | ||||
| -rw-r--r-- | dev/Kernel/src/PEFCodeMgr.cc | 28 | ||||
| -rw-r--r-- | dev/Kernel/src/Semaphore.cc | 9 | ||||
| -rw-r--r-- | dev/Kernel/src/UserProcessScheduler.cc | 161 | ||||
| -rw-r--r-- | dev/Kernel/src/UserProcessTeam.cc | 11 | ||||
| -rw-r--r-- | doc/OS-Scheduler-Design.drawio | 4 |
18 files changed, 265 insertions, 232 deletions
diff --git a/dev/Kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc b/dev/Kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc index 771a1e33..32be8dee 100644 --- a/dev/Kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc +++ b/dev/Kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc @@ -9,24 +9,31 @@ #include <NewKit/KString.h> #include <POSIXKit/signal.h> +STATIC BOOL kIsScheduling = NO; + /// @brief Handle GPF fault. /// @param rsp EXTERN_C void idt_handle_gpf(Kernel::UIntPtr rsp) { - kcout << "Kernel: GPF.\r"; - auto process = Kernel::UserProcessScheduler::The().GetCurrentProcess(); if (!process) Kernel::ke_panic(RUNTIME_CHECK_PAGE); + if (process.Leak().Status != Kernel::ProcessStatusKind::kRunning) + return; + + kIsScheduling = NO; + + kcout << "Kernel: GPF.\r"; + process.Leak().ProcessSignal.SignalIP = 0UL; process.Leak().ProcessSignal.SignalID = SIGKILL; process.Leak().ProcessSignal.PreviousStatus = process.Leak().Status; kcout << "Kernel: PRCFROZE status set..\r"; - process.Leak().Status = Kernel::ProcessStatusKind::kFrozen; + process.Leak().Status = Kernel::ProcessStatusKind::kKilled; process.Leak().Crash(); } @@ -35,21 +42,26 @@ EXTERN_C void idt_handle_gpf(Kernel::UIntPtr rsp) /// @param rsp EXTERN_C void idt_handle_pf(Kernel::UIntPtr rsp) { - kcout << "Kernel: Page Fault.\r"; - kcout << "Kernel: SIGKILL set.\r"; - auto process = Kernel::UserProcessScheduler::The().GetCurrentProcess(); if (!process) Kernel::ke_panic(RUNTIME_CHECK_PAGE); + if (process.Leak().Status != Kernel::ProcessStatusKind::kRunning) + return; + + kIsScheduling = NO; + + kcout << "Kernel: Page Fault.\r"; + kcout << "Kernel: SIGKILL set.\r"; + process.Leak().ProcessSignal.SignalIP = 0UL; process.Leak().ProcessSignal.SignalID = SIGKILL; process.Leak().ProcessSignal.PreviousStatus = process.Leak().Status; kcout << "Kernel: PRCFROZE status set..\r"; - process.Leak().Status = Kernel::ProcessStatusKind::kFrozen; + process.Leak().Status = Kernel::ProcessStatusKind::kKilled; process.Leak().Crash(); @@ -59,10 +71,9 @@ EXTERN_C void idt_handle_pf(Kernel::UIntPtr rsp) /// @brief Handle scheduler interrupt. EXTERN_C void idt_handle_scheduler(Kernel::UIntPtr rsp) { - static BOOL is_scheduling = NO; static Kernel::Int64 try_count_before_brute = 100000UL; - while (is_scheduling) + while (kIsScheduling) { --try_count_before_brute; @@ -71,32 +82,37 @@ EXTERN_C void idt_handle_scheduler(Kernel::UIntPtr rsp) } try_count_before_brute = 100000UL; - is_scheduling = YES; + kIsScheduling = YES; kcout << "Kernel: Timer IRQ (Scheduler Notification).\r"; Kernel::UserProcessHelper::StartScheduling(); - is_scheduling = NO; + kIsScheduling = NO; } /// @brief Handle math fault. /// @param rsp EXTERN_C void idt_handle_math(Kernel::UIntPtr rsp) { - kcout << "Kernel: Math error (division by zero?).\r"; - auto process = Kernel::UserProcessScheduler::The().GetCurrentProcess(); if (!process) Kernel::ke_panic(RUNTIME_CHECK_PAGE); + if (process.Leak().Status != Kernel::ProcessStatusKind::kRunning) + return; + + kIsScheduling = NO; + + kcout << "Kernel: Math error (division by zero?).\r"; + process.Leak().ProcessSignal.SignalIP = 0UL; process.Leak().ProcessSignal.SignalID = SIGKILL; process.Leak().ProcessSignal.PreviousStatus = process.Leak().Status; kcout << "Kernel: PRCFROZE status set..\r"; - process.Leak().Status = Kernel::ProcessStatusKind::kFrozen; + process.Leak().Status = Kernel::ProcessStatusKind::kKilled; process.Leak().Crash(); @@ -107,20 +123,25 @@ EXTERN_C void idt_handle_math(Kernel::UIntPtr rsp) /// @param rsp EXTERN_C void idt_handle_generic(Kernel::UIntPtr rsp) { - kcout << "Kernel: Generic Process Fault.\r"; - auto process = Kernel::UserProcessScheduler::The().GetCurrentProcess(); if (!process) Kernel::ke_panic(RUNTIME_CHECK_PAGE); + if (process.Leak().Status != Kernel::ProcessStatusKind::kRunning) + return; + + kIsScheduling = NO; + + kcout << "Kernel: Generic Process Fault.\r"; + process.Leak().ProcessSignal.SignalIP = 0UL; process.Leak().ProcessSignal.SignalID = SIGKILL; process.Leak().ProcessSignal.PreviousStatus = process.Leak().Status; kcout << "Kernel: PRCFROZE status set..\r"; - process.Leak().Status = Kernel::ProcessStatusKind::kFrozen; + process.Leak().Status = Kernel::ProcessStatusKind::kKilled; process.Leak().Crash(); @@ -134,6 +155,11 @@ EXTERN_C Kernel::Void idt_handle_breakpoint(Kernel::UIntPtr rip) if (!process) Kernel::ke_panic(RUNTIME_CHECK_PAGE); + if (process.Leak().Status != Kernel::ProcessStatusKind::kRunning) + return; + + kIsScheduling = NO; + kcout << "Kernel: Process RIP: " << Kernel::hex_number(rip) << endl; kcout << "Kernel: SIGTRAP set.\r"; @@ -151,20 +177,25 @@ EXTERN_C Kernel::Void idt_handle_breakpoint(Kernel::UIntPtr rip) /// @param rsp EXTERN_C void idt_handle_ud(Kernel::UIntPtr rsp) { - kcout << "Kernel: Undefined Opcode.\r"; - auto process = Kernel::UserProcessScheduler::The().GetCurrentProcess(); if (!process) Kernel::ke_panic(RUNTIME_CHECK_PAGE); + if (process.Leak().Status != Kernel::ProcessStatusKind::kRunning) + return; + + kIsScheduling = NO; + + kcout << "Kernel: Undefined Opcode.\r"; + process.Leak().ProcessSignal.SignalIP = 0UL; process.Leak().ProcessSignal.SignalID = SIGKILL; process.Leak().ProcessSignal.PreviousStatus = process.Leak().Status; kcout << "Kernel: PRCFROZE status set..\r"; - process.Leak().Status = Kernel::ProcessStatusKind::kFrozen; + process.Leak().Status = Kernel::ProcessStatusKind::kKilled; process.Leak().Crash(); diff --git a/dev/Kernel/HALKit/AMD64/HalDescriptorLoader.cc b/dev/Kernel/HALKit/AMD64/HalDescriptorLoader.cc index 8f20e8ae..ed9bf15b 100644 --- a/dev/Kernel/HALKit/AMD64/HalDescriptorLoader.cc +++ b/dev/Kernel/HALKit/AMD64/HalDescriptorLoader.cc @@ -26,11 +26,11 @@ namespace Kernel::HAL // Configure PIT to receieve scheduler interrupts. - UInt16 cCommonDivisor = kPITFrequency / ticks; // 100 Hz. + UInt16 cCommDivisor = kPITFrequency / ticks; // 100 Hz. HAL::rt_out8(kPITControlPort, 0x36); // Command to PIT - HAL::rt_out8(kPITChannel0Port, cCommonDivisor & 0xFF); // Send low byte - HAL::rt_out8(kPITChannel0Port, (cCommonDivisor >> 8) & 0xFF); // Send high byte + HAL::rt_out8(kPITChannel0Port, cCommDivisor & 0xFF); // Send low byte + HAL::rt_out8(kPITChannel0Port, (cCommDivisor >> 8) & 0xFF); // Send high byte hal_clear_irq_mask(32); } diff --git a/dev/Kernel/HALKit/AMD64/HalInterruptAPI.asm b/dev/Kernel/HALKit/AMD64/HalInterruptAPI.asm index 11deca52..fbc7cda8 100644 --- a/dev/Kernel/HALKit/AMD64/HalInterruptAPI.asm +++ b/dev/Kernel/HALKit/AMD64/HalInterruptAPI.asm @@ -16,26 +16,32 @@ %macro IntExp 1 global __ZKA_INT_%1 __ZKA_INT_%1: - cli + cld mov al, 0x20 out 0xA0, al out 0x20, al - sti + push rcx + call idt_handle_generic + pop rcx + + + + std o64 iret %endmacro %macro IntNormal 1 global __ZKA_INT_%1 __ZKA_INT_%1: - cli + cld mov al, 0x20 out 0xA0, al out 0x20, al - sti + std o64 iret %endmacro @@ -55,25 +61,31 @@ extern idt_handle_breakpoint section .text __ZKA_INT_0: - cli + cld mov al, 0x20 out 0x20, al - sti + std o64 iret __ZKA_INT_1: - cli + cld mov al, 0x20 out 0x20, al - sti + push rcx + call idt_handle_generic + pop rcx + + + + std o64 iret __ZKA_INT_2: - cli + cld mov al, 0x20 out 0x20, al @@ -82,12 +94,14 @@ __ZKA_INT_2: call idt_handle_generic pop rcx - sti + + + std o64 iret ;; @brief Triggers a breakpoint and freeze the process. RIP is also fetched. __ZKA_INT_3: - cli + cld mov al, 0x20 out 0x20, al @@ -95,11 +109,14 @@ __ZKA_INT_3: push rcx call idt_handle_generic pop rcx - sti + + + + std o64 iret __ZKA_INT_4: - cli + cld mov al, 0x20 out 0x20, al @@ -108,21 +125,27 @@ __ZKA_INT_4: push rcx call idt_handle_generic pop rcx - sti + + + + + std o64 iret __ZKA_INT_5: - cli + cld mov al, 0x20 out 0x20, al - sti + + + std o64 iret ;; Invalid opcode interrupt __ZKA_INT_6: - cli + cld mov al, 0x20 out 0x20, al @@ -131,11 +154,13 @@ __ZKA_INT_6: call idt_handle_generic pop rcx - sti + + + std o64 iret __ZKA_INT_7: - cli + cld mov al, 0x20 out 0x20, al @@ -144,12 +169,14 @@ __ZKA_INT_7: call idt_handle_generic pop rcx - sti + + + std o64 iret ;; Invalid opcode interrupt __ZKA_INT_8: - cli + cld mov al, 0x20 out 0xA0, al @@ -159,7 +186,7 @@ __ZKA_INT_8: call idt_handle_generic pop rcx - sti + std o64 iret IntNormal 9 @@ -169,7 +196,7 @@ IntExp 11 IntExp 12 __ZKA_INT_13: - cli + cld mov al, 0x20 out 0xA0, al @@ -179,11 +206,13 @@ __ZKA_INT_13: call idt_handle_gpf pop rcx - sti + add qword [rsp + 4], 2 + + std o64 iret __ZKA_INT_14: - cli + cld mov al, 0x20 out 0xA0, al @@ -193,7 +222,9 @@ __ZKA_INT_14: call idt_handle_pf pop rcx - sti + add qword [rsp + 4], 2 + + std o64 iret IntNormal 15 @@ -219,7 +250,7 @@ IntNormal 31 [extern idt_handle_scheduler] __ZKA_INT_32: - cli + cld mov al, 0x20 out 0xA0, al @@ -230,7 +261,7 @@ __ZKA_INT_32: call idt_handle_scheduler pop rax - sti + std o64 iret IntNormal 33 @@ -258,7 +289,7 @@ IntNormal 49 [extern hal_kernel_call_enter] __ZKA_INT_50: - cli + cld mov al, 0x20 out 0xA0, al @@ -273,12 +304,12 @@ __ZKA_INT_50: call rax pop rax - sti + std o64 iret __ZKA_INT_51: - cli + cld mov al, 0x20 out 0xA0, al @@ -293,7 +324,7 @@ __ZKA_INT_51: call rax pop rax - sti + std o64 iret diff --git a/dev/Kernel/HALKit/AMD64/HalKernelMain.cc b/dev/Kernel/HALKit/AMD64/HalKernelMain.cc index 5de6ddd9..25bb1de3 100644 --- a/dev/Kernel/HALKit/AMD64/HalKernelMain.cc +++ b/dev/Kernel/HALKit/AMD64/HalKernelMain.cc @@ -24,6 +24,14 @@ EXTERN_C Kernel::Void rtl_kernel_main(Kernel::SizeT argc, char** argv, char** en STATIC Kernel::Void hal_init_cxx_ctors() { + for (Kernel::SizeT i = 0U; i < Kernel::UserProcessScheduler::The().CurrentTeam().AsArray().Count(); ++i) + { + Kernel::UserProcessScheduler::The().CurrentTeam().AsArray()[i] = Kernel::UserThread(); + Kernel::UserProcessScheduler::The().CurrentTeam().AsArray()[i].Status = Kernel::ProcessStatusKind::kKilled; + } + + Kernel::UserProcessScheduler::The().CurrentTeam().mProcessCount = 0UL; + for (Kernel::SizeT index = 0UL; __CTOR_LIST__[index] != __DTOR_LIST__; ++index) { Kernel::rtl_ctor_kind constructor_cxx = (Kernel::rtl_ctor_kind)__CTOR_LIST__[index]; @@ -85,7 +93,10 @@ EXTERN_C Kernel::Void hal_real_init(Kernel::Void) noexcept { auto str_proc = Kernel::rt_alloc_string("System"); - Kernel::rtl_create_process(rtl_kernel_main, str_proc); + auto pid = Kernel::rtl_create_process(rtl_kernel_main, str_proc); + + Kernel::UserProcessScheduler::The().CurrentTeam().AsArray()[pid].PTime = 0; + Kernel::UserProcessScheduler::The().CurrentTeam().AsArray()[pid].Status = Kernel::ProcessStatusKind::kRunning; delete str_proc; str_proc = nullptr; diff --git a/dev/Kernel/HALKit/AMD64/HalUtils.asm b/dev/Kernel/HALKit/AMD64/HalUtils.asm index e48f7311..bd515e22 100644 --- a/dev/Kernel/HALKit/AMD64/HalUtils.asm +++ b/dev/Kernel/HALKit/AMD64/HalUtils.asm @@ -23,5 +23,4 @@ rt_install_tib: ;; //////////////////////////////////////////////////// ;; -[extern cBspDone] [extern kApicMadtAddressesCount] diff --git a/dev/Kernel/KernelKit/Defines.h b/dev/Kernel/KernelKit/Defines.h index 26618c93..abebdfdb 100644 --- a/dev/Kernel/KernelKit/Defines.h +++ b/dev/Kernel/KernelKit/Defines.h @@ -12,4 +12,4 @@ #define KERNELKIT_VERSION_BCD 0x01020 class UserProcessScheduler; -class UserProcess; +class UserThread; diff --git a/dev/Kernel/KernelKit/IPEFDLLObject.h b/dev/Kernel/KernelKit/IPEFDLLObject.h index 579587ee..1781c589 100644 --- a/dev/Kernel/KernelKit/IPEFDLLObject.h +++ b/dev/Kernel/KernelKit/IPEFDLLObject.h @@ -99,8 +99,8 @@ namespace Kernel typedef IPEFDLLObject* IDLL; - EXTERN_C IDLL rtl_init_dylib(UserProcess* header); - EXTERN_C Void rtl_fini_dylib(UserProcess* header, IDLL lib, Bool* successful); + EXTERN_C IDLL rtl_init_dylib(UserThread& header); + EXTERN_C Void rtl_fini_dylib(UserThread& header, IDLL lib, Bool* successful); } // namespace Kernel #endif /* ifndef __KERNELKIT_SHARED_OBJECT_H__ */ diff --git a/dev/Kernel/KernelKit/Semaphore.h b/dev/Kernel/KernelKit/Semaphore.h index 9ae3f617..41e02645 100644 --- a/dev/Kernel/KernelKit/Semaphore.h +++ b/dev/Kernel/KernelKit/Semaphore.h @@ -12,9 +12,9 @@ namespace Kernel { - class UserProcess; + class UserThread; - typedef UserProcess* UserProcessPtr; + typedef UserThread& UserProcessRef; /// @brief Access control class, which locks a task until one is done. class Semaphore final @@ -31,13 +31,13 @@ namespace Kernel void WaitForProcess() noexcept; public: - bool Lock(UserProcess* process); - bool LockOrWait(UserProcess* process, TimerInterface* timer); + bool Lock(UserThread& process); + bool LockOrWait(UserThread& process, TimerInterface* timer); public: ZKA_COPY_DEFAULT(Semaphore); private: - UserProcessPtr fLockingProcess{nullptr}; + UserProcessRef fLockingProcess; }; } // namespace Kernel diff --git a/dev/Kernel/KernelKit/UserProcessScheduler.h b/dev/Kernel/KernelKit/UserProcessScheduler.h index 744ad45a..452a55a3 100644 --- a/dev/Kernel/KernelKit/UserProcessScheduler.h +++ b/dev/Kernel/KernelKit/UserProcessScheduler.h @@ -31,7 +31,7 @@ namespace Kernel //! @note Forward class declarations. class IDLLObject; - class UserProcess; + class UserThread; class UserProcessTeam; class UserProcessScheduler; class UserProcessHelper; @@ -142,16 +142,16 @@ namespace Kernel } }; - /// @name UserProcess + /// @name UserThread /// @brief User process class, holds information about the running process/thread. - class UserProcess final + class UserThread final { public: - explicit UserProcess(); - ~UserProcess(); + explicit UserThread(); + ~UserThread(); public: - ZKA_COPY_DEFAULT(UserProcess); + ZKA_COPY_DEFAULT(UserThread); public: Char Name[kProcessNameLen] = {"Process"}; @@ -261,18 +261,18 @@ namespace Kernel ZKA_COPY_DEFAULT(UserProcessTeam); - Array<UserProcess*, kSchedProcessLimitPerTeam>& AsArray(); - Ref<UserProcess>& AsRef(); + Array<UserThread, kSchedProcessLimitPerTeam>& AsArray(); + Ref<UserThread>& AsRef(); ProcessID& Id() noexcept; public: - Array<UserProcess*, kSchedProcessLimitPerTeam> mProcessList; - Ref<UserProcess> mCurrentProcess; + Array<UserThread, kSchedProcessLimitPerTeam> mProcessList; + Ref<UserThread> mCurrentProcess; ProcessID mTeamId{0}; ProcessID mProcessCount{0}; }; - using UserProcessPtr = UserProcess*; + using UserProcessRef = UserThread&; /// @brief Process scheduler class. /// The main class which you call to schedule user processes. @@ -293,7 +293,7 @@ namespace Kernel UserProcessTeam& CurrentTeam(); public: - ProcessID Spawn(UserProcess* process); + ProcessID Spawn(const Char* name, VoidPtr code, VoidPtr image); const Bool Remove(ProcessID process_id); const Bool IsUser() override; @@ -301,7 +301,7 @@ namespace Kernel const Bool HasMP() override; public: - Ref<UserProcess>& GetCurrentProcess(); + Ref<UserThread>& GetCurrentProcess(); const SizeT Run() noexcept; public: @@ -312,14 +312,14 @@ namespace Kernel }; /* - * \brief UserProcess helper class, which contains needed utilities for the scheduler. + * \brief UserThread helper class, which contains needed utilities for the scheduler. */ class UserProcessHelper final { public: STATIC Bool Switch(VoidPtr image_ptr, UInt8* stack_ptr, HAL::StackFramePtr frame_ptr, const PID& new_pid); - STATIC Bool CanBeScheduled(const UserProcess* process); + STATIC Bool CanBeScheduled(const UserThread& process); STATIC ErrorOr<PID> TheCurrentPID(); STATIC SizeT StartScheduling(); }; diff --git a/dev/Kernel/KernelKit/UserProcessScheduler.inl b/dev/Kernel/KernelKit/UserProcessScheduler.inl index 70f9f0a8..83ced960 100644 --- a/dev/Kernel/KernelKit/UserProcessScheduler.inl +++ b/dev/Kernel/KernelKit/UserProcessScheduler.inl @@ -14,7 +14,7 @@ namespace Kernel /***********************************************************************************/ template <typename T> - Boolean UserProcess::Delete(ErrorOr<T*> ptr, const SizeT& sz) + Boolean UserThread::Delete(ErrorOr<T*> ptr, const SizeT& sz) { if (!ptr || sz == 0) diff --git a/dev/Kernel/NewKit/Array.h b/dev/Kernel/NewKit/Array.h index 3ccfb6db..7d7197da 100644 --- a/dev/Kernel/NewKit/Array.h +++ b/dev/Kernel/NewKit/Array.h @@ -22,15 +22,9 @@ namespace Kernel Array& operator=(const Array&) = default; Array(const Array&) = default; - T& operator[](const SizeT& At) + T& operator[](const SizeT& at) { - return fArray[At]; - } - - T Assign(const SizeT& At, T NewVal) - { - fArray[At] = NewVal; - return fArray[At]; + return fArray[at]; } Boolean Empty() @@ -45,15 +39,7 @@ namespace Kernel const SizeT Count() { - SizeT count = 0; - - for (SizeT i = 0; i < N; i++) - { - if (fArray[i]) - ++count; - } - - return count; + return N; } const T* CData() diff --git a/dev/Kernel/src/CodeMgr.cc b/dev/Kernel/src/CodeMgr.cc index ccf0659b..6077ed82 100644 --- a/dev/Kernel/src/CodeMgr.cc +++ b/dev/Kernel/src/CodeMgr.cc @@ -23,20 +23,6 @@ namespace Kernel *process_name == 0) return kProcessInvalidID; - UserProcess* process_hdr = new UserProcess(); - - process_hdr->Image.fCode = reinterpret_cast<VoidPtr>(main); - process_hdr->Kind = UserProcess::kExectuableKind; - process_hdr->StackSize = kib_cast(8); - - rt_set_memory(process_hdr->Name, 0, kProcessNameLen); - rt_copy_memory((VoidPtr)process_name, process_hdr->Name, rt_string_len(process_name)); - - ProcessID id = UserProcessScheduler::The().Spawn(process_hdr); - - delete process_hdr; - process_hdr = nullptr; - - return id; + return UserProcessScheduler::The().Spawn(process_name, reinterpret_cast<VoidPtr>(main), nullptr); } } // namespace Kernel diff --git a/dev/Kernel/src/IPEFDLLObject.cc b/dev/Kernel/src/IPEFDLLObject.cc index acc53705..1b8d2451 100644 --- a/dev/Kernel/src/IPEFDLLObject.cc +++ b/dev/Kernel/src/IPEFDLLObject.cc @@ -39,13 +39,13 @@ using namespace Kernel; /** @brief Library initializer. */ /***********************************************************************************/ -EXTERN_C IDLL rtl_init_dylib(UserProcess* header) +EXTERN_C IDLL rtl_init_dylib(UserThread& header) { IDLL dll_obj = tls_new_class<IPEFDLLObject>(); if (!dll_obj) { - header->Crash(); + header.Crash(); return nullptr; } @@ -54,18 +54,18 @@ EXTERN_C IDLL rtl_init_dylib(UserProcess* header) if (!dll_obj->Get()) { tls_delete_class(dll_obj); - header->Crash(); + header.Crash(); return nullptr; } dll_obj->Get()->ImageObject = - header->Image.fBlob; + header.Image.fBlob; if (!dll_obj->Get()->ImageObject) { tls_delete_class(dll_obj); - header->Crash(); + header.Crash(); return nullptr; } @@ -83,7 +83,7 @@ EXTERN_C IDLL rtl_init_dylib(UserProcess* header) /** @param successful Reports if successful or not. */ /***********************************************************************************/ -EXTERN_C Void rtl_fini_dylib(UserProcess* header, IDLL dll_obj, Bool* successful) +EXTERN_C Void rtl_fini_dylib(UserThread& header, IDLL dll_obj, Bool* successful) { MUST_PASS(successful); @@ -91,7 +91,7 @@ EXTERN_C Void rtl_fini_dylib(UserProcess* header, IDLL dll_obj, Bool* successful if (dll_obj == nullptr) { *successful = false; - header->Crash(); + header.Crash(); } delete dll_obj->Get(); diff --git a/dev/Kernel/src/PEFCodeMgr.cc b/dev/Kernel/src/PEFCodeMgr.cc index 63925c6c..17f7f895 100644 --- a/dev/Kernel/src/PEFCodeMgr.cc +++ b/dev/Kernel/src/PEFCodeMgr.cc @@ -246,38 +246,24 @@ namespace Kernel namespace Utils { - ProcessID rtl_create_process(PEFLoader& exec, const Int32& procKind) noexcept + ProcessID rtl_create_process(PEFLoader& exec, const Int32& process_kind) noexcept { auto errOrStart = exec.FindStart(); if (errOrStart.Error() != kErrorSuccess) return kProcessInvalidID; - UserProcess* proc = new UserProcess(); + UserThread process; - proc->Kind = procKind; - proc->Image.fCode = errOrStart.Leak().Leak(); - proc->Image.fBlob = exec.GetBlob().Leak().Leak(); - proc->StackSize = *(UIntPtr*)exec.FindSymbol(kPefStackSizeSymbol, kPefData); - proc->MemoryLimit = *(UIntPtr*)exec.FindSymbol(kPefHeapSizeSymbol, kPefData); - proc->PTime = 0UL; + auto id = UserProcessScheduler::The().Spawn(reinterpret_cast<const Char*>(exec.FindSymbol(kPefNameSymbol, kPefData)), errOrStart.Leak().Leak(), exec.GetBlob().Leak().Leak()); - rt_set_memory(proc->Name, 0, kProcessNameLen); - - if (exec.FindSymbol(kPefNameSymbol, kPefData)) - rt_copy_memory(exec.FindSymbol(kPefNameSymbol, kPefData), proc->Name, rt_string_len((Char*)exec.FindSymbol(kPefNameSymbol, kPefData))); - - if (!proc->StackSize) + if (id != kProcessInvalidID) { - const auto kDefaultStackSizeMib = 8; - proc->StackSize = mib_cast(kDefaultStackSizeMib); + UserProcessScheduler::The().CurrentTeam().AsArray()[id].Kind = process_kind; + UserProcessScheduler::The().CurrentTeam().AsArray()[id].StackSize = *(UIntPtr*)exec.FindSymbol(kPefStackSizeSymbol, kPefData); + UserProcessScheduler::The().CurrentTeam().AsArray()[id].MemoryLimit = *(UIntPtr*)exec.FindSymbol(kPefHeapSizeSymbol, kPefData); } - auto id = UserProcessScheduler::The().Spawn(proc); - - if (id == kProcessInvalidID) - delete proc; - return id; } } // namespace Utils diff --git a/dev/Kernel/src/Semaphore.cc b/dev/Kernel/src/Semaphore.cc index 257fed48..b63d5be3 100644 --- a/dev/Kernel/src/Semaphore.cc +++ b/dev/Kernel/src/Semaphore.cc @@ -15,7 +15,7 @@ namespace Kernel Bool Semaphore::Unlock() noexcept { if (fLockingProcess) - fLockingProcess = nullptr; + fLockingProcess = UserThread(); else return No; @@ -25,7 +25,7 @@ namespace Kernel /***********************************************************************************/ /// @brief Locks process in the semaphore. /***********************************************************************************/ - Bool Semaphore::Lock(UserProcess* process) + Bool Semaphore::Lock(UserThread& process) { if (!process || fLockingProcess) return No; @@ -46,11 +46,8 @@ namespace Kernel /***********************************************************************************/ /// @brief Try lock or wait. /***********************************************************************************/ - Bool Semaphore::LockOrWait(UserProcess* process, TimerInterface* timer) + Bool Semaphore::LockOrWait(UserThread& process, TimerInterface* timer) { - if (process == nullptr) - return No; - if (timer == nullptr) return No; diff --git a/dev/Kernel/src/UserProcessScheduler.cc b/dev/Kernel/src/UserProcessScheduler.cc index 03fa58f6..5356ee65 100644 --- a/dev/Kernel/src/UserProcessScheduler.cc +++ b/dev/Kernel/src/UserProcessScheduler.cc @@ -12,6 +12,7 @@ /// @brief Low level/Ring-3 process scheduler. /***********************************************************************************/ +#include "NewKit/Macros.h" #include <KernelKit/UserProcessScheduler.h> #include <KernelKit/HardwareThreadScheduler.h> #include <KernelKit/IPEFDLLObject.h> @@ -36,8 +37,8 @@ namespace Kernel STATIC UserProcessScheduler kProcessScheduler; - UserProcess::UserProcess() = default; - UserProcess::~UserProcess() = default; + UserThread::UserThread() = default; + UserThread::~UserThread() = default; /// @brief Gets the last exit code. /// @note Not thread-safe. @@ -48,10 +49,10 @@ namespace Kernel } /***********************************************************************************/ - /// @brief Crashes the current process-> + /// @brief Crashes the current process. /***********************************************************************************/ - Void UserProcess::Crash() + Void UserThread::Crash() { if (this->Status != ProcessStatusKind::kRunning) return; @@ -64,7 +65,7 @@ namespace Kernel //! @brief boolean operator, check status. /***********************************************************************************/ - UserProcess::operator bool() + UserThread::operator bool() { return this->Status == ProcessStatusKind::kRunning; } @@ -75,7 +76,7 @@ namespace Kernel /// @return Int32 the last exit code. /***********************************************************************************/ - const UInt32& UserProcess::GetExitCode() noexcept + const UInt32& UserThread::GetExitCode() noexcept { return this->fLastExitCode; } @@ -84,7 +85,7 @@ namespace Kernel /// @brief Error code variable getter. /***********************************************************************************/ - Int32& UserProcess::GetLocalCode() noexcept + Int32& UserThread::GetLocalCode() noexcept { return this->fLocalCode; } @@ -94,7 +95,7 @@ namespace Kernel /// @param should_wakeup if the program shall wakeup or not. /***********************************************************************************/ - Void UserProcess::Wake(const bool should_wakeup) + Void UserThread::Wake(const bool should_wakeup) { this->Status = should_wakeup ? ProcessStatusKind::kRunning : ProcessStatusKind::kFrozen; @@ -104,7 +105,7 @@ namespace Kernel /** @brief Add pointer to entry. */ /***********************************************************************************/ - ErrorOr<VoidPtr> UserProcess::New(const SizeT& sz, const SizeT& pad_amount) + ErrorOr<VoidPtr> UserThread::New(const SizeT& sz, const SizeT& pad_amount) { #ifdef __ZKA_AMD64__ auto vm_register = hal_read_cr3(); @@ -119,7 +120,7 @@ namespace Kernel if (!this->ProcessMemoryHeap) { - this->ProcessMemoryHeap = new UserProcess::ProcessMemoryHeapList(); + this->ProcessMemoryHeap = new UserThread::ProcessMemoryHeapList(); this->ProcessMemoryHeap->MemoryEntryPad = pad_amount; this->ProcessMemoryHeap->MemoryEntrySize = sz; @@ -156,36 +157,36 @@ namespace Kernel } /***********************************************************************************/ - /// @brief Gets the name of the current process-> + /// @brief Gets the name of the current process. /***********************************************************************************/ - const Char* UserProcess::GetName() noexcept + const Char* UserThread::GetName() noexcept { return this->Name; } /***********************************************************************************/ - /// @brief Gets the owner of the process-> + /// @brief Gets the owner of the process. /***********************************************************************************/ - const User* UserProcess::GetOwner() noexcept + const User* UserThread::GetOwner() noexcept { return this->Owner; } - /// @brief UserProcess status getter. - const ProcessStatusKind& UserProcess::GetStatus() noexcept + /// @brief UserThread status getter. + const ProcessStatusKind& UserThread::GetStatus() noexcept { return this->Status; } /***********************************************************************************/ /** - @brief Affinity is the time slot allowed for the process-> + @brief Affinity is the time slot allowed for the process. */ /***********************************************************************************/ - const AffinityKind& UserProcess::GetAffinity() noexcept + const AffinityKind& UserThread::GetAffinity() noexcept { return this->Affinity; } @@ -197,7 +198,7 @@ namespace Kernel */ /***********************************************************************************/ - Void UserProcess::Exit(const Int32& exit_code) + Void UserThread::Exit(const Int32& exit_code) { this->Status = exit_code > 0 ? ProcessStatusKind::kKilled : ProcessStatusKind::kFrozen; this->fLastExitCode = exit_code; @@ -252,7 +253,7 @@ namespace Kernel { Bool success = false; - rtl_fini_dylib(this, reinterpret_cast<IPEFDLLObject*>(this->DylibDelegate), &success); + rtl_fini_dylib(*this, reinterpret_cast<IPEFDLLObject*>(this->DylibDelegate), &success); if (!success) { @@ -279,14 +280,30 @@ namespace Kernel /// @return the process index inside the team. /***********************************************************************************/ - ProcessID UserProcessScheduler::Spawn(UserProcess* process) + ProcessID UserProcessScheduler::Spawn(const Char* name, VoidPtr code, VoidPtr image) { + ProcessID pid = this->mTeam.mProcessCount; + + if (pid > kSchedProcessLimitPerTeam) + { + return kErrorProcessFault; + } + + ++this->mTeam.mProcessCount; + + UserThread& process = this->mTeam.mProcessList[pid]; + + process.Image.fCode = code; + process.Image.fBlob = image; + + rt_copy_memory(reinterpret_cast<VoidPtr>(const_cast<Char*>(name)), process.Name, rt_string_len(name)); + #ifdef __ZKA_AMD64__ - process->VMRegister = new PDE(); + process.VMRegister = new PDE(); - if (!process->VMRegister) + if (!process.VMRegister) { - process->Crash(); + process.Crash(); return kErrorProcessFault; } @@ -294,14 +311,14 @@ namespace Kernel flags |= HAL::kMMFlagsWr; flags |= HAL::kMMFlagsUser; - HAL::mm_map_page((VoidPtr)process->VMRegister, flags); + HAL::mm_map_page((VoidPtr)process.VMRegister, flags); #endif // __ZKA_AMD64__ - process->StackFrame = new HAL::StackFrame(); + process.StackFrame = new HAL::StackFrame(); - if (!process->StackFrame) + if (!process.StackFrame) { - process->Crash(); + process.Crash(); return kErrorProcessFault; } @@ -309,51 +326,39 @@ namespace Kernel flags |= HAL::kMMFlagsWr; flags |= HAL::kMMFlagsUser; - HAL::mm_map_page((VoidPtr)process->StackFrame, flags); + HAL::mm_map_page((VoidPtr)process.StackFrame, flags); // Create heap according to type of process. - if (process->Kind == UserProcess::kExectuableDLLKind) + if (process.Kind == UserThread::kExectuableDLLKind) { - process->DylibDelegate = rtl_init_dylib(process); - MUST_PASS(process->DylibDelegate); + process.DylibDelegate = rtl_init_dylib(process); + MUST_PASS(process.DylibDelegate); } - process->StackReserve = new UInt8[process->StackSize]; + process.StackReserve = new UInt8[process.StackSize]; flags = HAL::kMMFlagsPresent; flags |= HAL::kMMFlagsWr; flags |= HAL::kMMFlagsUser; - HAL::mm_map_page((VoidPtr)process->StackReserve, flags); + HAL::mm_map_page((VoidPtr)process.StackReserve, flags); - if (!process->StackReserve) + if (!process.StackReserve) { - process->Crash(); - return -kErrorProcessFault; + process.Crash(); + return kErrorProcessFault; } - ProcessID pid = this->mTeam.mProcessCount; - - if (pid > kSchedProcessLimitPerTeam && - pid != (kSchedProcessLimitPerTeam + 1)) - { - this->mTeam.mProcessCount = 0; - pid = 0UL; - } + process.ProcessParentTeam = &mTeam; - ++this->mTeam.mProcessCount; + process.ProcessId = pid; + process.Status = ProcessStatusKind::kStarting; + process.PTime = (UIntPtr)AffinityKind::kStandard; - process->ProcessParentTeam = &mTeam; + kcout << "PID: " << number(process.ProcessId) << endl; + kcout << "Name: " << process.Name << endl; - process->ProcessId = pid; - process->Status = ProcessStatusKind::kStarting; - process->PTime = (UIntPtr)AffinityKind::kStandard; - - this->mTeam.mProcessList.Assign(pid, process); - - kcout << "PID: " << number(process->ProcessId) << endl; - - return process->ProcessId; + return pid; } /***********************************************************************************/ @@ -380,7 +385,7 @@ namespace Kernel if (process_id > mTeam.mProcessList.Count()) return No; - mTeam.mProcessList[process_id]->Exit(0); + mTeam.mProcessList[process_id].Exit(0); return Yes; } @@ -426,25 +431,22 @@ namespace Kernel auto process = mTeam.AsArray()[process_index]; //! check if process needs to be scheduled. - if (process && UserProcessHelper::CanBeScheduled(process)) + if (UserProcessHelper::CanBeScheduled(process)) { // Set current process header. this->GetCurrentProcess() = process; - process->PTime = static_cast<Int32>(process->Affinity); + process.PTime = static_cast<Int32>(process.Affinity); - kcout << "Switch to '" << process->Name << "'.\r"; + kcout << "Switch to '" << process.Name << "'.\r"; // tell helper to find a core to schedule on. - if (!UserProcessHelper::Switch(process->Image.fCode, &process->StackReserve[process->StackSize - 1], process->StackFrame, - process->ProcessId)) - { - process->Crash(); - } + UserProcessHelper::Switch(process.Image.fCode, &process.StackReserve[process.StackSize - 1], process.StackFrame, + process.ProcessId); } else { - --process->PTime; + --process.PTime; } } @@ -460,15 +462,15 @@ namespace Kernel /// @internal - /// @brief Gets current running process-> + /// @brief Gets current running process. /// @return - Ref<UserProcess>& UserProcessScheduler::GetCurrentProcess() + Ref<UserThread>& UserProcessScheduler::GetCurrentProcess() { return mTeam.AsRef(); } /// @brief Current proccess id getter. - /// @return UserProcess ID integer. + /// @return UserThread ID integer. ErrorOr<PID> UserProcessHelper::TheCurrentPID() { if (!kProcessScheduler.GetCurrentProcess()) @@ -482,23 +484,24 @@ namespace Kernel /// @param process the process reference. /// @retval true can be schedulded. /// @retval false cannot be schedulded. - Bool UserProcessHelper::CanBeScheduled(const UserProcess* process) + Bool UserProcessHelper::CanBeScheduled(const UserThread& process) { - if (process->Status == ProcessStatusKind::kKilled || - process->Status == ProcessStatusKind::kFinished || - process->Status == ProcessStatusKind::kFrozen) + if (process.Status == ProcessStatusKind::kKilled || + process.Status == ProcessStatusKind::kFinished || + process.Status == ProcessStatusKind::kStarting || + process.Status == ProcessStatusKind::kFrozen) return No; - if (process->Status == ProcessStatusKind::kInvalid) + if (process.Status == ProcessStatusKind::kInvalid) return No; - if (!process->Image.fCode) + if (!process.Image.fCode) return No; - if (!process->Name[0]) + if (!process.Name[0]) return No; - return process->PTime < 1; + return process.PTime < 1; } /***********************************************************************************/ @@ -549,7 +552,7 @@ namespace Kernel //////////////////////////////////////////////////////////// auto prev_ptime = HardwareThreadScheduler::The()[index].Leak()->fPTime; - HardwareThreadScheduler::The()[index].Leak()->fPTime = UserProcessScheduler::The().CurrentTeam().AsArray()[new_pid]->PTime; + HardwareThreadScheduler::The()[index].Leak()->fPTime = UserProcessScheduler::The().CurrentTeam().AsArray()[new_pid].PTime; Bool ret = HardwareThreadScheduler::The()[index].Leak()->Switch(image_ptr, stack, frame_ptr, new_pid); //////////////////////////////////////////////////////////// @@ -560,7 +563,7 @@ namespace Kernel HardwareThreadScheduler::The()[index].Leak()->fPTime = prev_ptime; UserProcessHelper::TheCurrentPID().Leak().Leak() = prev_pid; - continue; + return false; } } } diff --git a/dev/Kernel/src/UserProcessTeam.cc b/dev/Kernel/src/UserProcessTeam.cc index 25b9daac..a41160cc 100644 --- a/dev/Kernel/src/UserProcessTeam.cc +++ b/dev/Kernel/src/UserProcessTeam.cc @@ -17,16 +17,19 @@ namespace Kernel { for (SizeT i = 0U; i < this->mProcessList.Count(); ++i) { - this->mProcessList[i] = nullptr; + this->mProcessList[i] = UserThread(); + this->mProcessList[i].Status = ProcessStatusKind::kKilled; } + + this->mProcessCount = 0UL; } /***********************************************************************************/ - /// @brief UserProcess list array getter. + /// @brief UserThread list array getter. /// @return The list of process to schedule. /***********************************************************************************/ - Array<UserProcess*, kSchedProcessLimitPerTeam>& UserProcessTeam::AsArray() + Array<UserThread, kSchedProcessLimitPerTeam>& UserProcessTeam::AsArray() { return this->mProcessList; } @@ -46,7 +49,7 @@ namespace Kernel /// @return The current process header. /***********************************************************************************/ - Ref<UserProcess>& UserProcessTeam::AsRef() + Ref<UserThread>& UserProcessTeam::AsRef() { return this->mCurrentProcess; } diff --git a/doc/OS-Scheduler-Design.drawio b/doc/OS-Scheduler-Design.drawio index c8a382c4..b91c3010 100644 --- a/doc/OS-Scheduler-Design.drawio +++ b/doc/OS-Scheduler-Design.drawio @@ -10,10 +10,10 @@ <mxCell id="ifhO3zQZNW-sXvZMTmu8-3" value="Running code (RING 3)" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1"> <mxGeometry x="235.5" y="295" width="360" height="35" as="geometry"/> </mxCell> - <mxCell id="ifhO3zQZNW-sXvZMTmu8-8" value="<h1 style="margin-top: 0px;"><span style="background-color: initial;">ZKA Scheduler</span></h1><h1 style="margin-top: 0px;"><span style="font-size: 12px; font-weight: 400; background-color: initial;">This describes how ZKA is structued to schedule tasks.</span><br></h1><div>A UserProcess may be attached to another one (thread)</div><div>Otherwise it's a process within a team.</div>" style="text;html=1;whiteSpace=wrap;overflow=hidden;rounded=0;" parent="1" vertex="1"> + <mxCell id="ifhO3zQZNW-sXvZMTmu8-8" value="<h1 style="margin-top: 0px;"><span style="background-color: initial;">ZKA Scheduler</span></h1><h1 style="margin-top: 0px;"><span style="font-size: 12px; font-weight: 400; background-color: initial;">This describes how ZKA is structued to schedule tasks.</span><br></h1><div>A UserThread may be attached to another one (thread)</div><div>Otherwise it's a process within a team.</div>" style="text;html=1;whiteSpace=wrap;overflow=hidden;rounded=0;" parent="1" vertex="1"> <mxGeometry x="620" y="290" width="180" height="200" as="geometry"/> </mxCell> - <mxCell id="ifhO3zQZNW-sXvZMTmu8-13" value="UserProcess structure (RING 0)" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1"> + <mxCell id="ifhO3zQZNW-sXvZMTmu8-13" value="UserThread structure (RING 0)" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1"> <mxGeometry x="235.5" y="380" width="360" height="60" as="geometry"/> </mxCell> <mxCell id="4" value="HardwareThread, HardwareThreadScheduler and UserProcessScheduler (RING 0)" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1"> |
