X-Git-Url: https://codewiz.org/gitweb?a=blobdiff_plain;f=bertos%2Fkern%2Fpreempt.c;h=4b5e66c3d2261b67874b645c79e0351f7e8d1805;hb=aea9c54dbb7ea4b957f675ffee7266e0432cfd42;hp=065faed88e17823eace2972fcd754927f0326f6e;hpb=d9d931610bca1df6ceb9227eacc9ff2c7f89b77a;p=bertos.git diff --git a/bertos/kern/preempt.c b/bertos/kern/preempt.c index 065faed8..4b5e66c3 100644 --- a/bertos/kern/preempt.c +++ b/bertos/kern/preempt.c @@ -102,14 +102,6 @@ CONFIG_DEPEND(CONFIG_KERN_PREEMPT, CONFIG_KERN); MOD_DEFINE(preempt) -/** - * CPU dependent context switching routines. - * - * Saving and restoring the context on the stack is done by a CPU-dependent - * support routine which usually needs to be written in assembly. - */ -EXTERN_C void asm_switch_context(cpu_stack_t **new_sp, cpu_stack_t **save_sp); - /* Global preemption nesting counter */ cpu_atomic_t preempt_count; @@ -129,6 +121,7 @@ void preempt_yield(void); int preempt_needPreempt(void); void preempt_preempt(void); void preempt_switch(void); +void preempt_wakeup(Process *proc); void preempt_init(void); /** @@ -149,6 +142,8 @@ int preempt_needPreempt(void) return 0; if (!proc_preemptAllowed()) return 0; + if (LIST_EMPTY(&proc_ready_list)) + return 0; return _proc_quantum ? prio_next() > prio_curr() : prio_next() >= prio_curr(); } @@ -179,11 +174,32 @@ void preempt_preempt(void) void preempt_switch(void) { ASSERT(proc_preemptAllowed()); - IRQ_ASSERT_ENABLED(); ATOMIC(preempt_schedule()); } +/** + * Immediately wakeup a process, dispatching it to the CPU. + */ +void preempt_wakeup(Process *proc) +{ + ASSERT(proc_preemptAllowed()); + ASSERT(current_process); + IRQ_ASSERT_DISABLED(); + + if (prio_proc(proc) >= prio_curr()) + { + Process *old_process = current_process; + + SCHED_ENQUEUE(current_process); + _proc_quantum = CONFIG_KERN_QUANTUM; + current_process = proc; + proc_switchTo(current_process, old_process); + } + else + SCHED_ENQUEUE_HEAD(proc); +} + /** * Voluntarily release the CPU. */