From 8357bda627bdf02c1b69eecf27993182239fb463 Mon Sep 17 00:00:00 2001 From: Minep Date: Sat, 11 Jun 2022 18:12:37 +0100 Subject: [PATCH] feat: The waitpid family! feat: Ability to switch data segment fix: Mitigated some race conditions feat: Better way for process to yield current time slice. --- lunaix-os/includes/arch/x86/interrupts.h | 23 +++++-- lunaix-os/includes/hal/cpu.h | 17 +++--- lunaix-os/includes/lunaix/lunistd.h | 2 - lunaix-os/includes/lunaix/proc.h | 6 +- lunaix-os/includes/lunaix/sched.h | 13 +++- lunaix-os/includes/lunaix/syscall.h | 3 +- lunaix-os/includes/lunaix/timer.h | 33 ++++++---- lunaix-os/includes/lunaix/types.h | 10 ++++ lunaix-os/kernel/asm/x86/interrupt.S | 51 +++++++++++++++- lunaix-os/kernel/asm/x86/interrupts.c | 40 +++++++------ lunaix-os/kernel/asm/x86/syscall.S | 3 +- lunaix-os/kernel/k_init.c | 29 +++++---- lunaix-os/kernel/lxinit.c | 30 ++++++++-- lunaix-os/kernel/proc0.c | 5 +- lunaix-os/kernel/sched.c | 39 ++++++++++-- lunaix-os/kernel/time/timer.c | 76 ++++++++++++++---------- 16 files changed, 273 insertions(+), 107 deletions(-) diff --git a/lunaix-os/includes/arch/x86/interrupts.h b/lunaix-os/includes/arch/x86/interrupts.h index 9d3d085..88138b6 100644 --- a/lunaix-os/includes/arch/x86/interrupts.h +++ b/lunaix-os/includes/arch/x86/interrupts.h @@ -5,8 +5,24 @@ #ifndef __ASM__ #include -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; @@ -66,8 +82,7 @@ intr_subscribe(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); diff --git a/lunaix-os/includes/hal/cpu.h b/lunaix-os/includes/hal/cpu.h index b155d4b..fe633d0 100644 --- a/lunaix-os/includes/hal/cpu.h +++ b/lunaix-os/includes/hal/cpu.h @@ -20,12 +20,10 @@ typedef struct typedef struct { - reg16 ss; - reg16 es; reg16 ds; + reg16 es; reg16 fs; reg16 gs; - reg16 cs; } __attribute__((packed)) sg_reg; void @@ -40,7 +38,7 @@ static inline reg32 cpu_rcr0() { uintptr_t val; - asm volatile("movl %%cr0,%0" : "=r" (val)); + asm volatile("movl %%cr0,%0" : "=r"(val)); return val; } @@ -48,7 +46,7 @@ static inline reg32 cpu_rcr2() { uintptr_t val; - asm volatile("movl %%cr2,%0" : "=r" (val)); + asm volatile("movl %%cr2,%0" : "=r"(val)); return val; } @@ -56,7 +54,7 @@ static inline reg32 cpu_rcr3() { uintptr_t val; - asm volatile("movl %%cr3,%0" : "=r" (val)); + asm volatile("movl %%cr3,%0" : "=r"(val)); return val; } @@ -64,10 +62,9 @@ static inline reg32 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 diff --git a/lunaix-os/includes/lunaix/lunistd.h b/lunaix-os/includes/lunaix/lunistd.h index fc1a535..42c4320 100644 --- a/lunaix-os/includes/lunaix/lunistd.h +++ b/lunaix-os/includes/lunaix/lunistd.h @@ -18,6 +18,4 @@ __LXSYSCALL1(void, _exit, int, status) __LXSYSCALL1(unsigned int, sleep, unsigned int, seconds) -__LXSYSCALL1(pid_t, wait, int*, status); - #endif /* __LUNAIX_UNISTD_H */ diff --git a/lunaix-os/includes/lunaix/proc.h b/lunaix-os/includes/lunaix/proc.h index cec5670..a6f4470 100644 --- a/lunaix-os/includes/lunaix/proc.h +++ b/lunaix-os/includes/lunaix/proc.h @@ -2,7 +2,11 @@ #define __LUNAIX_SYS_H #include +#include -__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 */ diff --git a/lunaix-os/includes/lunaix/sched.h b/lunaix-os/includes/lunaix/sched.h index b20a33a..69019f3 100644 --- a/lunaix-os/includes/lunaix/sched.h +++ b/lunaix-os/includes/lunaix/sched.h @@ -3,13 +3,20 @@ #define SCHED_TIME_SLICE 300 -struct scheduler { +struct scheduler +{ 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 */ diff --git a/lunaix-os/includes/lunaix/syscall.h b/lunaix-os/includes/lunaix/syscall.h index dc61f64..c19d501 100644 --- a/lunaix-os/includes/lunaix/syscall.h +++ b/lunaix-os/includes/lunaix/syscall.h @@ -12,6 +12,7 @@ #define __SYSCALL_sleep 7 #define __SYSCALL__exit 8 #define __SYSCALL_wait 9 +#define __SYSCALL_waitpid 10 #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_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( \ diff --git a/lunaix-os/includes/lunaix/timer.h b/lunaix-os/includes/lunaix/timer.h index 567b8d2..c02d7f6 100644 --- a/lunaix-os/includes/lunaix/timer.h +++ b/lunaix-os/includes/lunaix/timer.h @@ -4,32 +4,34 @@ #include #include -#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; -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) - * + * */ ticks_t base_frequency; /** * @brief Desired system running frequency - * + * */ uint32_t running_frequency; /** * @brief Ticks per hertz - * + * */ ticks_t tphz; }; -struct lx_timer { +struct lx_timer +{ struct llist_header link; ticks_t deadline; ticks_t counter; @@ -38,25 +40,30 @@ struct lx_timer { uint8_t flags; }; - /** * @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* -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* -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_context* +struct lx_timer_context* timer_context(); #endif /* __LUNAIX_TIMER_H */ diff --git a/lunaix-os/includes/lunaix/types.h b/lunaix-os/includes/lunaix/types.h index ed59da3..028792a 100644 --- a/lunaix-os/includes/lunaix/types.h +++ b/lunaix-os/includes/lunaix/types.h @@ -3,6 +3,16 @@ #include +#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 */ diff --git a/lunaix-os/kernel/asm/x86/interrupt.S b/lunaix-os/kernel/asm/x86/interrupt.S index 471a8e6..4647e95 100644 --- a/lunaix-os/kernel/asm/x86/interrupt.S +++ b/lunaix-os/kernel/asm/x86/interrupt.S @@ -1,5 +1,6 @@ #define __ASM__ #include +#include // #define __ASM_INTR_DIAGNOSIS .macro isr_template vector, no_error_code=1 @@ -36,8 +37,39 @@ 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 + subl $16, %esp + movw %gs, 12(%esp) + movw %fs, 8(%esp) + movw %es, 4(%esp) + movw %ds, (%esp) + pushl %esi pushl %ebp pushl %edi @@ -46,6 +78,17 @@ 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 @@ -64,7 +107,13 @@ 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 diff --git a/lunaix-os/kernel/asm/x86/interrupts.c b/lunaix-os/kernel/asm/x86/interrupts.c index 55d7e9b..a59e5f2 100644 --- a/lunaix-os/kernel/asm/x86/interrupts.c +++ b/lunaix-os/kernel/asm/x86/interrupts.c @@ -1,33 +1,36 @@ #include #include #include -#include -#include -#include -#include #include #include +#include +#include +#include +#include LOG_MODULE("intr") static int_subscriber subscribers[256]; -static int_subscriber fallback = (int_subscriber) 0; +static int_subscriber fallback = (int_subscriber)0; void -intr_subscribe(const uint8_t vector, int_subscriber subscriber) { +intr_subscribe(const uint8_t vector, int_subscriber subscriber) +{ 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) { - subscribers[vector] = (int_subscriber) 0; + subscribers[vector] = (int_subscriber)0; } } void -intr_set_fallback_handler(int_subscriber subscribers) { +intr_set_fallback_handler(int_subscriber subscribers) +{ fallback = subscribers; } @@ -37,15 +40,15 @@ void 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 - isr_param *lparam = &__current->intr_ctx; - + isr_param* lparam = &__current->intr_ctx; + 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; } - + 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 - 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(); } diff --git a/lunaix-os/kernel/asm/x86/syscall.S b/lunaix-os/kernel/asm/x86/syscall.S index 1d5b935..2e36196 100644 --- a/lunaix-os/kernel/asm/x86/syscall.S +++ b/lunaix-os/kernel/asm/x86/syscall.S @@ -16,7 +16,8 @@ .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 diff --git a/lunaix-os/kernel/k_init.c b/lunaix-os/kernel/k_init.c index eee475f..3fa05ef 100644 --- a/lunaix-os/kernel/k_init.c +++ b/lunaix-os/kernel/k_init.c @@ -118,18 +118,22 @@ spawn_proc0() * 2. 将_kernel_post_init搬进proc0进程 * (_kernel_post_init已经更名为init_platform) * - * 目前的解决方案是两者都使用 + * 目前的解决方案是2 */ 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() }; - // 必须在读取eflags之后禁用。否则当进程被调度时,中断依然是关闭的! - cpu_disable_interrupt(); + // 方案1:必须在读取eflags之后禁用。否则当进程被调度时,中断依然是关闭的! + // cpu_disable_interrupt(); + 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" - "movl %0, %%cr3\n" - "movl %1, %%esp\n" + "movl %1, %%cr3\n" + "movl %2, %%esp\n" "pushf\n" - "pushl %2\n" "pushl %3\n" + "pushl %4\n" "pushl $0\n" "pushl $0\n" + "movl %%esp, %0\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"); // 向调度器注册进程。 diff --git a/lunaix-os/kernel/lxinit.c b/lunaix-os/kernel/lxinit.c index d951a9f..f7b0f95 100644 --- a/lunaix-os/kernel/lxinit.c +++ b/lunaix-os/kernel/lxinit.c @@ -30,6 +30,7 @@ _lxinit_main() } #endif + int status; #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); } - int 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 - 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++) { @@ -62,6 +75,15 @@ _lxinit_main() 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"); diff --git a/lunaix-os/kernel/proc0.c b/lunaix-os/kernel/proc0.c index a2102ae..dac1b55 100644 --- a/lunaix-os/kernel/proc0.c +++ b/lunaix-os/kernel/proc0.c @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -39,7 +40,9 @@ __proc0() asm("jmp _lxinit_main"); } - asm("1: jmp 1b"); + while (1) { + yield(); + } } extern uint8_t __kernel_start; /* link/linker.ld */ diff --git a/lunaix-os/kernel/sched.c b/lunaix-os/kernel/sched.c index 8f65087..35e3cff 100644 --- a/lunaix-os/kernel/sched.c +++ b/lunaix-os/kernel/sched.c @@ -81,6 +81,8 @@ schedule() sched_ctx.procs_index = ptr; + // 上下文切换相当的敏感!我们不希望任何的中断打乱栈的顺序…… + cpu_disable_interrupt(); run(next); } @@ -116,12 +118,27 @@ __DEFINE_LXSYSCALL1(void, exit, int, status) __DEFINE_LXSYSCALL(void, yield) { - schedule(); + sched_yield(); } +pid_t +_wait(pid_t wpid, int* status, int options); + __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; + int status_flags = 0; 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) { - 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: - *status = proc->exit_code; + *status = (proc->exit_code & 0xffff) | status_flags; return destroy_process(proc->pid); } diff --git a/lunaix-os/kernel/time/timer.c b/lunaix-os/kernel/time/timer.c index 981b645..b9d333b 100644 --- a/lunaix-os/kernel/time/timer.c +++ b/lunaix-os/kernel/time/timer.c @@ -1,26 +1,26 @@ /** * @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 - * + * * @copyright Copyright (c) 2022 - * + * */ #include #include #include #include +#include #include #include #include -#include #define LVT_ENTRY_TIMER(vector, mode) (LVT_DELIVERY_FIXED | mode | vector) - 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); - } 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 - (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 @@ -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."); } - #endif +#endif timer_ctx->base_frequency = 0; rtc_counter = 0; @@ -119,7 +118,6 @@ timer_init(uint32_t frequency) 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); @@ -142,23 +140,35 @@ 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) { - 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* -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 = (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; @@ -179,12 +189,6 @@ timer_update(const isr_param* param) llist_for_each(pos, n, &timer_list_head->link, link) { - if (!pos->counter) { - llist_delete(&pos->link); - lxfree(pos); - 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; + } else { + llist_delete(&pos->link); + lxfree(pos); } } - + 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) { @@ -224,7 +237,8 @@ temp_intr_routine_apic_timer(const isr_param* param) rtc_disable_timer(); } -struct lx_timer_context* -timer_context() { +struct lx_timer_context* +timer_context() +{ return timer_ctx; } \ No newline at end of file -- 2.27.0