pthread: Account for pth stopping in has_blocked
authorBarret Rhoden <brho@cs.berkeley.edu>
Tue, 20 Oct 2015 18:16:19 +0000 (14:16 -0400)
committerBarret Rhoden <brho@cs.berkeley.edu>
Wed, 28 Oct 2015 16:05:13 +0000 (12:05 -0400)
This popped up as

uthread.c:621: run_uthread: Assertion `uthread->state == 2' failed.

and

pthread.c:246: pth_sched_entry: Assertion `new_thread->state == 2'
failed.

for an epoll/eventfd app.

The ready and active queues were corrupted, due to adding a pthread to
the ready queue in pth_thread_runnable() that was still on the active
queue.

Anytime a pthread stops and will eventually have pth_thread_runnable()
called, as is the case with blocking a uthread on an event queue (which
epoll does), then the pthread code needs to yank it off the active
queue.  Modifications of pthread->state are a good sign that list
management needs to be done.

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

index b68cd55..59cf4cb 100644 (file)
@@ -381,6 +381,8 @@ static void pth_thread_blockon_sysc(struct uthread *uthread, void *syscall)
 static void pth_thread_has_blocked(struct uthread *uthread, int flags)
 {
        struct pthread_tcb *pthread = (struct pthread_tcb*)uthread;
+
+       __pthread_generic_yield(pthread);
        /* could imagine doing something with the flags.  For now, we just treat all
         * externally blocked reasons as 'MUTEX'.  Whatever we do here, we are
         * mostly communicating to our future selves in pth_thread_runnable(), which