Uthread code no longer tracks detailed states
authorBarret Rhoden <brho@cs.berkeley.edu>
Wed, 18 Apr 2012 19:18:16 +0000 (12:18 -0700)
committerBarret Rhoden <brho@cs.berkeley.edu>
Wed, 18 Apr 2012 19:18:16 +0000 (12:18 -0700)
Uthread code only cares about RUNNING vs NOT_RUNNING, and this is only
to catch bugs.  The 2LS is responsible for any state it wishes to track,
such as the diff btw blocking on a syscall, joining, exiting, blocking
on a mutex, whatever.

user/parlib/include/uthread.h
user/parlib/uthread.c
user/pthread/pthread.c

index db10e82..e39004a 100644 (file)
@@ -9,11 +9,8 @@
 #define UTHREAD_FPSAVED                                0x004 /* uthread's FP state is in uth->as */
 
 /* Thread States */
-#define UT_CREATED     1
-#define UT_RUNNABLE    2
-#define UT_RUNNING     3
-#define UT_BLOCKED     4
-#define UT_DYING       5
+#define UT_RUNNING             1
+#define UT_NOT_RUNNING 2
 
 /* Bare necessities of a user thread.  2LSs should allocate a bigger struct and
  * cast their threads to uthreads when talking with vcore code.  Vcore/default
index 98c592c..e0a99b2 100644 (file)
@@ -172,7 +172,7 @@ void uthread_init(struct uthread *new_thread)
        assert(!in_vcore_context());
        uint32_t vcoreid;
        assert(new_thread);
-       new_thread->state = UT_CREATED;
+       new_thread->state = UT_NOT_RUNNING;
        /* They should have zero'd the uthread.  Let's check critical things: */
        assert(!new_thread->flags && !new_thread->sysc);
        /* the utf/as holds the context of the uthread (set by the 2LS earlier) */
@@ -213,7 +213,6 @@ void uthread_runnable(struct uthread *uthread)
 {
        /* Allow the 2LS to make the thread runnable, and do whatever. */
        assert(sched_ops->thread_runnable);
-       uthread->state = UT_RUNNABLE;
        sched_ops->thread_runnable(uthread);
 }
 
@@ -229,15 +228,14 @@ __uthread_yield(void)
        /* Note: we no longer care if the thread is exiting, the 2LS will call
         * uthread_destroy() */
        uthread->flags &= ~UTHREAD_DONT_MIGRATE;
+       uthread->state = UT_NOT_RUNNING;
        /* Determine if we're blocking on a syscall or just yielding.  Might end
         * up doing this differently when/if we have more ways to yield. */
        if (uthread->sysc) {
-               uthread->state = UT_BLOCKED;
                assert(sched_ops->thread_blockon_sysc);
                sched_ops->thread_blockon_sysc(uthread->sysc);
                /* make sure you don't touch uthread after that sched ops call */
        } else { /* generic yield */
-               uthread->state = UT_RUNNABLE;
                assert(sched_ops->thread_yield);
                /* 2LS will save the thread somewhere for restarting.  Later on,
                 * we'll probably have a generic function for all sorts of waiting.
@@ -316,7 +314,6 @@ yield_return_path:
 void uthread_cleanup(struct uthread *uthread)
 {
        printd("[U] thread %08p on vcore %d is DYING!\n", uthread, vcore_id());
-       uthread->state = UT_DYING;
        /* we alloc and manage the TLS, so lets get rid of it */
        __uthread_free_tls(uthread);
 }
@@ -406,14 +403,12 @@ static void __run_cur_uthread(void)
 /* Simply sets current uthread to be whatever the value of uthread is.  This
  * can be called from outside of sched_entry() to highjack the current context,
  * and make sure that the new uthread struct is used to store this context upon
- * yielding, etc. USE WITH EXTREME CAUTION!
-*/
+ * yielding, etc. USE WITH EXTREME CAUTION! */
 void highjack_current_uthread(struct uthread *uthread)
 {
        assert(uthread != current_uthread);
        assert(uthread->tls_desc);
-
-       current_uthread->state = UT_RUNNABLE;
+       current_uthread->state = UT_NOT_RUNNING;
        uthread->state = UT_RUNNING;
        vcore_set_tls_var(current_uthread, uthread);
        set_tls_desc(uthread->tls_desc, vcore_id());
@@ -441,13 +436,13 @@ void run_uthread(struct uthread *uthread)
 {
        uint32_t vcoreid = vcore_id();
        assert(uthread != current_uthread);
-       if (uthread->state != UT_RUNNABLE) {
+       if (uthread->state != UT_NOT_RUNNING) {
                /* had vcore3 throw this, when the UT blocked on vcore1 and didn't come
                 * back up yet (kernel didn't wake up, didn't send IPI) */
                printf("Uth %08p not runnable (was %d) in run_uthread on vcore %d!\n",
                       uthread, uthread->state, vcore_id());
        }
-       assert(uthread->state == UT_RUNNABLE);
+       assert(uthread->state == UT_NOT_RUNNING);
        uthread->state = UT_RUNNING;
        /* Save a ptr to the uthread we'll run in the transition context's TLS */
        current_uthread = uthread;
index 88fb284..b0fda20 100644 (file)
@@ -102,7 +102,6 @@ void __attribute__((noreturn)) pth_sched_entry(void)
                 * bit before yielding (or not at all if you want to be greedy). */
                vcore_yield(FALSE);
        } while (1);
-       assert(((struct uthread*)new_thread)->state != UT_RUNNING);
        run_uthread((struct uthread*)new_thread);
        assert(0);
 }
@@ -223,7 +222,7 @@ static void restart_thread(struct syscall *sysc)
        struct uthread *ut_restartee = (struct uthread*)sysc->u_data;
        /* uthread stuff here: */
        assert(ut_restartee);
-       assert(ut_restartee->state == UT_BLOCKED);
+       //assert(ut_restartee->state == UT_BLOCKED);
        assert(ut_restartee->sysc == sysc);
        ut_restartee->sysc = 0; /* so we don't 'reblock' on this later */
        uthread_runnable(ut_restartee);
@@ -261,7 +260,7 @@ void pth_blockon_sysc(struct syscall *sysc)
        bool need_to_restart = FALSE;
        uint32_t vcoreid = vcore_id();
 
-       assert(current_uthread->state == UT_BLOCKED);
+       //assert(current_uthread->state == UT_BLOCKED);
        /* rip from the active queue */
        struct pthread_tcb *pthread = (struct pthread_tcb*)current_uthread;
        mcs_pdr_lock(&queue_lock);