feat: The waitpid family!
authorMinep <zelong56@gmail.com>
Sat, 11 Jun 2022 17:12:37 +0000 (18:12 +0100)
committerMinep <zelong56@gmail.com>
Sat, 11 Jun 2022 17:12:37 +0000 (18:12 +0100)
feat: Ability to switch data segment
fix: Mitigated some race conditions
feat: Better way for process to yield current time slice.

16 files changed:
lunaix-os/includes/arch/x86/interrupts.h
lunaix-os/includes/hal/cpu.h
lunaix-os/includes/lunaix/lunistd.h
lunaix-os/includes/lunaix/proc.h
lunaix-os/includes/lunaix/sched.h
lunaix-os/includes/lunaix/syscall.h
lunaix-os/includes/lunaix/timer.h
lunaix-os/includes/lunaix/types.h
lunaix-os/kernel/asm/x86/interrupt.S
lunaix-os/kernel/asm/x86/interrupts.c
lunaix-os/kernel/asm/x86/syscall.S
lunaix-os/kernel/k_init.c
lunaix-os/kernel/lxinit.c
lunaix-os/kernel/proc0.c
lunaix-os/kernel/sched.c
lunaix-os/kernel/time/timer.c

index 9d3d0857ddff155ad290d2ed095f071b9dacfaff..88138b604cef639e898804919069017a281f8c9e 100644 (file)
@@ -5,8 +5,24 @@
 
 #ifndef __ASM__
 #include <hal/cpu.h>
 
 #ifndef __ASM__
 #include <hal/cpu.h>
