Add uthread_paused() API call
authorKevin Klues <klueska@cs.berkeley.edu>
Wed, 11 Nov 2015 02:10:27 +0000 (18:10 -0800)
committerBarret Rhoden <brho@cs.berkeley.edu>
Mon, 16 Nov 2015 23:15:03 +0000 (15:15 -0800)
This call is much like uthread_has_blocked(), except that it indicates
that some external component has temporarily paused a uthread, rather
than blocked it. That is, the external component calls uthread_yield()
directly, but then wishes to hand control of the uthread back to the 2LS
in the body of theyield callback.

It is the job of the 2LS to implement sched_ops->paused() such that the
thread becomes runnable again. This sched op actually already exists
because things like preemption can trigger it. Now it is triggerable by
any external component that wishes to temporarily pause a uthread with
its own yield call.

This functionality will prove useful when pausing a temporarily pausing
thread to run a signal handler in its place.

Signed-off-by: Kevin Klues <klueska@cs.berkeley.edu>
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
user/parlib/include/uthread.h
user/parlib/uthread.c

index b876deb..c7e71f6 100644 (file)
@@ -81,6 +81,7 @@ void uthread_yield(bool save_state, void (*yield_func)(struct uthread*, void*),
 void uthread_sleep(unsigned int seconds);
 void uthread_usleep(unsigned int usecs);
 void uthread_has_blocked(struct uthread *uthread, int flags);
+void uthread_paused(struct uthread *uthread);
 
 /* Utility functions */
 bool __check_preempt_pending(uint32_t vcoreid);        /* careful: check the code */
index 48538c9..a65c6d9 100644 (file)
@@ -329,6 +329,17 @@ void uthread_has_blocked(struct uthread *uthread, int flags)
        sched_ops->thread_has_blocked(uthread, flags);
 }
 
+/* Function indicating an external event has temporarily paused a uthread, but
+ * it is ok to resume it if possible. */
+void uthread_paused(struct uthread *uthread)
+{
+       /* Call out to the 2LS to let it know the uthread was paused for some
+        * reason, but it is ok to resume it now. */
+    assert(uthread->state == UT_NOT_RUNNING);
+    assert(sched_ops->thread_paused);
+    sched_ops->thread_paused(uthread);
+}
+
 /* Need to have this as a separate, non-inlined function since we clobber the
  * stack pointer before calling it, and don't want the compiler to play games
  * with my hart. */