Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/netbsd-9]: src/lib/libpthread Apply patch, requested by riastradh in tic...



details:   https://anonhg.NetBSD.org/src/rev/3f0a27364abd
branches:  netbsd-9
changeset: 368857:3f0a27364abd
user:      martin <martin%NetBSD.org@localhost>
date:      Mon Aug 08 17:16:53 2022 +0000

description:
Apply patch, requested by riastradh in ticket #1498:

        lib/libpthread/pthread.c                1.181 (via patch)

libpthread(3): Fix a marvellous interaction with rtld.

Patch from chs@.  Comment explaining the story by me.  This patch may
not be optimal -- maybe it would be better in pthread__init, or
better for rtld to call _lwp_unpark after _lwp_park in the contened
case -- but we've tested this version and it's annoying to reproduce,
so let's take this version and worry about testing improvements
later.

diffstat:

 lib/libpthread/pthread.c |  32 ++++++++++++++++++++++++++++++--
 1 files changed, 30 insertions(+), 2 deletions(-)

diffs (53 lines):

diff -r 492704a1d187 -r 3f0a27364abd lib/libpthread/pthread.c
--- a/lib/libpthread/pthread.c  Mon Aug 08 17:09:20 2022 +0000
+++ b/lib/libpthread/pthread.c  Mon Aug 08 17:16:53 2022 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: pthread.c,v 1.153.2.1 2020/01/26 10:55:16 martin Exp $ */
+/*     $NetBSD: pthread.c,v 1.153.2.2 2022/08/08 17:16:53 martin Exp $ */
 
 /*-
  * Copyright (c) 2001, 2002, 2003, 2006, 2007, 2008 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: pthread.c,v 1.153.2.1 2020/01/26 10:55:16 martin Exp $");
+__RCSID("$NetBSD: pthread.c,v 1.153.2.2 2022/08/08 17:16:53 martin Exp $");
 
 #define        __EXPOSE_STACK  1
 
@@ -425,6 +425,34 @@
                return __libc_thr_create_stub(thread, attr, startfunc, arg);
        }
 
+       if (!pthread__started) {
+               /*
+                * Force the _lwp_park symbol to be resolved before we
+                * begin any activity that might rely on concurrent
+                * wakeups.
+                *
+                * This is necessary because rtld itself uses _lwp_park
+                * and _lwp_unpark internally for its own locking: If
+                * we wait to resolve _lwp_park until there is an
+                * _lwp_unpark from another thread pending in the
+                * current lwp (for example, pthread_mutex_unlock or
+                * pthread_cond_signal), rtld's internal use of
+                * _lwp_park might consume the pending unpark.  The
+                * result is a deadlock where libpthread and rtld have
+                * both correctly used _lwp_park and _lwp_unpark for
+                * themselves, but rtld has consumed the wakeup meant
+                * for libpthread so it is lost to libpthread.
+                *
+                * For the very first thread, before pthread__started
+                * is set to true, pthread__self()->pt_lid should have
+                * been initialized in pthread__init by the time we get
+                * here to the correct lid so we go to sleep and wake
+                * ourselves at the same time as a no-op.
+                */
+               _lwp_park(CLOCK_REALTIME, 0, NULL, pthread__self()->pt_lid,
+                   NULL, NULL);
+       }
+
        /*
         * It's okay to check this without a lock because there can
         * only be one thread before it becomes true.



Home | Main Index | Thread Index | Old Index