int preempt_needPreempt(void);
void preempt_preempt(void);
void preempt_switch(void);
+void preempt_wakeup(Process *proc);
void preempt_init(void);
+static void preempt_switchTo(Process *proc)
+{
+ Process *old_process = current_process;
+
+ SCHED_ENQUEUE(current_process);
+ _proc_quantum = CONFIG_KERN_QUANTUM;
+ current_process = proc;
+ proc_switchTo(current_process, old_process);
+}
+
/**
* Call the scheduler and eventually replace the current running process.
*/
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();
}
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())
+ preempt_switchTo(proc);
+ else
+ SCHED_ENQUEUE_HEAD(proc);
+}
+
/**
* Voluntarily release the CPU.
*/
void preempt_yield(void)
{
+ Process *proc;
+
/*
* Voluntary preemption while preemption is disabled is considered
* illegal, as not very useful in practice.
ASSERT(proc_preemptAllowed());
IRQ_ASSERT_ENABLED();
- ATOMIC(
- SCHED_ENQUEUE(current_process);
- preempt_schedule();
- );
+ IRQ_DISABLE;
+ proc = (struct Process *)list_remHead(&proc_ready_list);
+ if (proc)
+ preempt_switchTo(proc);
+ IRQ_ENABLE;
}
void preempt_init(void)