parlib: Catch broken uses of notif_disabled_depth
authorBarret Rhoden <brho@cs.berkeley.edu>
Tue, 25 Apr 2017 18:25:02 +0000 (14:25 -0400)
committerBarret Rhoden <brho@cs.berkeley.edu>
Wed, 3 May 2017 16:13:02 +0000 (12:13 -0400)
Uthreads can disable notifs, such as when grabbing PDR locks, and then
yield to vcore context.  However, they can only do so if their yield
callback lets go of the lock.  At that point, we'll reenable their notifs.
It's broken to have notifs disabled while yielding under any other
circumstance.

Note that the spin_pdr_unlock() call, often made in the yield callback,
will not reenable notifs, since it is being called by vcore context - not
the original uthread that grabbed the lock.  Vcore context is unlocking on
behalf of the uthread.  This is the "atomically block and unlock" that is
the basis for all of the higher-level blocking sync primitives (e.g.
mutex).

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

index 0a339c4..ef0ffc3 100644 (file)
@@ -396,6 +396,7 @@ __uthread_yield(void)
        /* Any locks that were held before the yield must be unlocked in the
         * callback.  That callback won't get a chance to update our disabled depth.
         * This sets us up for the next time the uthread runs. */
+       assert(uthread->notif_disabled_depth <= 1);
        uthread->notif_disabled_depth = 0;
        /* Do whatever the yielder wanted us to do */
        assert(uthread->yield_func);