Преглед изворни кода

feat(proc): add class proclist

greatbridf пре 2 година
родитељ
комит
0d8e0a0ef4
3 измењених фајлова са 90 додато и 71 уклоњено
  1. 79 11
      include/kernel/process.hpp
  2. 3 43
      src/kernel/process.cpp
  3. 8 17
      src/kernel/syscall.cpp

+ 79 - 11
include/kernel/process.hpp

@@ -4,6 +4,7 @@
 #include <kernel/interrupt.h>
 #include <kernel/mm.hpp>
 #include <kernel/task.h>
+#include <types/cplusplus.hpp>
 #include <types/hash_map.hpp>
 #include <types/list.hpp>
 #include <types/stdint.h>
@@ -107,23 +108,85 @@ private:
     }
 };
 
-constexpr uint32_t push_stack(uint32_t** stack, uint32_t val)
-{
-    --*stack;
-    **stack = val;
-    return val;
-}
+class proclist {
+public:
+    using list_type = types::list<process>;
+    using index_type = types::hash_map<pid_t, types::list<process>::iterator_type, types::linux_hasher<pid_t>>;
+    using child_index_type = types::hash_map<pid_t, types::list<pid_t>, types::linux_hasher<pid_t>>;
+    using iterator_type = list_type::iterator_type;
+    using const_iterator_type = list_type::const_iterator_type;
+
+private:
+    list_type m_procs;
+    index_type m_idx;
+    child_index_type m_child_idx;
+
+public:
+    template <typename... Args>
+    constexpr iterator_type emplace(Args&&... args)
+    {
+        auto iter = m_procs.emplace_back(types::forward<Args>(args)...);
+        m_idx.insert(iter->pid, iter);
+
+        auto children = m_child_idx.find(iter->ppid);
+        if (!children) {
+            m_child_idx.insert(iter->ppid, {});
+            children = m_child_idx.find(iter->ppid);
+        }
+
+        children->value.push_back(iter->pid);
+
+        return iter;
+    }
+
+    constexpr void remove(pid_t pid)
+    {
+        make_children_orphans(pid);
+
+        auto proc_iter = m_idx.find(pid);
+        auto ppid = proc_iter->value->ppid;
+
+        auto& parent_children = m_child_idx.find(ppid)->value;
+
+        auto i = parent_children.find(pid);
+        parent_children.erase(i);
+
+        m_procs.erase(proc_iter->value);
+        m_idx.remove(proc_iter);
+    }
+
+    constexpr process* find(pid_t pid)
+    {
+        return m_idx.find(pid)->value.ptr();
+    }
+
+    constexpr bool has_child(pid_t pid)
+    {
+        auto children = m_child_idx.find(pid);
+        return children && !children->value.empty();
+    }
+
+    constexpr void make_children_orphans(pid_t pid)
+    {
+        auto children = m_child_idx.find(pid);
+        if (children) {
+            auto init_children = m_child_idx.find(1);
+            for (auto iter = children->value.begin(); iter != children->value.end(); ++iter) {
+                init_children->value.push_back(*iter);
+                this->find(*iter)->ppid = 1;
+            }
+            m_child_idx.remove(children);
+        }
+    }
+};
 
 inline process* volatile current_process;
 inline thread* volatile current_thread;
-inline typename types::hash_map<pid_t, types::list<pid_t>, types::linux_hasher<pid_t>>* idx_child_processes;
+inline proclist* procs;
 
 extern "C" void NORETURN init_scheduler();
 void schedule(void);
 
-pid_t add_to_process_list(process&& proc);
-void remove_from_process_list(pid_t pid);
-
 void add_to_ready_list(thread* thd);
 void remove_from_ready_list(thread* thd);
 types::list<thread*>::iterator_type query_next_thread(void);
@@ -137,6 +200,11 @@ inline void next_task(types::list<thread*>::iterator_type target)
         add_to_ready_list(ptr);
 }
 
-process* findproc(pid_t pid);
+constexpr uint32_t push_stack(uint32_t** stack, uint32_t val)
+{
+    --*stack;
+    **stack = val;
+    return val;
+}
 
 void k_new_thread(void (*func)(void*), void* data);

+ 3 - 43
src/kernel/process.cpp

@@ -22,8 +22,6 @@
 #include <types/types.h>
 
 static bool is_scheduler_ready;
-static types::list<process>* processes;
-static typename types::hash_map<pid_t, types::list<process>::iterator_type, types::linux_hasher<pid_t>>* idx_processes;
 static types::list<thread*>* ready_thds;
 static void (*volatile kthreadd_new_thd_func)(void*);
 static void* volatile kthreadd_new_thd_data;
@@ -174,7 +172,7 @@ void NORETURN _kernel_init(void)
     {
         kernel::no_irq_guard grd;
 
-        add_to_process_list(process { kernel_threadd_main, 1 });
+        procs->emplace(kernel_threadd_main, 1);
     }
     hw::init_ata();
 