-typedef struct {
-    gp_regs registers;
+typedef struct
+{
+    struct
+    {
+        reg32 eax;
+        reg32 ebx;
+        reg32 ecx;
+        reg32 edx;
+        reg32 edi;
+        reg32 ebp;
+        reg32 esi;
+        reg32 ds;
+        reg32 es;
+        reg32 fs;
+        reg32 gs;
+        reg32 esp;
+    } registers;
+
     unsigned int vector;
     unsigned int err_code;
     unsigned int eip;
     unsigned int vector;
     unsigned int err_code;
     unsigned int eip;
@@ -66,8 +82,7 @@ intr_subscribe(const uint8_t vector, int_subscriber);
 void
 intr_unsubscribe(const uint8_t vector, int_subscriber);
 
 void
 intr_unsubscribe(const uint8_t vector, int_subscriber);
 
-void
-intr_set_fallback_handler(int_subscriber);
+void intr_set_fallback_handler(int_subscriber);
 
 void
 intr_handler(isr_param* param);
 
 void
 intr_handler(isr_param* param);
index b155d4b57496e67a93b99e6ddd7a58432b599789..fe633d090fa7f3c7a189d590e9c8655c691ba752 100644 (file)
@@ -20,12 +20,10 @@ typedef struct
 
 typedef struct
 {
 
 typedef struct
 {
-    reg16 ss;
-    reg16 es;
     reg16 ds;
     reg16 ds;
+    reg16 es;
     reg16 fs;
     reg16 gs;
     reg16 fs;
     reg16 gs;
-    reg16 cs;
 } __attribute__((packed)) sg_reg;
 
 void
 } __attribute__((packed)) sg_reg;
 
 void
@@ -40,7 +38,7 @@ static inline reg32
 cpu_rcr0()
 {
     uintptr_t val;
 cpu_rcr0()
 {
     uintptr_t val;
-    asm volatile("movl %%cr0,%0" : "=r" (val));
+    asm volatile("movl %%cr0,%0" : "=r"(val));
     return val;
 }
 
     return val;
 }
 
@@ -48,7 +46,7 @@ static inline reg32
 cpu_rcr2()
 {
     uintptr_t val;
 cpu_rcr2()
 {
     uintptr_t val;
-    asm volatile("movl %%cr2,%0" : "=r" (val));
+    asm volatile("movl %%cr2,%0" : "=r"(val));
     return val;
 }
 
     return val;
 }
 
@@ -56,7 +54,7 @@ static inline reg32
 cpu_rcr3()
 {
     uintptr_t val;
 cpu_rcr3()
 {
     uintptr_t val;
-    asm volatile("movl %%cr3,%0" : "=r" (val));
+    asm volatile("movl %%cr3,%0" : "=r"(val));
     return val;
 }
 
     return val;
 }
 
@@ -64,10 +62,9 @@ static inline reg32
 cpu_reflags()
 {
     uintptr_t val;
 cpu_reflags()
 {
     uintptr_t val;
-    asm volatile(
-        "pushf\n"
-        "popl %0\n"
-        :"=r"(val)::);
+    asm volatile("pushf\n"
+                 "popl %0\n"
+                 : "=r"(val)::);
     return val;
 }
 #pragma GCC diagnostic pop
     return val;
 }
 #pragma GCC diagnostic pop
index fc1a535cd02751916600a0792e10446a03de01da..42c432018dda74d4437ec810ab4717f2b6b3bf86 100644 (file)
@@ -18,6 +18,4 @@ __LXSYSCALL1(void, _exit, int, status)
 
 __LXSYSCALL1(unsigned int, sleep, unsigned int, seconds)
 
 
 __LXSYSCALL1(unsigned int, sleep, unsigned int, seconds)
 
-__LXSYSCALL1(pid_t, wait, int*, status);
-
 #endif /* __LUNAIX_UNISTD_H */
 #endif /* __LUNAIX_UNISTD_H */
index cec56704f6b6e531dcf435d455e671b2944d58d1..a6f44700aa67ab7b59d8b6500a92beabfb0bb2af 100644 (file)
@@ -2,7 +2,11 @@
 #define __LUNAIX_SYS_H
 
 #include <lunaix/syscall.h>
 #define __LUNAIX_SYS_H
 
 #include <lunaix/syscall.h>
+#include <lunaix/types.h>
 
 
-__LXSYSCALL(void, yield)
+__LXSYSCALL(void, yield);
+
+__LXSYSCALL1(pid_t, wait, int*, status);
+__LXSYSCALL3(pid_t, waitpid, pid_t, pid, int*, status, int, options);
 
 #endif /* __LUNAIX_SYS_H */
 
 #endif /* __LUNAIX_SYS_H */
index b20a33a709699012553ade72dcda317065ca467c..69019f3a7a3c92cc796fd6e79010a4c98415f613 100644 (file)
@@ -3,13 +3,20 @@
 
 #define SCHED_TIME_SLICE 300
 
 
 #define SCHED_TIME_SLICE 300
 
-struct scheduler {
+struct scheduler
+{
     struct proc_info* _procs;
     int procs_index;
     unsigned int ptable_len;
 };
 
     struct proc_info* _procs;
     int procs_index;
     unsigned int ptable_len;
 };
 
-void sched_init();
-void schedule();
+void
+sched_init();
+
+void
+schedule();
+
+void
+sched_yield();
 
 #endif /* __LUNAIX_SCHEDULER_H */
 
 #endif /* __LUNAIX_SCHEDULER_H */
index dc61f64fc0e656f4aa942127d24e0243578f877f..c19d5016ae01e26494734a55cf7ffb5017ea7f58 100644 (file)
@@ -12,6 +12,7 @@
 #define __SYSCALL_sleep 7
 #define __SYSCALL__exit 8
 #define __SYSCALL_wait 9
 #define __SYSCALL_sleep 7
 #define __SYSCALL__exit 8
 #define __SYSCALL_wait 9
+#define __SYSCALL_waitpid 10
 
 #define __SYSCALL_MAX 0x100
 
 
 #define __SYSCALL_MAX 0x100
 
@@ -48,7 +49,7 @@ syscall(unsigned int callcode)
     asmlinkage rettype __lxsys_##name(__PARAM_MAP2(t1, p1, t2, p2))
 
 #define __DEFINE_LXSYSCALL3(rettype, name, t1, p1, t2, p2, t3, p3)             \
     asmlinkage rettype __lxsys_##name(__PARAM_MAP2(t1, p1, t2, p2))
 
 #define __DEFINE_LXSYSCALL3(rettype, name, t1, p1, t2, p2, t3, p3)             \
-    asmlinkage rettype __lxsys_##name(__PARAM_MAP3(t1, p1, t2, p2, t3, p3));
+    asmlinkage rettype __lxsys_##name(__PARAM_MAP3(t1, p1, t2, p2, t3, p3))
 
 #define __DEFINE_LXSYSCALL4(rettype, name, t1, p1, t2, p2, t3, p3, t4, p4)     \
     asmlinkage rettype __lxsys_##nam(                                          \
 
 #define __DEFINE_LXSYSCALL4(rettype, name, t1, p1, t2, p2, t3, p3, t4, p4)     \
     asmlinkage rettype __lxsys_##nam(                                          \
index 567b8d24d70e72462ad1ee941c20c1c26e2ed25e..c02d7f6bb49a55b003a8c38a3fdc7d4ed7dd3faf 100644 (file)
@@ -4,32 +4,34 @@
 #include <lunaix/ds/llist.h>
 #include <stdint.h>
 
 #include <lunaix/ds/llist.h>
 #include <stdint.h>
 
-#define SYS_TIMER_FREQUENCY_HZ      2048
+#define SYS_TIMER_FREQUENCY_HZ 2048
 
 
-#define TIMER_MODE_PERIODIC   0x1
+#define TIMER_MODE_PERIODIC 0x1
 
 typedef uint32_t ticks_t;
 
 
 typedef uint32_t ticks_t;
 
-struct lx_timer_context {
-    struct lx_timer *active_timers;
+struct lx_timer_context
+{
+    struct lx_timer* active_timers;
     /**
      * @brief APIC timer base frequency (ticks per seconds)
     /**
      * @brief APIC timer base frequency (ticks per seconds)
-     * 
+     *
      */
     ticks_t base_frequency;
     /**
      * @brief Desired system running frequency
      */
     ticks_t base_frequency;
     /**
      * @brief Desired system running frequency
-     * 
+     *
      */
     uint32_t running_frequency;
     /**
      * @brief Ticks per hertz
      */
     uint32_t running_frequency;
     /**
      * @brief Ticks per hertz
-     * 
+     *
      */
     ticks_t tphz;
 };
 
      */
     ticks_t tphz;
 };
 
-struct lx_timer {
+struct lx_timer
+{
     struct llist_header link;
     ticks_t deadline;
     ticks_t counter;
     struct llist_header link;
     ticks_t deadline;
     ticks_t counter;
@@ -38,25 +40,30 @@ struct lx_timer {
     uint8_t flags;
 };
 
     uint8_t flags;
 };
 
-
 /**
  * @brief Initialize the system timer that runs at specified frequency
 /**
  * @brief Initialize the system timer that runs at specified frequency
- * 
+ *
  * @param frequency The frequency that timer should run in Hz.
  */
 void
 timer_init(uint32_t frequency);
 
 struct lx_timer*
  * @param frequency The frequency that timer should run in Hz.
  */
 void
 timer_init(uint32_t frequency);
 
 struct lx_timer*
-timer_run_second(uint32_t second, void (*callback)(void*), void* payload, uint8_t flags);
+timer_run_second(uint32_t second,
+                 void (*callback)(void*),
+                 void* payload,
+                 uint8_t flags);
 
 struct lx_timer*
 
 struct lx_timer*
-timer_run_ms(uint32_t millisecond, void (*callback)(void*), void* payload, uint8_t flags);
+timer_run_ms(uint32_t millisecond,
+             void (*callback)(void*),
+             void* payload,
+             uint8_t flags);
 
 struct lx_timer*
 timer_run(ticks_t ticks, void (*callback)(void*), void* payload, uint8_t flags);
 
 
 struct lx_timer*
 timer_run(ticks_t ticks, void (*callback)(void*), void* payload, uint8_t flags);
 
-struct lx_timer_context* 
+struct lx_timer_context*
 timer_context();
 
 #endif /* __LUNAIX_TIMER_H */
 timer_context();
 
 #endif /* __LUNAIX_TIMER_H */
index ed59da3fde2ae17410006f728d2966347702ea87..028792a6375cb92a823776b511bb908bdd0fb57e 100644 (file)
@@ -3,6 +3,16 @@
 
 #include <stdint.h>
 
 
 #include <stdint.h>
 
+#define PROCTERM 0x10000
+#define PROCSTOP 0x20000
+
+#define WNOHANG 1
+#define WUNTRACED 2
+#define WEXITSTATUS(wstatus) ((wstatus & 0xffff))
+#define WIFSTOPPED(wstatus) ((wstatus & PROCSTOP))
+#define WIFEXITED(wstatus)                                                     \
+    ((wstatus & PROCTERM) && ((short)WEXITSTATUS(wstatus) >= 0))
+
 typedef int32_t pid_t;
 
 #endif /* __LUNAIX_TYPES_H */
 typedef int32_t pid_t;
 
 #endif /* __LUNAIX_TYPES_H */
index 471a8e643f44a204b23c3928f5269cc76cd69ddf..4647e95a467da053aec06509b5612b149bd3698d 100644 (file)
@@ -1,5 +1,6 @@
 #define __ASM__
 #include <arch/x86/interrupts.h>
 #define __ASM__
 #include <arch/x86/interrupts.h>
+#include <lunaix/common.h>
 // #define __ASM_INTR_DIAGNOSIS
 
 .macro isr_template vector, no_error_code=1
 // #define __ASM_INTR_DIAGNOSIS
 
 .macro isr_template vector, no_error_code=1
     isr_template PC_KBD_IV
 
     interrupt_wrapper:
     isr_template PC_KBD_IV
 
     interrupt_wrapper:
+        /*
+         Stack layout
+    msa:   [ss]
+           [esp]
+           eflags
+           cs
+           eip
+           err_code   
+           vector     > offset = 28 + 16 + 4 = 48
+           esp
+           gs
+           fs
+           es
+           ds         > offset = 7 * 4 = 28
+           esi
+           ebp
+           edi
+           edx
+           ecx
+           ebx
+    lsa:   eax        > offset = 0
+
+            las: Least Significant Address
+            msa: Most Significant Address
+        */
         pushl %esp
 
         pushl %esp
 
+        subl $16, %esp
+        movw %gs, 12(%esp)
+        movw %fs,  8(%esp)
+        movw %es,  4(%esp)
+        movw %ds,   (%esp)
+
         pushl %esi
         pushl %ebp
         pushl %edi
         pushl %esi
         pushl %ebp
         pushl %edi
         pushl %ebx
         pushl %eax
 
         pushl %ebx
         pushl %eax
 
+        movl 60(%esp), %eax   /* 取出 %cs */
+        andl $0x3, %eax          /* 判断 RPL */
+        jz 1f
+
+        movw $KDATA_SEG, %ax    /* 如果从用户模式转来,则切换至内核数据段 */
+        movw %ax, %gs
+        movw %ax, %fs
+        movw %ax, %ds
+        movw %ax, %es
+
+    1:
         movl %esp, %eax
         andl $0xfffffff0, %esp
         subl $16, %esp
         movl %esp, %eax
         andl $0xfffffff0, %esp
         subl $16, %esp
         popl %edi
         popl %ebp
         popl %esi
         popl %edi
         popl %ebp
         popl %esi
-        popl %esp
+        
+        movw   (%esp), %ds
+        movw  4(%esp), %es
+        movw  8(%esp), %fs
+        movw 12(%esp), %gs
+
+        movl 16(%esp), %esp
 
         addl $8, %esp
 
 
         addl $8, %esp
 
index 55d7e9b9a1e1002773b7d4ce8303c11bc2c24b1c..a59e5f29a3a083266430976929a86bbab3db250e 100644 (file)
@@ -1,33 +1,36 @@
 #include <arch/x86/interrupts.h>
 #include <hal/apic.h>
 #include <hal/cpu.h>
 #include <arch/x86/interrupts.h>
 #include <hal/apic.h>
 #include <hal/cpu.h>
-#include <lunaix/syslog.h>
-#include <lunaix/tty/tty.h>
-#include <lunaix/process.h>
-#include <lunaix/sched.h>
 #include <lunaix/mm/page.h>
 #include <lunaix/mm/vmm.h>
 #include <lunaix/mm/page.h>
 #include <lunaix/mm/vmm.h>
+#include <lunaix/process.h>
+#include <lunaix/sched.h>
+#include <lunaix/syslog.h>
+#include <lunaix/tty/tty.h>
 
 LOG_MODULE("intr")
 
 static int_subscriber subscribers[256];
 
 
 LOG_MODULE("intr")
 
 static int_subscriber subscribers[256];
 
-static int_subscriber fallback = (int_subscriber) 0;
+static int_subscriber fallback = (int_subscriber)0;
 
 void
 
 void
-intr_subscribe(const uint8_t vector, int_subscriber subscriber) {
+intr_subscribe(const uint8_t vector, int_subscriber subscriber)
+{
     subscribers[vector] = subscriber;
 }
 
 void
     subscribers[vector] = subscriber;
 }
 
 void
-intr_unsubscribe(const uint8_t vector, int_subscriber subscriber) {
+intr_unsubscribe(const uint8_t vector, int_subscriber subscriber)
+{
     if (subscribers[vector] == subscriber) {
     if (subscribers[vector] == subscriber) {
-        subscribers[vector] = (int_subscriber) 0;
+        subscribers[vector] = (int_subscriber)0;
     }
 }
 
 void
     }
 }
 
 void
-intr_set_fallback_handler(int_subscriber subscribers) {
+intr_set_fallback_handler(int_subscriber subscribers)
+{
     fallback = subscribers;
 }
 
     fallback = subscribers;
 }
 
@@ -37,15 +40,15 @@ void
 intr_handler(isr_param* param)
 {
     __current->intr_ctx = *param;
 intr_handler(isr_param* param)
 {
     __current->intr_ctx = *param;
-    
+
 #ifdef USE_KERNEL_PT
     cpu_lcr3(__kernel_ptd);
 
     vmm_mount_pd(PD_MOUNT_1, __current->page_table);
 #endif
 
 #ifdef USE_KERNEL_PT
     cpu_lcr3(__kernel_ptd);
 
     vmm_mount_pd(PD_MOUNT_1, __current->page_table);
 #endif
 
-    isr_param *lparam = &__current->intr_ctx;
-    
+    isr_paramlparam = &__current->intr_ctx;
+
     if (lparam->vector <= 255) {
         int_subscriber subscriber = subscribers[lparam->vector];
         if (subscriber) {
     if (lparam->vector <= 255) {
         int_subscriber subscriber = subscribers[lparam->vector];
         if (subscriber) {
@@ -58,17 +61,18 @@ intr_handler(isr_param* param)
         fallback(lparam);
         goto done;
     }
         fallback(lparam);
         goto done;
     }
-    
+
     kprint_panic("INT %u: (%x) [%p: %p] Unknown",
     kprint_panic("INT %u: (%x) [%p: %p] Unknown",
-            lparam->vector,
-            lparam->err_code,
-            lparam->cs,
-            lparam->eip);
+                 lparam->vector,
+                 lparam->err_code,
+                 lparam->cs,
+                 lparam->eip);
 
 done:
     // for all external interrupts except the spurious interrupt
     //  this is required by Intel Manual Vol.3A, section 10.8.1 & 10.8.5
 
 done:
     // for all external interrupts except the spurious interrupt
     //  this is required by Intel Manual Vol.3A, section 10.8.1 & 10.8.5
-    if (lparam->vector >= EX_INTERRUPT_BEGIN && lparam->vector != APIC_SPIV_IV) {
+    if (lparam->vector >= EX_INTERRUPT_BEGIN &&
+        lparam->vector != APIC_SPIV_IV) {
         apic_done_servicing();
     }
 
         apic_done_servicing();
     }
 
index 1d5b9354ce85bcfbfca94f0017b616cdee25ee64..2e361967295265bd8bc900a265cfb9464b15ff98 100644 (file)
@@ -16,7 +16,8 @@
         .long __lxsys_getppid
         .long __lxsys_sleep
         .long __lxsys_exit
         .long __lxsys_getppid
         .long __lxsys_sleep
         .long __lxsys_exit
-        .long __lxsys_wait          /* 9 */
+        .long __lxsys_wait          
+        .long __lxsys_waitpid       /* 10 */
         2:
         .rept __SYSCALL_MAX - (2b - 1b)/4
             .long 0
         2:
         .rept __SYSCALL_MAX - (2b - 1b)/4
             .long 0
index eee475fc604d0dbb7786c174a7bd530df1368ca9..3fa05ef1225d8374142b13d1f374b7a525705567 100644 (file)
@@ -118,18 +118,22 @@ spawn_proc0()
      *      2. 将_kernel_post_init搬进proc0进程
      * (_kernel_post_init已经更名为init_platform)
      *
      *      2. 将_kernel_post_init搬进proc0进程
      * (_kernel_post_init已经更名为init_platform)
      *
-     * 目前的解决方案是两者都使用
+     * 目前的解决方案是2
      */
 
     init_proc(&proc0);
      */
 
     init_proc(&proc0);
-    proc0.intr_ctx = (isr_param){ .registers.esp = KSTACK_TOP - 20,
+    proc0.intr_ctx = (isr_param){ .registers = { .ds = KDATA_SEG,
+                                                 .es = KDATA_SEG,
+                                                 .fs = KDATA_SEG,
+                                                 .gs = KDATA_SEG },
                                   .cs = KCODE_SEG,
                                   .eip = (void*)__proc0,
                                   .ss = KDATA_SEG,
                                   .eflags = cpu_reflags() };
 
                                   .cs = KCODE_SEG,
                                   .eip = (void*)__proc0,
                                   .ss = KDATA_SEG,
                                   .eflags = cpu_reflags() };
 
-    // 必须在读取eflags之后禁用。否则当进程被调度时,中断依然是关闭的!
-    cpu_disable_interrupt();
+    // 方案1:必须在读取eflags之后禁用。否则当进程被调度时,中断依然是关闭的!
+    // cpu_disable_interrupt();
+
     setup_proc_mem(&proc0, PD_REFERENCED);
 
     // Ok... 首先fork进我们的零号进程,而后由那里,我们fork进init进程。
     setup_proc_mem(&proc0, PD_REFERENCED);
 
     // Ok... 首先fork进我们的零号进程,而后由那里,我们fork进init进程。
@@ -139,18 +143,21 @@ spawn_proc0()
     */
     asm volatile("movl %%cr3, %%eax\n"
                  "movl %%esp, %%ebx\n"
     */
     asm volatile("movl %%cr3, %%eax\n"
                  "movl %%esp, %%ebx\n"
-                 "movl %0, %%cr3\n"
-                 "movl %1, %%esp\n"
+                 "movl %1, %%cr3\n"
+                 "movl %2, %%esp\n"
                  "pushf\n"
                  "pushf\n"
-                 "pushl %2\n"
                  "pushl %3\n"
                  "pushl %3\n"
+                 "pushl %4\n"
                  "pushl $0\n"
                  "pushl $0\n"
                  "pushl $0\n"
                  "pushl $0\n"
+                 "movl %%esp, %0\n"
                  "movl %%eax, %%cr3\n"
                  "movl %%eax, %%cr3\n"
-                 "movl %%ebx, %%esp\n" ::"r"(proc0.page_table),
-                 "i"(KSTACK_TOP),
-                 "i"(KCODE_SEG),
-                 "r"(proc0.intr_ctx.eip)
+                 "movl %%ebx, %%esp\n"
+                 : "=m"(proc0.intr_ctx.registers.esp)
+                 : "r"(proc0.page_table),
+                   "i"(KSTACK_TOP),
+                   "i"(KCODE_SEG),
+                   "r"(proc0.intr_ctx.eip)
                  : "%eax", "%ebx", "memory");
 
     // 向调度器注册进程。
                  : "%eax", "%ebx", "memory");
 
     // 向调度器注册进程。
index d951a9fc6f5e553f108d9d3d5b36703b3f4195df..f7b0f955973d158d302365aed186ce6ce522ec83 100644 (file)
@@ -30,6 +30,7 @@ _lxinit_main()
     }
 #endif
 
     }
 #endif
 
+    int status;
 #ifdef WAIT_DEMO
     // 测试wait
     kprintf("I am parent, going to fork my child and wait.\n");
 #ifdef WAIT_DEMO
     // 测试wait
     kprintf("I am parent, going to fork my child and wait.\n");
@@ -39,13 +40,25 @@ _lxinit_main()
         kprintf("I am child, I am about to terminated\n");
         _exit(1);
     }
         kprintf("I am child, I am about to terminated\n");
         _exit(1);
     }
-    int status;
     pid_t child = wait(&status);
     pid_t child = wait(&status);
-    kprintf(
-      "I am parent, my child (%d) terminated with code: %d.\n", child, status);
+    kprintf("I am parent, my child (%d) terminated normally with code: %d.\n",
+            child,
+            WEXITSTATUS(status));
 #endif
 
 #endif
 
-    sleep(5);
+    pid_t p = 0;
+
+    if (!(p = fork())) {
+        kprintf("Test no hang!");
+        sleep(1);
+        _exit(0);
+    }
+
+    waitpid(-1, &status, 0);
+    // FIXME: WNOHANG还有点问题……
+    // waitpid(-1, &status, WNOHANG);
+
+    sleep(2);
 
     // 这里是就是LunaixOS的第一个进程了!
     for (size_t i = 0; i < 10; i++) {
 
     // 这里是就是LunaixOS的第一个进程了!
     for (size_t i = 0; i < 10; i++) {
@@ -62,6 +75,15 @@ _lxinit_main()
         kprintf(KINFO "Forked %d\n", pid);
     }
 
         kprintf(KINFO "Forked %d\n", pid);
     }
 
+    while ((p = wait(&status)) >= 0) {
+        short code = WEXITSTATUS(status);
+        if (WIFEXITED(status)) {
+            kprintf(KINFO "Process %d exited with code %d\n", p, code);
+        } else {
+            kprintf(KWARN "Process %d aborted with code %d\n", p, code);
+        }
+    }
+
     char buf[64];
 
     kprintf(KINFO "Hello processes!\n");
     char buf[64];
 
     kprintf(KINFO "Hello processes!\n");
index a2102aeca029313b203bc7360b65060874650571..dac1b55597c7400c783efcbca659ac72b6a7a390 100644 (file)
@@ -3,6 +3,7 @@
 #include <lunaix/lunistd.h>
 #include <lunaix/mm/vmm.h>
 #include <lunaix/peripheral/ps2kbd.h>
 #include <lunaix/lunistd.h>
 #include <lunaix/mm/vmm.h>
 #include <lunaix/peripheral/ps2kbd.h>
+#include <lunaix/proc.h>
 #include <lunaix/spike.h>
 #include <lunaix/syscall.h>
 #include <lunaix/syslog.h>
 #include <lunaix/spike.h>
 #include <lunaix/syscall.h>
 #include <lunaix/syslog.h>
@@ -39,7 +40,9 @@ __proc0()
         asm("jmp _lxinit_main");
     }
 
         asm("jmp _lxinit_main");
     }
 
-    asm("1: jmp 1b");
+    while (1) {
+        yield();
+    }
 }
 
 extern uint8_t __kernel_start;            /* link/linker.ld */
 }
 
 extern uint8_t __kernel_start;            /* link/linker.ld */
