wizard: fix typo.
[bertos.git] / bertos / kern / preempt.c
index 1cb5e5a07f88d61f1989888855d3d8425eadb64c..bdb6d3c9e716b543529b464167b8ecc04a6a0751 100644 (file)
@@ -124,6 +124,16 @@ 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.
  */
@@ -142,6 +152,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();
 }
@@ -186,14 +198,7 @@ void preempt_wakeup(Process *proc)
        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);
-       }
+               preempt_switchTo(proc);
        else
                SCHED_ENQUEUE_HEAD(proc);
 }
@@ -203,6 +208,8 @@ void preempt_wakeup(Process *proc)
  */
 void preempt_yield(void)
 {
+       Process *proc;
+
        /*
         * Voluntary preemption while preemption is disabled is considered
         * illegal, as not very useful in practice.
@@ -212,10 +219,11 @@ void preempt_yield(void)
        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)