@@ -229,13 +227,10 @@ void k_new_thread(void (*func)(void*), void* data)
 
 void NORETURN init_scheduler()
 {
-    processes = types::kernel_allocator_pnew(processes);
+    procs = types::kernel_allocator_pnew(procs);
     ready_thds = types::kernel_allocator_pnew(ready_thds);
-    idx_processes = types::kernel_allocator_pnew(idx_processes);
-    idx_child_processes = types::kernel_allocator_pnew(idx_child_processes);
 
-    auto pid = add_to_process_list(process {});
-    auto init = findproc(pid);
+    auto* init = procs->emplace().ptr();
 
     // we need interrupts enabled for cow mapping so now we disable it
     // in case timer interrupt mess things up
@@ -280,36 +275,6 @@ void NORETURN init_scheduler()
         assert(false);
 }
 
-pid_t add_to_process_list(process&& proc)
-{
-    auto iter = processes->emplace_back(types::move(proc));
-    idx_processes->insert(iter->pid, iter);
-
-    auto children = idx_child_processes->find(iter->ppid);
-    if (!children) {
-        idx_child_processes->insert(iter->ppid, {});
-        children = idx_child_processes->find(iter->ppid);
-    }
-
-    children->value.push_back(iter->pid);
-
-    return iter->pid;
-}
-
-void remove_from_process_list(pid_t pid)
-{
-    auto proc_iter = idx_processes->find(pid);
-    auto ppid = proc_iter->value->ppid;
-
-    auto& parent_children = idx_child_processes->find(ppid)->value;
-
-    auto i = parent_children.find(pid);
-    parent_children.erase(i);
-
-    processes->erase(proc_iter->value);
-    idx_processes->remove(proc_iter);
-}
-
 void add_to_ready_list(thread* thd)
 {
     ready_thds->push_back(thd);
@@ -332,11 +297,6 @@ types::list<thread*>::iterator_type query_next_thread(void)
     return iter_thd;
 }
 
-process* findproc(pid_t pid)
-{
-    return idx_processes->find(pid)->value.ptr();
-}
-
 extern "C" void asm_ctx_switch(uint32_t** curr_esp, uint32_t* next_esp);
 void schedule()
 {

+ 8 - 17
src/kernel/syscall.cpp

@@ -34,8 +34,7 @@ void _syscall_not_impl(interrupt_stack* data)
 extern "C" void _syscall_stub_fork_return(void);
 void _syscall_fork(interrupt_stack* data)
 {
-    auto newpid = add_to_process_list(process { *current_process, *current_thread });
-    auto* newproc = findproc(newpid);
+    auto* newproc = procs->emplace(*current_process, *current_thread).ptr();
     thread* newthd = newproc->thds.begin().ptr();
     add_to_ready_list(newthd);
 
@@ -71,7 +70,7 @@ void _syscall_fork(interrupt_stack* data)
     // eflags
     push_stack(&newthd->esp, 0);
 
-    SYSCALL_SET_RETURN_VAL(newpid, 0);
+    SYSCALL_SET_RETURN_VAL(newproc->pid, 0);
 }
 
 void _syscall_write(interrupt_stack* data)
@@ -143,22 +142,14 @@ void _syscall_exit(interrupt_stack* data)
     current_process->mms.clear_user();
 
     // make child processes orphans (children of init)
-    auto children = idx_child_processes->find(pid);
-    if (children) {
-        auto init_children = idx_child_processes->find(1);
-        for (auto iter = children->value.begin(); iter != children->value.end(); ++iter) {
-            init_children->value.push_back(*iter);
-            findproc(*iter)->ppid = 1;
-        }
-        idx_child_processes->remove(children);
-    }
+    procs->make_children_orphans(pid);
 
     current_process->attr.zombie = 1;
 
     // notify parent process and init
-    auto* proc = findproc(pid);
-    auto* parent = findproc(ppid);
-    auto* init = findproc(1);
+    auto* proc = procs->find(pid);
+    auto* parent = procs->find(ppid);
+    auto* init = procs->find(1);
     while (!proc->wait_lst.empty()) {
         init->wait_lst.push(proc->wait_lst.front());
     }
@@ -183,7 +174,7 @@ void _syscall_wait(interrupt_stack* data)
     }
 
     auto& waitlst = current_process->wait_lst;
-    if (waitlst.empty() && !idx_child_processes->find(current_process->pid)) {
+    if (waitlst.empty() && !procs->has_child(current_process->pid)) {
         SYSCALL_SET_RETURN_VAL(-1, ECHILD);
         return;
     }
@@ -207,7 +198,7 @@ void _syscall_wait(interrupt_stack* data)
     // TODO: copy_to_user check privilege
     *arg1 = (int)evt.data2;
 
-    remove_from_process_list(pid);
+    procs->remove(pid);
     SYSCALL_SET_RETURN_VAL(pid, 0);
 }