Browse Source

feat(syscall): impl. sleep

greatbridf 2 years ago
parent
commit
d50e70efaa
3 changed files with 39 additions and 15 deletions
  1. 13 0
      include/kernel/process.hpp
  2. 22 14
      src/kernel/process.cpp
  3. 4 1
      src/kernel/syscall.cpp

+ 13 - 0
include/kernel/process.hpp

@@ -15,12 +15,19 @@ struct process_attr {
     uint16_t system : 1;
 };
 
+struct thread_attr {
+    uint32_t system : 1;
+    uint32_t ready : 1;
+    uint32_t wait : 1;
+};
+
 struct thread {
     void* eip;
     process* owner;
     regs_32 regs;
     uint32_t eflags;
     uint32_t esp;
+    thread_attr attr;
 };
 
 class process {
@@ -38,10 +45,16 @@ public:
 
 // in process.cpp
 extern process* current_process;
+extern thread* current_thread;
 
 extern "C" void NORETURN init_scheduler();
 void do_scheduling(interrupt_stack* intrpt_data);
 
+void thread_context_save(interrupt_stack* int_stack, thread* thd, bool kernel);
+void thread_context_load(interrupt_stack* int_stack, thread* thd, bool kernel);
+void process_context_save(interrupt_stack*, process*);
+void process_context_load(interrupt_stack*, process* proc);
+
 #else
 
 void NORETURN init_scheduler();

+ 22 - 14
src/kernel/process.cpp

@@ -3,6 +3,7 @@
 #include <kernel/mm.hpp>
 #include <kernel/process.hpp>
 #include <kernel/stdio.h>
+#include <kernel/tty.h>
 #include <kernel_main.h>
 #include <types/types.h>
 #include <hello-world.res>
@@ -61,6 +62,11 @@ process::process(void* start_eip, uint8_t* image, size_t image_size, bool system
         .eflags {},
         // TODO: change this
         .esp = 0x40100000U,
+        .attr {
+            .system = system,
+            .ready = 1,
+            .wait = 0,
+        },
     });
     ready_thds->push_back(thd.ptr());
 
@@ -149,16 +155,19 @@ void do_scheduling(interrupt_stack* intrpt_data)
     if (!is_scheduler_ready)
         return;
 
-    thread* thd = *ready_thds->begin();
-    if (current_thread == thd) {
-        ready_thds->erase(ready_thds->begin());
-        // check if the thread is ready
-        ready_thds->push_back(thd);
-        return;
-    }
+    auto iter_thd = ready_thds->begin();
+    while (!((*iter_thd)->attr.ready))
+        iter_thd = ready_thds->erase(iter_thd);
+    auto thd = *iter_thd;
+
+    process* proc = nullptr;
+    bool kernel = false;
 
-    process* proc = thd->owner;
-    bool kernel = proc->attr.system;
+    if (current_thread == thd)
+        goto next_task;
+
+    proc = thd->owner;
+    kernel = proc->attr.system;
     if (current_process != proc) {
         process_context_save(intrpt_data, current_process);
         process_context_load(intrpt_data, proc);
@@ -167,9 +176,8 @@ void do_scheduling(interrupt_stack* intrpt_data)
     thread_context_save(intrpt_data, current_thread, kernel);
     thread_context_load(intrpt_data, thd, kernel);
 
-    ready_thds->erase(ready_thds->begin());
-    // check if the thread is ready
-    ready_thds->push_back(thd);
-
-    current_thread = thd;
+next_task:
+    ready_thds->erase(iter_thd);
+    if (thd->attr.ready)
+        ready_thds->push_back(thd);
 }

+ 4 - 1
src/kernel/syscall.cpp

@@ -1,5 +1,6 @@
 #include <asm/port_io.h>
 #include <kernel/syscall.hpp>
+#include <kernel/process.hpp>
 #include <kernel/tty.h>
 
 syscall_handler syscall_handlers[8];
@@ -25,7 +26,9 @@ void _syscall_write(interrupt_stack* data)
 
 void _syscall_sleep(interrupt_stack* data)
 {
-    ++data->s_regs.ecx;
+    current_thread->attr.ready = 0;
+    current_thread->attr.wait = 1;
+    do_scheduling(data);
 }
 
 void init_syscall(void)