Module Name: src
Committed By: christos
Date: Fri Jan 31 19:22:00 UTC 2014
Modified Files:
src/lib/libpthread: pthread_cond.c pthread_mutex.c
Log Message:
PR/44756: Sad Clouds: Prevent leakage of errno = ESRCH from _lwp_park. This
has two parts:
- in pthread_cond_timedwait() if the thread we are trying to unpark
exited, retry the the _lwp_park call without it.
- pthread_mutex() was affecting errno since it is calling _lwp_park()
from pthread_mutex_lock_slow(). preserve the original errno.
Note that the example problem still causes an occassional deadlock on machines
with many CPUs and it is the same deadlock we observe with named.
To generate a diff of this commit:
cvs rdiff -u -r1.61 -r1.62 src/lib/libpthread/pthread_cond.c
cvs rdiff -u -r1.56 -r1.57 src/lib/libpthread/pthread_mutex.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_cond.c
diff -u src/lib/libpthread/pthread_cond.c:1.61 src/lib/libpthread/pthread_cond.c:1.62
--- src/lib/libpthread/pthread_cond.c:1.61 Mon Apr 1 09:28:21 2013
+++ src/lib/libpthread/pthread_cond.c Fri Jan 31 14:22:00 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: pthread_cond.c,v 1.61 2013/04/01 13:28:21 christos Exp $ */
+/* $NetBSD: pthread_cond.c,v 1.62 2014/01/31 19:22:00 christos Exp $ */
/*-
* Copyright (c) 2001, 2006, 2007, 2008 The NetBSD Foundation, Inc.
@@ -46,7 +46,7 @@
*/
#include <sys/cdefs.h>
-__RCSID("$NetBSD: pthread_cond.c,v 1.61 2013/04/01 13:28:21 christos Exp $");
+__RCSID("$NetBSD: pthread_cond.c,v 1.62 2014/01/31 19:22:00 christos Exp $");
#include <stdlib.h>
#include <errno.h>
@@ -184,10 +184,12 @@ pthread_cond_timedwait(pthread_cond_t *c
pthread_mutex_unlock(mutex);
self->pt_willpark = 0;
self->pt_blocking++;
- retval = _lwp_park(abstime, self->pt_unpark,
- __UNVOLATILE(&mutex->ptm_waiters),
- __UNVOLATILE(&mutex->ptm_waiters));
- self->pt_unpark = 0;
+ do {
+ retval = _lwp_park(abstime, self->pt_unpark,
+ __UNVOLATILE(&mutex->ptm_waiters),
+ __UNVOLATILE(&mutex->ptm_waiters));
+ self->pt_unpark = 0;
+ } while (retval == -1 && errno == ESRCH);
self->pt_blocking--;
membar_sync();
pthread_mutex_lock(mutex);
Index: src/lib/libpthread/pthread_mutex.c
diff -u src/lib/libpthread/pthread_mutex.c:1.56 src/lib/libpthread/pthread_mutex.c:1.57
--- src/lib/libpthread/pthread_mutex.c:1.56 Thu Mar 21 12:49:12 2013
+++ src/lib/libpthread/pthread_mutex.c Fri Jan 31 14:22:00 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: pthread_mutex.c,v 1.56 2013/03/21 16:49:12 christos Exp $ */
+/* $NetBSD: pthread_mutex.c,v 1.57 2014/01/31 19:22:00 christos Exp $ */
/*-
* Copyright (c) 2001, 2003, 2006, 2007, 2008 The NetBSD Foundation, Inc.
@@ -47,7 +47,7 @@
*/
#include <sys/cdefs.h>
-__RCSID("$NetBSD: pthread_mutex.c,v 1.56 2013/03/21 16:49:12 christos Exp $");
+__RCSID("$NetBSD: pthread_mutex.c,v 1.57 2014/01/31 19:22:00 christos Exp $");
#include <sys/types.h>
#include <sys/lwpctl.h>
@@ -213,6 +213,7 @@ pthread__mutex_lock_slow(pthread_mutex_t
{
void *waiters, *new, *owner, *next;
pthread_t self;
+ int serrno;
pthread__error(EINVAL, "Invalid mutex",
ptm->ptm_magic == _PT_MUTEX_MAGIC);
@@ -232,6 +233,7 @@ pthread__mutex_lock_slow(pthread_mutex_t
return EDEADLK;
}
+ serrno = errno;
for (;; owner = ptm->ptm_owner) {
/* Spin while the owner is running. */
owner = pthread__mutex_spin(ptm, owner);
@@ -244,6 +246,7 @@ pthread__mutex_lock_slow(pthread_mutex_t
next = atomic_cas_ptr(&ptm->ptm_owner, owner,
new);
if (next == owner) {
+ errno = serrno;
#ifndef PTHREAD__ATOMIC_IS_MEMBAR
membar_enter();
#endif