summaryrefslogtreecommitdiffhomepage
path: root/Private/Source/ProcessManager.cxx
diff options
context:
space:
mode:
authorAmlal El Mahrouss <amlal.elmahrouss@icloud.com>2024-01-28 14:33:43 +0100
committerAmlal El Mahrouss <amlal.elmahrouss@icloud.com>2024-01-28 14:33:43 +0100
commitf69bd40d5d97e371451d2e9c27721422141d828f (patch)
treecaceff362a4631bb66d92d87898687364e11f2ca /Private/Source/ProcessManager.cxx
parentb177e9c4c954170b590d777fe77442ff3a0cd8d7 (diff)
KernelKit/ProcessManager: add new ProcessPrimitives file, specific to
each architecture, lint-fix and improvements. Signed-off-by: Amlal El Mahrouss <amlal.elmahrouss@icloud.com>
Diffstat (limited to 'Private/Source/ProcessManager.cxx')
-rw-r--r--Private/Source/ProcessManager.cxx410
1 files changed, 213 insertions, 197 deletions
diff --git a/Private/Source/ProcessManager.cxx b/Private/Source/ProcessManager.cxx
index f37badee..5dcc98f2 100644
--- a/Private/Source/ProcessManager.cxx
+++ b/Private/Source/ProcessManager.cxx
@@ -24,275 +24,291 @@
namespace hCore
{
- static Int32 kExitCode = 0;
+static Int32 kExitCode = 0;
- const Int32& rt_get_exit_code() noexcept { return kExitCode; }
+const Int32 &rt_get_exit_code() noexcept
+{
+ return kExitCode;
+}
- void Process::Crash()
- {
- kcout << this->Name << ": Crashed.";
- this->Exit(-1);
- }
+void Process::Crash()
+{
+ kcout << this->Name << ": Crashed.";
+ this->Exit(-1);
+}
- void Process::Wake(const bool should_wakeup)
- {
- this->Status = should_wakeup ? ProcessStatus::kRunning : ProcessStatus::kFrozen;
- }
+void Process::Wake(const bool should_wakeup)
+{
+ this->Status = should_wakeup ? ProcessStatus::kRunning : ProcessStatus::kFrozen;
+}
- VoidPtr Process::New(const SizeT& sz)
- {
- // RAM allocation
- if (this->PoolCursor)
- {
- VoidPtr ptr = this->PoolCursor;
- this->PoolCursor = (VoidPtr)((UIntPtr)this->PoolCursor + (sizeof(sz) + kPoolAlign));
+VoidPtr Process::New(const SizeT &sz)
+{
+ if (this->FreeMemory < 1)
+ return nullptr;
- return ptr;
- }
+ // RAM allocation
+ if (this->PoolCursor)
+ {
+ VoidPtr ptr = this->PoolCursor;
+ this->PoolCursor = (VoidPtr)((UIntPtr)this->PoolCursor + (sizeof(sz) + kPoolAlign));
- //! TODO: Disk allocation
+ ++this->UsedMemory;
+ --this->FreeMemory;
- return nullptr;
+ return ptr;
}
- /* @brief checks if runtime pointer is in region. */
- bool rt_in_pool_region(VoidPtr pool_ptr, VoidPtr pool, const SizeT& sz)
+ //! TODO: Disk allocation
+
+ return nullptr;
+}
+
+/* @brief checks if runtime pointer is in region. */
+bool rt_in_pool_region(VoidPtr pool_ptr, VoidPtr pool, const SizeT &sz)
+{
+ Char *_pool_ptr = (Char *)pool_ptr;
+ Char *_pool = (Char *)pool;
+
+ for (SizeT index = sz; _pool[sz] != 0x55; --index)
{
- Char* _pool_ptr = (Char*)pool_ptr;
- Char* _pool = (Char*)pool;
+ if (&_pool[index] > &_pool_ptr[sz])
+ continue;
- for (SizeT index = sz; _pool[sz] != 0x55; --index)
- {
- if (&_pool[index] > &_pool_ptr[sz])
- continue;
+ if (_pool[index] == _pool_ptr[index])
+ return true;
+ }
- if (_pool[index] == _pool_ptr[index])
- return true;
- }
+ return false;
+}
+/* @brief free pointer from usage. */
+Boolean Process::Delete(VoidPtr ptr, const SizeT &sz)
+{
+ if (sz < 1 || this->PoolCursor == this->Pool)
return false;
- }
- /* @brief free pointer from usage. */
- Boolean Process::Delete(VoidPtr ptr, const SizeT& sz)
- {
- if (sz < 1 ||
- this->PoolCursor == this->Pool)
- return false;
+ // also check for the amount of allocations we've done so far.
+ if (this->UsedMemory < 1)
+ return false;
- if (rt_in_pool_region(ptr, this->PoolCursor, this->UsedMemory))
- {
- this->PoolCursor = (VoidPtr)((UIntPtr)this->PoolCursor - (sizeof(sz) - kPoolAlign));
- rt_zero_memory(ptr, sz);
+ if (rt_in_pool_region(ptr, this->PoolCursor, this->UsedMemory))
+ {
+ this->PoolCursor = (VoidPtr)((UIntPtr)this->PoolCursor - (sizeof(sz) - kPoolAlign));
+ rt_zero_memory(ptr, sz);
- return true;
- }
+ ++this->FreeMemory;
+ --this->UsedMemory;
- return false;
+ return true;
}
- const Char* Process::GetName() { return this->Name; }
+ return false;
+}
- const ProcessSelector& Process::GetSelector() { return this->Selector; }
+const Char *Process::GetName()
+{
+ return this->Name;
+}
- const ProcessStatus& Process::GetStatus() { return this->Status; }
+const ProcessSelector &Process::GetSelector()
+{
+ return this->Selector;
+}
- const AffinityKind& Process::GetAffinity() { return this->Affinity; }
+const ProcessStatus &Process::GetStatus()
+{
+ return this->Status;
+}
- void Process::Exit(Int32 exit_code)
+const AffinityKind &Process::GetAffinity()
+{
+ return this->Affinity;
+}
+
+void Process::Exit(Int32 exit_code)
+{
+ if (this->ProcessId != ProcessManager::Shared().Leak().GetCurrent().Leak().ProcessId)
+ return;
+
+ if (this->Ring == (Int32)ProcessSelector::kRingKernel &&
+ ProcessManager::Shared().Leak().GetCurrent().Leak().Ring > 0)
+ return;
+
+ kExitCode = exit_code;
+
+ if (this->Ring != (Int32)ProcessSelector::kRingDriver && this->Ring != (Int32)ProcessSelector::kRingKernel)
{
- if (this->ProcessId != ProcessManager::Shared().Leak().GetCurrent().Leak().ProcessId)
- return;
+ pool_free_ptr(this->Pool);
- if (this->Ring == (Int32)ProcessSelector::kRingKernel &&
- ProcessManager::Shared().Leak().GetCurrent().Leak().Ring > 0)
- return;
+ this->PoolCursor = nullptr;
- kExitCode = exit_code;
+ this->FreeMemory = kPoolMaxSz;
+ this->UsedMemory = 0UL;
+ }
- if (this->Ring != (Int32)ProcessSelector::kRingDriver &&
- this->Ring != (Int32)ProcessSelector::kRingKernel)
- {
- pool_free_ptr(this->Pool);
+ //! Delete image if not done already.
+ if (this->Image)
+ kernel_delete_ptr(this->Image);
- this->PoolCursor = nullptr;
+ if (this->StackFrame)
+ kernel_delete_ptr((VoidPtr)this->StackFrame);
- this->FreeMemory = kPoolMaxSz;
- this->UsedMemory = 0UL;
- }
+ ProcessManager::Shared().Leak().Remove(this->ProcessId);
+}
- //! Delete image if not done already.
- if (this->Image)
- kernel_delete_ptr(this->Image);
+bool ProcessManager::Add(Ref<Process> &process)
+{
+ if (!process)
+ return false;
- if (this->StackFrame)
- kernel_delete_ptr((VoidPtr)this->StackFrame);
+ kcout << "ProcessManager::Add(Ref<Process>& process)\r\n";
- ProcessManager::Shared().Leak().Remove(this->ProcessId);
- }
+ process.Leak().Pool = pool_new_ptr(kPoolUser | kPoolRw);
+ process.Leak().ProcessId = this->m_Headers.Count();
+ process.Leak().PoolCursor = process.Leak().Pool;
- bool ProcessManager::Add(Ref<Process>& process)
- {
- if (!process)
- return false;
+ process.Leak().StackFrame =
+ reinterpret_cast<HAL::StackFrame *>(kernel_new_ptr(sizeof(HAL::StackFrame), true, false));
+
+ MUST_PASS(process.Leak().StackFrame);
- kcout << "ProcessManager::Add(Ref<Process>& process)\r\n";
+ UIntPtr imageStart = reinterpret_cast<UIntPtr>(process.Leak().Image);
- process.Leak().Pool = pool_new_ptr(kPoolUser | kPoolRw);
- process.Leak().ProcessId = this->m_Headers.Count();
- process.Leak().PoolCursor = process.Leak().Pool;
+ process.Leak().AssignStart(imageStart);
- process.Leak().StackFrame = reinterpret_cast<HAL::StackFrame*>(
- kernel_new_ptr(sizeof(HAL::StackFrame), true, false)
- );
+ this->m_Headers.Add(process);
- MUST_PASS(process.Leak().StackFrame);
+ return true;
+}
- UIntPtr imageStart = reinterpret_cast<UIntPtr>(
- process.Leak().Image
- );
+bool ProcessManager::Remove(SizeT process)
+{
+ if (process > this->m_Headers.Count())
+ return false;
-#ifdef __x86_64__
- process.Leak().StackFrame->Rbp = imageStart;
-#elif defined(__powerpc)
- // link return register towards the __start symbol.
- process.Leak().StackFrame->R3 = imageStart;
-#endif
+ kcout << "ProcessManager::Remove(SizeT process)\r\n";
- this->m_Headers.Add(process);
+ return this->m_Headers.Remove(process);
+}
- return true;
- }
+SizeT ProcessManager::Run() noexcept
+{
+ SizeT processIndex = 0; //! we store this guy to tell the scheduler how many things we
+ //! have scheduled.
- bool ProcessManager::Remove(SizeT process)
+ for (; processIndex < this->m_Headers.Count(); ++processIndex)
{
- if (process > this->m_Headers.Count())
- return false;
+ auto process = this->m_Headers[processIndex];
+ MUST_PASS(
+ process); //! no need for a MUST_PASS(process.Leak());, it is recursive because of the nature of the class;
- kcout << "ProcessManager::Remove(SizeT process)\r\n";
+ //! run any process needed to be scheduled.
+ if (ProcessHelper::CanBeScheduled(process.Leak()))
+ {
+ auto unwrapped_process = *process.Leak();
- return this->m_Headers.Remove(process);
- }
+ unwrapped_process.PTime = 0;
- SizeT ProcessManager::Run() noexcept
- {
- SizeT processIndex = 0; //! we store this guy to tell the scheduler how many things we
- //! have scheduled.
+ // set the current process.
+ m_CurrentProcess = unwrapped_process;
- for (; processIndex < this->m_Headers.Count(); ++processIndex)
+ ProcessHelper::Switch(m_CurrentProcess.Leak().StackFrame, m_CurrentProcess.Leak().ProcessId);
+ }
+ else
{
- auto process = this->m_Headers[processIndex];
- MUST_PASS(process); //! no need for a MUST_PASS(process.Leak());, it is recursive because of the nature of the class;
-
- //! run any process needed to be scheduled.
- if (ProcessHelper::CanBeScheduled(process.Leak()))
- {
- auto unwrapped_process = *process.Leak();
-
- unwrapped_process.PTime = 0;
-
- // set the current process.
- m_CurrentProcess = unwrapped_process;
-
- ProcessHelper::Switch(m_CurrentProcess.Leak().StackFrame,
- m_CurrentProcess.Leak().ProcessId);
- }
- else
- {
- // otherwise increment the micro-time.
- ++m_CurrentProcess.Leak().PTime;
- }
+ // otherwise increment the micro-time.
+ ++m_CurrentProcess.Leak().PTime;
}
-
- return processIndex;
}
- Ref<ProcessManager> ProcessManager::Shared()
- {
- static ProcessManager ref;
- return { ref };
- }
+ return processIndex;
+}
- Ref<Process>& ProcessManager::GetCurrent()
- {
- return m_CurrentProcess;
- }
+Ref<ProcessManager> ProcessManager::Shared()
+{
+ static ProcessManager ref;
+ return {ref};
+}
- PID& ProcessHelper::GetCurrentPID()
- {
- kcout << "ProcessHelper::GetCurrentPID\r\n";
- return ProcessManager::Shared().Leak().GetCurrent().Leak().ProcessId;
- }
+Ref<Process> &ProcessManager::GetCurrent()
+{
+ return m_CurrentProcess;
+}
- bool ProcessHelper::CanBeScheduled(Ref<Process>& process)
- {
- if (process.Leak().Status == ProcessStatus::kFrozen ||
- process.Leak().Status == ProcessStatus::kDead)
- return false;
+PID &ProcessHelper::GetCurrentPID()
+{
+ kcout << "ProcessHelper::GetCurrentPID\r\n";
+ return ProcessManager::Shared().Leak().GetCurrent().Leak().ProcessId;
+}
- if (process.Leak().GetStatus() == ProcessStatus::kStarting)
- {
- if (process.Leak().PTime < static_cast<Int>(kMinMicroTime))
- {
- process.Leak().Status = ProcessStatus::kRunning;
- process.Leak().Affinity = AffinityKind::kStandard;
+bool ProcessHelper::CanBeScheduled(Ref<Process> &process)
+{
+ if (process.Leak().Status == ProcessStatus::kFrozen || process.Leak().Status == ProcessStatus::kDead)
+ return false;
- return true;
- }
+ if (process.Leak().GetStatus() == ProcessStatus::kStarting)
+ {
+ if (process.Leak().PTime < static_cast<Int>(kMinMicroTime))
+ {
+ process.Leak().Status = ProcessStatus::kRunning;
+ process.Leak().Affinity = AffinityKind::kStandard;
- ++process.Leak().PTime;
+ return true;
}
- return process.Leak().PTime > static_cast<Int>(kMinMicroTime);
+ ++process.Leak().PTime;
}
- bool ProcessHelper::StartScheduling()
+ return process.Leak().PTime > static_cast<Int>(kMinMicroTime);
+}
+
+bool ProcessHelper::StartScheduling()
+{
+ if (ProcessHelper::CanBeScheduled(ProcessManager::Shared().Leak().GetCurrent()))
{
- if (ProcessHelper::CanBeScheduled(ProcessManager::Shared().Leak().GetCurrent()))
- {
- --ProcessManager::Shared().Leak().GetCurrent().Leak().PTime;
- return false;
- }
+ --ProcessManager::Shared().Leak().GetCurrent().Leak().PTime;
+ return false;
+ }
- auto process_ref = ProcessManager::Shared().Leak();
+ auto process_ref = ProcessManager::Shared().Leak();
- if (!process_ref)
- return false; // we have nothing to schedule. simply return.
+ if (!process_ref)
+ return false; // we have nothing to schedule. simply return.
- SizeT ret = process_ref.Run();
+ SizeT ret = process_ref.Run();
- kcout << StringBuilder::FromInt("ProcessHelper::StartScheduling() iterated over: % processes\r\n", ret);
+ kcout << StringBuilder::FromInt("ProcessHelper::StartScheduling() iterated over: % processes\r\n", ret);
- return true;
- }
+ return true;
+}
- bool ProcessHelper::Switch(HAL::StackFrame* the_stack, const PID& new_pid)
- {
- if (!the_stack ||
- new_pid < 0)
- return false;
+bool ProcessHelper::Switch(HAL::StackFrame *the_stack, const PID &new_pid)
+{
+ if (!the_stack || new_pid < 0)
+ return false;
- for (SizeT index = 0UL; index < kMaxHarts; ++index)
+ for (SizeT index = 0UL; index < kMaxHarts; ++index)
+ {
+ if (SMPManager::Shared().Leak()[index].Leak().StackFrame() == the_stack)
{
- if (SMPManager::Shared().Leak()[index].Leak().StackFrame() == the_stack)
- {
- SMPManager::Shared().Leak()[index].Leak().Busy(false);
- continue;
- }
-
- if (SMPManager::Shared().Leak()[index].Leak().IsBusy())
- continue;
-
- if (SMPManager::Shared().Leak()[index].Leak().Kind() != ThreadKind::kBoot ||
- SMPManager::Shared().Leak()[index].Leak().Kind() != ThreadKind::kSystemReserved)
- {
- SMPManager::Shared().Leak()[index].Leak().Busy(true);
- ProcessHelper::GetCurrentPID() = new_pid;
-
- return SMPManager::Shared().Leak()[index].Leak().Switch(the_stack);
- }
+ SMPManager::Shared().Leak()[index].Leak().Busy(false);
+ continue;
}
- return false;
+ if (SMPManager::Shared().Leak()[index].Leak().IsBusy())
+ continue;
+
+ if (SMPManager::Shared().Leak()[index].Leak().Kind() != ThreadKind::kBoot ||
+ SMPManager::Shared().Leak()[index].Leak().Kind() != ThreadKind::kSystemReserved)
+ {
+ SMPManager::Shared().Leak()[index].Leak().Busy(true);
+ ProcessHelper::GetCurrentPID() = new_pid;
+
+ return SMPManager::Shared().Leak()[index].Leak().Switch(the_stack);
+ }
}
+
+ return false;
+}
} // namespace hCore