Эх сурвалжийг харах

feat(process): add class readyqueue

greatbridf 2 жил өмнө
parent
commit
b120b34b82

+ 55 - 15
include/kernel/process.hpp

@@ -94,7 +94,7 @@ public:
     process(const process& proc, const thread& main_thread);
 
     // only used for system initialization
-    explicit process(void);
+    explicit process(pid_t ppid);
     explicit process(void (*func_in_kernel_space)(void), pid_t ppid);
 
     ~process();
@@ -108,7 +108,7 @@ private:
     }
 };
 
-class proclist {
+class proclist final {
 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>>;
@@ -180,26 +180,66 @@ public:
     }
 };
 
+class readyqueue final {
+public:
+    using list_type = types::list<thread*>;
+    using iterator_type = list_type::iterator_type;
+    using const_iterator_type = list_type::const_iterator_type;
+
+private:
+    list_type m_thds;
+
+private:
+    readyqueue(const readyqueue&) = delete;
+    readyqueue(readyqueue&&) = delete;
+    readyqueue& operator=(const readyqueue&) = delete;
+    readyqueue& operator=(readyqueue&&) = delete;
+
+    ~readyqueue() = delete;
+
+public:
+    constexpr explicit readyqueue(void) = default;
+
+    constexpr void push(thread* thd)
+    {
+        m_thds.push_back(thd);
+    }
+
+    constexpr thread* pop(void)
+    {
+        auto iter = m_thds.begin();
+        while (!((*iter)->attr.ready))
+            iter = m_thds.erase(iter);
+        auto* ptr = *iter;
+        m_thds.erase(iter);
+        return ptr;
+    }
+
+    constexpr thread* query(void)
+    {
+        auto* thd = this->pop();
+        this->push(thd);
+        return thd;
+    }
+
+    constexpr void remove_all(thread* thd)
+    {
+        auto iter = m_thds.find(thd);
+        while (iter != m_thds.end()) {
+            m_thds.erase(iter);
+            iter = m_thds.find(thd);
+        }
+    }
+};
+
 inline process* volatile current_process;
 inline thread* volatile current_thread;
 inline proclist* procs;
+inline readyqueue* readythds;
 
 extern "C" void NORETURN init_scheduler();
 void schedule(void);
 
-void add_to_ready_list(thread* thd);
-void remove_from_ready_list(thread* thd);
-types::list<thread*>::iterator_type query_next_thread(void);
-
-// the function call INVALIDATES iterator
-inline void next_task(types::list<thread*>::iterator_type target)
-{
-    auto* ptr = *target;
-    remove_from_ready_list(ptr);
-    if (ptr->attr.ready)
-        add_to_ready_list(ptr);
-}
-
 constexpr uint32_t push_stack(uint32_t** stack, uint32_t val)
 {
     --*stack;

+ 1 - 1
src/kernel/event/event.cpp

@@ -85,7 +85,7 @@ void kernel::evtqueue::notify(void)
     for (auto* sub : m_subscribers) {
         sub->attr.ready = 1;
         sub->attr.wait = 0;
-        add_to_ready_list(sub);
+        readythds->push(sub);
     }
 }
 

+ 14 - 47
src/kernel/process.cpp

@@ -21,7 +21,6 @@
 #include <types/stdint.h>
 #include <types/types.h>
 
-static types::list<thread*>* ready_thds;
 static void (*volatile kthreadd_new_thd_func)(void*);
 static void* volatile kthreadd_new_thd_data;
 static types::mutex kthreadd_mtx;
@@ -69,8 +68,8 @@ process::process(const process& val, const thread& main_thd)
     , pid { process::alloc_pid() }
     , ppid { val.pid }
 {
-    auto iter_thd = thds.emplace_back(main_thd);
-    iter_thd->owner = this;
+    auto* thd = thds.emplace_back(main_thd).ptr();
+    thd->owner = this;
 
     for (auto& area : val.mms) {
         if (area.is_ident())
@@ -78,30 +77,24 @@ process::process(const process& val, const thread& main_thd)
 
         mms.mirror_area(area);
     }
+
+    readythds->push(thd);
 }
 
