kthread_yield()
authorBarret Rhoden <brho@cs.berkeley.edu>
Thu, 25 Oct 2012 19:34:11 +0000 (12:34 -0700)
committerBarret Rhoden <brho@cs.berkeley.edu>
Thu, 25 Oct 2012 19:34:11 +0000 (12:34 -0700)
Caller is suspended in a kthread, and will get woken up via RKM to the
calling core.  In essence, it pauses the kthread and allows other RKMs
to run.

If the ksched does anything fancy, we could do other things, like send
the kthread to another core.

kern/include/kthread.h
kern/src/kthread.c

index 60108c0..48714b0 100644 (file)
@@ -93,5 +93,6 @@ void kthread_runnable(struct kthread *kthread);
  * it does not return. */
 void __launch_kthread(struct trapframe *tf, uint32_t srcid, long a0, long a1,
                          long a2);
+void kthread_yield(void);
 
 #endif /* ROS_KERN_KTHREAD_H */
index ac7425d..1f9fc35 100644 (file)
@@ -32,7 +32,7 @@ void sleep_on(struct semaphore *sem)
        int8_t irq_state = 0;
        struct per_cpu_info *pcpui = &per_cpu_info[core_id()];
 
-       /* interrups would be messy here */
+       /* interrupts would be messy here */
        disable_irqsave(&irq_state);
        /* Make sure we aren't holding any locks (only works if SPINLOCK_DEBUG) */
        assert(!pcpui->lock_depth);
@@ -258,3 +258,20 @@ void __launch_kthread(struct trapframe *tf, uint32_t srcid, long a0, long a1,
        restart_kthread(kthread);
        assert(0);
 }
+
+/* Stop the current kthread.  It'll get woken up next time we run routine kmsgs,
+ * after all existing kmsgs are processed. */
+void kthread_yield(void)
+{
+       struct semaphore local_sem, *sem = &local_sem;
+       void __wake_me_up(struct trapframe *tf, uint32_t srcid, long a0, long a1,
+                         long a2)
+       {
+               struct kthread *me = __up_sem(sem, TRUE);
+               assert(me);
+               kthread_runnable(me);
+       }
+       init_sem(sem, 0);
+       send_kernel_message(core_id(), __wake_me_up, 0, 0, 0, KMSG_ROUTINE);
+       sleep_on(sem);
+}