X-Git-Url: https://codewiz.org/gitweb?a=blobdiff_plain;f=bertos%2Fkern%2Fpreempt.c;h=078724b42a8e38095fb93e3c6e226d2e2b5e2d70;hb=f35b6066ecdeffcc8998dd566b5246bdcf43c548;hp=4b1ad9ee2d5dea8e213570eeb1c59fc400290fa6;hpb=e62ca0b357f09804d7d894949df44224c9d74bb7;p=bertos.git diff --git a/bertos/kern/preempt.c b/bertos/kern/preempt.c index 4b1ad9ee..078724b4 100644 --- a/bertos/kern/preempt.c +++ b/bertos/kern/preempt.c @@ -26,140 +26,7 @@ * invalidate any other reasons why the executable file might be covered by * the GNU General Public License. * - * Copyright 2008 Bernie Innocenti - * --> - * - * \brief Simple preemptive multitasking scheduler. - * - * All voluntary and preemptive context switching happens on exit from - * a common interrupt (signal) dispatcher. Preemption on quantum timeout - * is regulated by a soft-timer. Other kinds of preemption could happen - * if an interrupt sends a signal to a higher priority process (but this - * is still unimplemented). + * \note This file is deprecated and kept only for backward compatibility. * - * In the POSIX implementaiton, context switching is done by the portable - * SVR4 swapcontext() facility. - * - * \version $Id: proc.c 1616 2008-08-10 19:41:26Z bernie $ - * \author Bernie Innocenti + * --> */ - -#include - -#if CONFIG_KERN_PREEMPT - -#include "proc_p.h" -#include "proc.h" -#include "idle.h" - -#include -#include -#include // CPU_IDLE -#include // IRQ_DISABLE()... -#include -#include -#include // CONFIG_DEPEND() - -// Check config dependencies -CONFIG_DEPEND(CONFIG_KERN_PREEMPT, CONFIG_KERN_SCHED && CONFIG_TIMER_EVENTS && CONFIG_KERN_IRQ); - -MOD_DEFINE(preempt) - -/// Global preemption disabling nesting counter -cpu_atomic_t _preempt_forbid_cnt; - -static Timer preempt_timer; - - -void proc_schedule(void) -{ - IRQ_DISABLE; - - ASSERT(proc_allowed()); - LIST_ASSERT_VALID(&ProcReadyList); - CurrentProcess = (struct Process *)list_remHead(&ProcReadyList); - ASSERT2(CurrentProcess, "no idle proc?"); - - IRQ_ENABLE; - - TRACEMSG("launching %p:%s", CurrentProcess, proc_currentName()); -} - -void proc_preempt(UNUSED_ARG(void *, param)) -{ - if (proc_allowed()) - { - IRQ_DISABLE; - - #if CONFIG_KERN_PRI - Process *rival = (Process *)LIST_HEAD(&ProcReadyList); - if (rival && rival->link.pri >= CurrentProcess->link.pri) - { - #endif - - TRACEMSG("preempting %p:%s", CurrentProcess, proc_currentName()); - -// FIXME: this still breaks havoc, probably because of some reentrancy issue -#if 0 - SCHED_ENQUEUE(CurrentProcess); - proc_schedule(); -#endif - #if CONFIG_KERN_PRI - } - #endif - - IRQ_ENABLE; - } - - timer_setDelay(&preempt_timer, CONFIG_KERN_QUANTUM); - timer_add(&preempt_timer); -} - -void proc_switch(void) -{ - ATOMIC(LIST_ASSERT_VALID(&ProcReadyList)); - TRACEMSG("%p:%s", CurrentProcess, proc_currentName()); - ATOMIC(LIST_ASSERT_VALID(&ProcReadyList)); - - /* Sleeping with IRQs disabled or preemption forbidden is illegal */ - IRQ_ASSERT_ENABLED(); - ASSERT(proc_allowed()); - - // Will invoke proc_switch() in interrupt context - kill(0, SIGUSR1); -} - -void proc_yield(void) -{ - TRACEMSG("%p:%s", CurrentProcess, proc_currentName()); - - IRQ_DISABLE; - SCHED_ENQUEUE(CurrentProcess); - IRQ_ENABLE; - - proc_switch(); -} - -void proc_entry(void (*user_entry)(void)) -{ - user_entry(); - proc_exit(); -} - -void preempt_init(void) -{ - MOD_CHECK(irq); - MOD_CHECK(timer); - - irq_register(SIGUSR1, proc_schedule); - - timer_setSoftint(&preempt_timer, proc_preempt, NULL); - timer_setDelay(&preempt_timer, CONFIG_KERN_QUANTUM); - timer_add(&preempt_timer); - - idle_init(); - - MOD_INIT(preempt); -} - -#endif // CONFIG_KERN_PREEMPT