index 8f65087f8253175f0a2dd2f4f26ab34afd718a4a..35e3cff5c69f2a6164a40009cc48d560eb3e1bc5 100644 (file)
@@ -81,6 +81,8 @@ schedule()
 
     sched_ctx.procs_index = ptr;
 
 
     sched_ctx.procs_index = ptr;
 
+    // 上下文切换相当的敏感!我们不希望任何的中断打乱栈的顺序……
+    cpu_disable_interrupt();
     run(next);
 }
 
     run(next);
 }
 
@@ -116,12 +118,27 @@ __DEFINE_LXSYSCALL1(void, exit, int, status)
 
 __DEFINE_LXSYSCALL(void, yield)
 {
 
 __DEFINE_LXSYSCALL(void, yield)
 {
-    schedule();
+    sched_yield();
 }
 
 }
 
+pid_t
+_wait(pid_t wpid, int* status, int options);
+
 __DEFINE_LXSYSCALL1(pid_t, wait, int*, status)
 __DEFINE_LXSYSCALL1(pid_t, wait, int*, status)
+{
+    return _wait(-1, status, 0);
+}
+
+__DEFINE_LXSYSCALL3(pid_t, waitpid, pid_t, pid, int*, status, int, options)
+{
+    return _wait(pid, status, options);
+}
+
+pid_t
+_wait(pid_t wpid, int* status, int options)
 {
     pid_t cur = __current->pid;
 {
     pid_t cur = __current->pid;
+    int status_flags = 0;
     struct proc_info *proc, *n;
     if (llist_empty(&__current->children)) {
         return -1;
     struct proc_info *proc, *n;
     if (llist_empty(&__current->children)) {
         return -1;
@@ -129,16 +146,26 @@ __DEFINE_LXSYSCALL1(pid_t, wait, int*, status)
 repeat:
     llist_for_each(proc, n, &__current->children, siblings)
     {
 repeat:
     llist_for_each(proc, n, &__current->children, siblings)
     {
-        if (proc->state == PROC_TERMNAT) {
-            goto done;
+        if (!~wpid || proc->pid == wpid) {
+            if (proc->state == PROC_TERMNAT && !options) {
+                status_flags |= PROCTERM;
+                goto done;
+            }
+            if (proc->state == PROC_STOPPED && (options & WUNTRACED)) {
+                status_flags |= PROCSTOP;
+                goto done;
+            }
         }
     }
         }
     }
-    // FIXME: 除了循环,也许有更高效的办法……
-    // (在这里进行schedule,需要重写context switch!)
+    if ((options & WNOHANG)) {
+        return 0;
+    }
+    // 放弃当前的运行机会
+    sched_yield();
     goto repeat;
 
 done:
     goto repeat;
 
 done:
-    *status = proc->exit_code;
+    *status = (proc->exit_code & 0xffff) | status_flags;
     return destroy_process(proc->pid);
 }
 
     return destroy_process(proc->pid);
 }
 
index 981b64565fc458121e3f071d4ba65a1540621876..b9d333b1273856d202d2db4a0625e6cb9948654e 100644 (file)
@@ -1,26 +1,26 @@
 /**
  * @file timer.c
  * @author Lunaixsky
 /**
  * @file timer.c
  * @author Lunaixsky
- * @brief A simple timer implementation based on APIC with adjustable frequency and subscribable "timerlets"
+ * @brief A simple timer implementation based on APIC with adjustable frequency
+ * and subscribable "timerlets"
  * @version 0.1
  * @date 2022-03-12
  * @version 0.1
  * @date 2022-03-12
- * 
+ *
  * @copyright Copyright (c) 2022
  * @copyright Copyright (c) 2022
- * 
+ *
  */
 #include <arch/x86/interrupts.h>
 #include <hal/apic.h>
 #include <hal/rtc.h>
 
 #include <lunaix/mm/kalloc.h>
  */
 #include <arch/x86/interrupts.h>
 #include <hal/apic.h>
 #include <hal/rtc.h>
 
 #include <lunaix/mm/kalloc.h>
+#include <lunaix/sched.h>
 #include <lunaix/spike.h>
 #include <lunaix/syslog.h>
 #include <lunaix/timer.h>
 #include <lunaix/spike.h>
 #include <lunaix/syslog.h>
 #include <lunaix/timer.h>
-#include <lunaix/sched.h>
 
 #define LVT_ENTRY_TIMER(vector, mode) (LVT_DELIVERY_FIXED | mode | vector)
 
 
 #define LVT_ENTRY_TIMER(vector, mode) (LVT_DELIVERY_FIXED | mode | vector)
 
-
 LOG_MODULE("TIMER");
 
 static void
 LOG_MODULE("TIMER");
 
 static void
@@ -55,7 +55,6 @@ timer_init_context()
     timer_ctx->active_timers =
       (struct lx_timer*)lxmalloc(sizeof(struct lx_timer));
     llist_init_head(timer_ctx->active_timers);
     timer_ctx->active_timers =
       (struct lx_timer*)lxmalloc(sizeof(struct lx_timer));
     llist_init_head(timer_ctx->active_timers);
-
 }
 
 void
 }
 
 void
