Browse Source

fix(signal): wakeup the threading on signals generated

greatbridf 1 year ago
parent
commit
fdb0052684

+ 9 - 9
include/kernel/process.hpp

@@ -53,7 +53,6 @@ struct process_attr {
 struct thread_attr {
     uint32_t system : 1;
     uint32_t ready : 1;
-    uint32_t wait : 1;
 };
 
 namespace kernel::tasks {
@@ -79,7 +78,7 @@ public:
 
     explicit inline thread(types::string<> name, pid_t owner)
         : owner { owner }
-        , attr { .system = 1, .ready = 1, .wait = 0, }
+        , attr { .system = 1, .ready = 1, }
         , name { name }
     {
         alloc_kstack();
@@ -91,6 +90,13 @@ public:
         alloc_kstack();
     }
 
+    constexpr void sleep()
+    { attr.ready = 0; }
+    constexpr void wakeup()
+    { attr.ready = 1; }
+    constexpr bool is_ready() const
+    { return attr.ready; }
+
     constexpr thread(thread&& val) = default;
     inline ~thread() { free_kstack(pkstack); }
 
@@ -343,12 +349,6 @@ public:
         return iter->second;
     }
 
-    constexpr bool has_child(pid_t pid)
-    {
-        auto& proc = find(pid);
-        return !proc.children.empty();
-    }
-
     constexpr void make_children_orphans(pid_t pid)
     {
         auto& children = find(pid).children;
@@ -407,7 +407,7 @@ public:
     constexpr thread* pop(void)
     {
         m_thds.remove_if([](thread* item) {
-            return !item->attr.ready;
+            return !item->is_ready();
         });
         auto* retval = m_thds.front();
         m_thds.pop_front();

+ 3 - 6
src/kernel/event/event.cpp

@@ -49,8 +49,7 @@ bool kernel::cond_var::wait(types::mutex& lock)
 {
     kernel::tasks::thread* thd = current_thread;
 
-    current_thread->attr.ready = 0;
-    current_thread->attr.wait = 1;
+    current_thread->sleep();
     m_subscribers.push_back(thd);
 
     lock.unlock();
@@ -69,8 +68,7 @@ void kernel::cond_var::notify(void)
         return;
 
     auto* thd = *iter;
-    thd->attr.ready = 1;
-    thd->attr.wait = 0;
+    thd->wakeup();
     readythds->push(thd);
 
     m_subscribers.erase(iter);
@@ -81,8 +79,7 @@ void kernel::cond_var::notify_all(void)
     types::lock_guard lck(m_mtx);
 
     for (auto& thd : m_subscribers) {
-        thd->attr.ready = 1;
-        thd->attr.wait = 0;
+        thd->wakeup();
         readythds->push(thd);
     }
 

+ 11 - 9
src/kernel/interrupt.cpp

@@ -165,14 +165,15 @@ extern "C" void int6_handler(
     uint16_t cs,
     uint32_t eflags)
 {
-    char buf[128] = {};
+    if (!current_process->attr.system)
+        kill_current(SIGSEGV);
+
+    char buf[128];
     snprintf(buf, sizeof(buf),
         "[kernel] int6 data: cs: %x, eflags: %x\n", cs, eflags);
     kmsg(buf);
-    if (!current_process->attr.system)
-        kill_current(SIGSEGV);
-    else
-        die(s_regs, eip);
+
+    die(s_regs, eip);
 }
 
 // general protection
@@ -183,15 +184,16 @@ extern "C" void int13_handler(
     uint16_t cs,
     uint32_t eflags)
 {
+    if (!current_process->attr.system)
+        kill_current(SIGILL);
+
     char buf[128] = {};
     snprintf(buf, sizeof(buf),
         "[kernel] int13 data: error_code: %x, cs: %x, eflags: %x\n",
         error_code, cs, eflags);
     kmsg(buf);
-    if (!current_process->attr.system)
-        kill_current(SIGILL);
-    else
-        die(s_regs, eip);
+
+    die(s_regs, eip);
 }
 
 struct PACKED int14_data {

+ 6 - 6
src/kernel/process.cpp

@@ -170,6 +170,8 @@ void process::send_signal(kernel::signal_list::signo_type signal)
         if (thd.signals.is_masked(signal))
             continue;
         thd.signals.set(signal);
+        thd.wakeup();
+        readythds->push(&thd);
         break;
     }
 }
@@ -178,11 +180,9 @@ void proclist::kill(pid_t pid, int exit_code)
 {
     auto& proc = this->find(pid);
 
-    // remove threads from ready list
-    for (auto& thd : proc.thds) {
-        thd.attr.ready = 0;
-        readythds->remove_all(&thd);
-    }
+    // put all threads into sleep
+    for (auto& thd : proc.thds)
+        thd.sleep();
 
     // if current process is connected to a tty
     // clear its read buffer
@@ -200,7 +200,7 @@ void proclist::kill(pid_t pid, int exit_code)
     // init should never exit
     if (proc.ppid == 0) {
         console->print("kernel panic: init exited!\n");
-        assert(false);
+        freeze();
     }
 
     // make child processes orphans (children of init)

+ 1 - 3
src/kernel/signal.cpp

@@ -10,9 +10,7 @@ static void continue_process(int) { }
 
 static void stop_process(int)
 {
-    current_thread->attr.ready = 0;
-    current_thread->attr.wait = 1;
-    readythds->remove_all(current_thread);
+    current_thread->sleep();
 
     schedule();
 }

+ 10 - 5
src/kernel/syscall.cpp

@@ -121,8 +121,7 @@ int _syscall_read(interrupt_stack* data)
 // TODO: sleep seconds
 int _syscall_sleep(interrupt_stack*)
 {
-    current_thread->attr.ready = 0;
-    current_thread->attr.wait = 1;
+    current_thread->sleep();
 
     schedule();
     return 0;
@@ -217,11 +216,14 @@ int _syscall_waitpid(interrupt_stack* data)
     auto& waitlist = current_process->waitlist;
 
     while (waitlist.empty()) {
-        if (!procs->has_child(current_process->pid))
+        if (current_process->children.empty())
             return -ECHILD;
 
-        if (!cv.wait(mtx))
-            return -EINTR;
+        cv.wait(mtx);
+
+        // TODO: check WNOHANG
+        // if (!cv.wait(mtx))
+        //     return -EINTR;
     }
 
     auto iter = waitlist.begin();
@@ -740,6 +742,9 @@ int _syscall_kill(interrupt_stack* data)
     if (!kernel::signal_list::check_valid(sig))
         return -EINVAL;
 
+    if (procs->find(pid).is_system())
+        return 0;
+
     // TODO: check permission
     procs->send_signal(pid, sig);
 

+ 4 - 1
src/types/elf.cpp

@@ -134,7 +134,10 @@ int types::elf::elf32_load(types::elf::elf32_load_data* d)
     // map stack area
     auto ret = mmap((void*)types::elf::ELF_STACK_TOP,
         types::elf::ELF_STACK_SIZE, nullptr, 0, true, false);
-    assert(ret == GB_OK);
+
+    // TODO: destruct local variables before calling kill_current
+    if (ret != GB_OK)
+        kill_current(SIGSEGV);
 
     d->eip = (void*)hdr.entry;
     d->sp = reinterpret_cast<uint32_t*>(types::elf::ELF_STACK_BOTTOM);