Cleaned up some kthread business
authorBarret Rhoden <brho@cs.berkeley.edu>
Sun, 31 Oct 2010 01:18:44 +0000 (18:18 -0700)
committerKevin Klues <klueska@cs.berkeley.edu>
Thu, 3 Nov 2011 00:35:56 +0000 (17:35 -0700)
kern/include/kthread.h
kern/src/blockdev.c
kern/src/kthread.c
kern/src/page_alloc.c

index 733f454..5ce5ff4 100644 (file)
@@ -87,6 +87,7 @@ static inline struct kthread *__up_sem(struct semaphore *sem)
 void kthread_init(void);
 void sleep_on(struct semaphore *sem);
 void restart_kthread(struct kthread *kthread);
+void kthread_runnable(struct kthread *kthread);
 /* Kmsg handler to launch/run a kthread.  This must be a routine message, since
  * it does not return. */
 void __launch_kthread(struct trapframe *tf, uint32_t srcid, void *a0, void *a1,
index 4b849e0..7f4809a 100644 (file)
@@ -144,10 +144,7 @@ void generic_breq_done(struct block_request *breq)
                printk("[kernel] no one waiting on breq %08p\n", breq);
                return;
        }
-       /* For lack of anything better, send it to ourselves (so we handle it out of
-        * interrupt context, which we're still in). (TODO: KSCHED). */
-       send_kernel_message(core_id(), __launch_kthread, (void*)sleeper, 0, 0,
-                           KMSG_ROUTINE);
+       kthread_runnable(sleeper);
        assert(TAILQ_EMPTY(&breq->sem.waiters));
 #else
        breq->data = (void*)1;
index d89e40c..c800c7e 100644 (file)
@@ -154,6 +154,15 @@ void restart_kthread(struct kthread *kthread)
        pop_kernel_tf(&kthread->context);
 }
 
+/* Call this when a kthread becomes runnable/unblocked.  We don't do anything
+ * particularly smart yet, but when we do, we can put it here. */
+void kthread_runnable(struct kthread *kthread)
+{
+       /* For lack of anything better, send it to ourselves. (TODO: KSCHED) */
+       send_kernel_message(core_id(), __launch_kthread, (void*)kthread, 0, 0,
+                           KMSG_ROUTINE);
+}
+
 /* Kmsg handler to launch/run a kthread.  This must be a routine message, since
  * it does not return.  Furthermore, like all routine kmsgs that don't return,
  * this needs to handle the fact that it won't return to the given TF (which is
@@ -165,6 +174,15 @@ void __launch_kthread(struct trapframe *tf, uint32_t srcid, void *a0, void *a1,
        struct proc *cur_proc = current;
        /* If there is no proc running, don't worry about not returning. */
        if (cur_proc) {
+               /* If we're dying, we have a message incoming that we need to deal with,
+                * so we send this message to ourselves (at the end of the queue).  This
+                * is a bit ghetto, and a lot of this will need work. */
+               if (cur_proc->state == PROC_DYING) {
+                       /* We could fake it and send it manually, but this is fine */
+                       send_kernel_message(core_id(), __launch_kthread, (void*)kthread,
+                                           0, 0, KMSG_ROUTINE);
+                       return;
+               }
                if (cur_proc != kthread->proc) {
                        /* we're running the kthread from a different proc.  For now, we
                         * can't be _M, since that would be taking away someone's vcore to
@@ -175,7 +193,8 @@ void __launch_kthread(struct trapframe *tf, uint32_t srcid, void *a0, void *a1,
                        __proc_yield_s(cur_proc, tf);
                        spin_unlock(&cur_proc->proc_lock);
                } else {
-                       assert(cur_proc->state == PROC_RUNNING_M);
+                       /* possible to get here if there is only one _S proc that blocked */
+                       //assert(cur_proc->state == PROC_RUNNING_M);
                        /* TODO: might need to do something here, though it will depend on
                         * how we handle async local calls. */
                }
index ce5aeeb..c4183b9 100644 (file)
@@ -313,9 +313,7 @@ void unlock_page(struct page *page)
        sleeper = __up_sem(&page->pg_sem);
        if (sleeper) {
                printk("Unexpected sleeper on a page!");        /* til we test this */
-               /* For lack of anything better, send it to ourselves. (TODO: KSCHED) */
-               send_kernel_message(core_id(), __launch_kthread, (void*)sleeper, 0, 0,
-                                   KMSG_ROUTINE);
+               kthread_runnable(sleeper);
        }
 }