@@ -79,13 +78,13 @@ timer_init(uint32_t frequency)
         Timer calibration process - measure the APIC timer base frequency
 
          step 1: setup a temporary isr for RTC timer which trigger at each tick
         Timer calibration process - measure the APIC timer base frequency
 
          step 1: setup a temporary isr for RTC timer which trigger at each tick
-                 (1024Hz) 
-         step 2: setup a temporary isr for #APIC_TIMER_IV 
-         step 3: setup the divider, APIC_TIMER_DCR 
-         step 4: Startup RTC timer 
-         step 5: Write a large value, v, to APIC_TIMER_ICR to start APIC timer (this must be
-                 followed immediately after step 4) 
-         step 6: issue a write to EOI and clean up.
+                 (1024Hz)
+         step 2: setup a temporary isr for #APIC_TIMER_IV
+         step 3: setup the divider, APIC_TIMER_DCR
+         step 4: Startup RTC timer
+         step 5: Write a large value, v, to APIC_TIMER_ICR to start APIC timer
+       (this must be followed immediately after step 4) step 6: issue a write to
+       EOI and clean up.
 
         When the APIC ICR counting down to 0 #APIC_TIMER_IV triggered, save the
        rtc timer's counter, k, and disable RTC timer immediately (although the
 
         When the APIC ICR counting down to 0 #APIC_TIMER_IV triggered, save the
        rtc timer's counter, k, and disable RTC timer immediately (although the
