Module Name: src Committed By: ad Date: Sat Jan 25 18:01:28 UTC 2020
Modified Files: src/lib/libpthread: pthread.c Log Message: pthread_exit(): it looks there there is at least one path through which a thread can exit with waiters still hanging off it (cancellation when waiting on a condvar) so deal with all/any crappy failure like that and make sure there are never any waiters left before exiting. Maybe of help for: PR: bin/50350: rump/rumpkern/t_sp/stress_{long,short} fail on Core 2 To generate a diff of this commit: cvs rdiff -u -r1.155 -r1.156 src/lib/libpthread/pthread.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/lib/libpthread/pthread.c diff -u src/lib/libpthread/pthread.c:1.155 src/lib/libpthread/pthread.c:1.156 --- src/lib/libpthread/pthread.c:1.155 Sat Jan 25 15:41:52 2020 +++ src/lib/libpthread/pthread.c Sat Jan 25 18:01:28 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: pthread.c,v 1.155 2020/01/25 15:41:52 ad Exp $ */ +/* $NetBSD: pthread.c,v 1.156 2020/01/25 18:01:28 ad Exp $ */ /*- * Copyright (c) 2001, 2002, 2003, 2006, 2007, 2008, 2020 @@ -31,7 +31,7 @@ */ #include <sys/cdefs.h> -__RCSID("$NetBSD: pthread.c,v 1.155 2020/01/25 15:41:52 ad Exp $"); +__RCSID("$NetBSD: pthread.c,v 1.156 2020/01/25 18:01:28 ad Exp $"); #define __EXPOSE_STACK 1 @@ -621,6 +621,23 @@ pthread_resume_np(pthread_t thread) return errno; } +/* + * In case the thread is exiting at an inopportune time leaving waiters not + * awoken (because cancelled, for instance) make sure we have no waiters + * left. + */ +static void +pthread__clear_waiters(pthread_t self) +{ + + if (self->pt_nwaiters != 0) { + (void)_lwp_unpark_all(self->pt_waiters, self->pt_nwaiters, + NULL); + self->pt_nwaiters = 0; + } + self->pt_willpark = 0; +} + void pthread_exit(void *retval) { @@ -658,7 +675,10 @@ pthread_exit(void *retval) /* Perform cleanup of thread-specific data */ pthread__destroy_tsd(self); - /* Signal our exit. */ + /* + * Signal our exit. Our stack and pthread_t won't be reused until + * pthread_create() can see from kernel info that this LWP is gone. + */ self->pt_exitval = retval; if (self->pt_flags & PT_FLAG_DETACHED) { self->pt_state = PT_STATE_DEAD; @@ -670,11 +690,13 @@ pthread_exit(void *retval) pthread_mutex_lock(&pthread__deadqueue_lock); PTQ_INSERT_TAIL(&pthread__deadqueue, self, pt_deadq); pthread_mutex_unlock(&pthread__deadqueue_lock); + pthread__clear_waiters(self); _lwp_exit(); } else { self->pt_state = PT_STATE_ZOMBIE; pthread_cond_broadcast(&self->pt_joiners); pthread_mutex_unlock(&self->pt_lock); + pthread__clear_waiters(self); /* Note: name will be freed by the joiner. */ _lwp_exit(); }