-process::process(void)
+process::process(pid_t _ppid)
     : mms(*kernel_mms)
     , attr { .system = 1 }
     , pid { process::alloc_pid() }
-    , ppid { 1 }
+    , ppid { _ppid }
 {
     auto thd = thds.emplace_back(this, true);
-
-    add_to_ready_list(thd.ptr());
+    readythds->push(thd.ptr());
 }
 
 process::process(void (*func)(void), pid_t _ppid)
-    : mms(*kernel_mms)
-    , attr { .system = 1 }
-    , pid { process::alloc_pid() }
-    , ppid { _ppid }
+    : process { _ppid }
 {
-    auto thd = thds.emplace_back(this, true);
-
-    add_to_ready_list(thd.ptr());
-
-    auto* esp = &thd->esp;
+    auto* esp = &thds.begin().ptr()->esp;
 
     // return(start) address
     push_stack(esp, (uint32_t)func);
@@ -120,7 +113,7 @@ process::process(void (*func)(void), pid_t _ppid)
 process::~process()
 {
     for (auto iter = thds.begin(); iter != thds.end(); ++iter)
-        remove_from_ready_list(iter.ptr());
+        readythds->remove_all(iter.ptr());
 }
 
 inline void NORETURN _noreturn_crash(void)
@@ -222,9 +215,9 @@ void k_new_thread(void (*func)(void*), void* data)
 void NORETURN init_scheduler()
 {
     procs = types::kernel_allocator_pnew(procs);
-    ready_thds = types::kernel_allocator_pnew(ready_thds);
+    readythds = types::kernel_ident_allocator_pnew(readythds);
 
-    auto* init = procs->emplace().ptr();
+    auto* init = procs->emplace(1).ptr();
 
     // we need interrupts enabled for cow mapping so now we disable it
     // in case timer interrupt mess things up
@@ -267,38 +260,13 @@ void NORETURN init_scheduler()
     _noreturn_crash();
 }
 
-void add_to_ready_list(thread* thd)
-{
-    ready_thds->push_back(thd);
-}
-
-void remove_from_ready_list(thread* thd)
-{
-    auto iter = ready_thds->find(thd);
-    while (iter != ready_thds->end()) {
-        ready_thds->erase(iter);
-        iter = ready_thds->find(thd);
-    }
-}
-
-types::list<thread*>::iterator_type query_next_thread(void)
-{
-    auto iter_thd = ready_thds->begin();
-    while (!((*iter_thd)->attr.ready))
-        iter_thd = ready_thds->erase(iter_thd);
-    return iter_thd;
-}
-
 extern "C" void asm_ctx_switch(uint32_t** curr_esp, uint32_t* next_esp);
 void schedule()
 {
-    auto iter_thd = query_next_thread();
-    auto thd = *iter_thd;
+    auto thd = readythds->query();
 
-    if (current_thread == thd) {
-        next_task(iter_thd);
+    if (current_thread == thd)
         return;
-    }
 
     process* proc = thd->owner;
     if (current_process != proc) {
@@ -310,7 +278,6 @@ void schedule()
 
     current_thread = thd;
     tss.esp0 = current_thread->kstack;
-    next_task(iter_thd);
 
     asm_ctx_switch(&curr_thd->esp, thd->esp);
 }

+ 1 - 2
src/kernel/syscall.cpp

@@ -36,7 +36,6 @@ void _syscall_fork(interrupt_stack* data)
 {
     auto* newproc = procs->emplace(*current_process, *current_thread).ptr();
     thread* newthd = newproc->thds.begin().ptr();
-    add_to_ready_list(newthd);
 
     // create fake interrupt stack
     push_stack(&newthd->esp, data->ss);
@@ -134,7 +133,7 @@ void _syscall_exit(interrupt_stack* data)
 
     // remove this thread from ready list
     current_thread->attr.ready = 0;
-    remove_from_ready_list(current_thread);
+    readythds->remove_all(current_thread);
 
     // TODO: write back mmap'ped files and close them