@@ -98,11 +97,11 @@ timer_init(uint32_t frequency)
 
     */
 
 
     */
 
-    #ifdef __LUNAIXOS_DEBUG__
+#ifdef __LUNAIXOS_DEBUG__
     if (frequency < 1000) {
         kprintf(KWARN "Frequency too low. Millisecond timer might be dodgy.");
     }
     if (frequency < 1000) {
         kprintf(KWARN "Frequency too low. Millisecond timer might be dodgy.");
     }
-    #endif
+#endif
 
     timer_ctx->base_frequency = 0;
     rtc_counter = 0;
 
     timer_ctx->base_frequency = 0;
     rtc_counter = 0;
@@ -119,7 +118,6 @@ timer_init(uint32_t frequency)
 
     wait_until(apic_timer_done);
 
 
     wait_until(apic_timer_done);
 
-
     assert_msg(timer_ctx->base_frequency, "Fail to initialize timer (NOFREQ)");
 
     kprintf(KINFO "Base frequency: %u Hz\n", timer_ctx->base_frequency);
     assert_msg(timer_ctx->base_frequency, "Fail to initialize timer (NOFREQ)");
 
     kprintf(KINFO "Base frequency: %u Hz\n", timer_ctx->base_frequency);
@@ -142,23 +140,35 @@ timer_init(uint32_t frequency)
 }
 
 struct lx_timer*
 }
 
 struct lx_timer*
