Merge from trunk.
[bertos.git] / bertos / kern / preempt.c
index 065faed88e17823eace2972fcd754927f0326f6e..1cb5e5a07f88d61f1989888855d3d8425eadb64c 100644 (file)
@@ -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);
 
 /**
@@ -179,11 +172,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.
  */