-timer_run_second(uint32_t second, void (*callback)(void*), void* payload, uint8_t flags)
+timer_run_second(uint32_t second,
+                 void (*callback)(void*),
+                 void* payload,
+                 uint8_t flags)
 {
 {
-    return timer_run(second * timer_ctx->running_frequency, callback, payload, flags);
+    return timer_run(
+      second * timer_ctx->running_frequency, callback, payload, flags);
 }
 
 struct lx_timer*
 }
 
 struct lx_timer*
-timer_run_ms(uint32_t millisecond, void (*callback)(void*), void* payload, uint8_t flags)
+timer_run_ms(uint32_t millisecond,
+             void (*callback)(void*),
+             void* payload,
+             uint8_t flags)
 {
 {
-    return timer_run(timer_ctx->running_frequency / 1000 * millisecond, callback, payload, flags);
+    return timer_run(timer_ctx->running_frequency / 1000 * millisecond,
+                     callback,
+                     payload,
+                     flags);
 }
 
 struct lx_timer*
 timer_run(ticks_t ticks, void (*callback)(void*), void* payload, uint8_t flags)
 {
 }
 
 struct lx_timer*
 timer_run(ticks_t ticks, void (*callback)(void*), void* payload, uint8_t flags)
 {
-    struct lx_timer* timer = (struct lx_timer*)lxmalloc(sizeof(struct lx_timer));
+    struct lx_timer* timer =
+      (struct lx_timer*)lxmalloc(sizeof(struct lx_timer));
 
 
-    if (!timer) return NULL;
+    if (!timer)
+        return NULL;
 
     timer->callback = callback;
     timer->counter = ticks;
 
     timer->callback = callback;
     timer->counter = ticks;
@@ -179,12 +189,6 @@ timer_update(const isr_param* param)
 
     llist_for_each(pos, n, &timer_list_head->link, link)
     {
 
     llist_for_each(pos, n, &timer_list_head->link, link)
     {
-        if (!pos->counter) {
-            llist_delete(&pos->link);
-            lxfree(pos);
-            continue;
-        }
-        
         if (--(pos->counter)) {
             continue;
         }
         if (--(pos->counter)) {
             continue;
         }
@@ -193,9 +197,12 @@ timer_update(const isr_param* param)
 
         if ((pos->flags & TIMER_MODE_PERIODIC)) {
             pos->counter = pos->deadline;
 
         if ((pos->flags & TIMER_MODE_PERIODIC)) {
             pos->counter = pos->deadline;
+        } else {
+            llist_delete(&pos->link);
+            lxfree(pos);
         }
     }
         }
     }
-    
+
     sched_ticks_counter++;
 
     if (sched_ticks_counter >= sched_ticks) {
     sched_ticks_counter++;
 
     if (sched_ticks_counter >= sched_ticks) {
@@ -204,6 +211,12 @@ timer_update(const isr_param* param)
     }
 }
 
     }
 }
 
+void
+sched_yield()
+{
+    sched_ticks_counter = sched_ticks;
+}
+
 static void
 temp_intr_routine_rtc_tick(const isr_param* param)
 {
 static void
 temp_intr_routine_rtc_tick(const isr_param* param)
 {
@@ -224,7 +237,8 @@ temp_intr_routine_apic_timer(const isr_param* param)
     rtc_disable_timer();
 }
 
     rtc_disable_timer();
 }
 
-struct lx_timer_context* 
-timer_context() {
+struct lx_timer_context*
+timer_context()
+{
     return timer_ctx;
 }
\ No newline at end of file
     return timer_ctx;
 }
\ No newline at end of file