Source-Changes-HG archive

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

[src/trunk]: src/lib/libpthread Allow for arbitrary MI scheduler implementati...



details:   https://anonhg.NetBSD.org/src/rev/66d16a767878
branches:  trunk
changeset: 334946:66d16a767878
user:      pooka <pooka%NetBSD.org@localhost>
date:      Tue Dec 16 20:05:54 2014 +0000

description:
Allow for arbitrary MI scheduler implementations.

A concrete result is enabling unpatched libpthread to run on the
rumprun stacks (e.g. Xen and bare metal) with a non-NetBSD scheduler.
Those schedulers hook into the existing _lwp_frobnitz() NetBSD syscall
interfaces (well, "syscall" interfaces in that scenario ;)

More specifically about the change itself:

1) instead of calling _lwp_makecontext() followed by _lwp_create()
   and passing the entry point in ucontext_t (MD) through the calls, roll
   the calls into pthread__makelwp() and allow alternate implementations
   for that MI interface.

2) allow compile-time overriding of __lwp_gettcb_fast() or
   __lwp_getprivate_fast, which are inline and leak MD scheduler/thread
   details into libpthread


Additionally, two small nits:

I)  define LIB=pthread before including mk.conf so that it's possible
    to test for LIB==pthread in mk.conf

II) make it possible to leave out pthread_cancelstub.c.  This is required
    by the current implementation of rumprun-posix (i.e. rumprun on
    POSIX hosts) due to symbol collisions.  It needs to be fixed properly
    some day, but for now allows an almost-correct libpthread to run.
    I am sure @justin will be happy to explain the details ;)


no change to NetBSD
tested: anita+atf

diffstat:

 lib/libpthread/Makefile                 |  12 +++++-
 lib/libpthread/pthread.c                |  25 +++++-------
 lib/libpthread/pthread_int.h            |  16 ++++----
 lib/libpthread/pthread_makelwp.h        |  46 +++++++++++++++++++++++
 lib/libpthread/pthread_makelwp_netbsd.c |  64 +++++++++++++++++++++++++++++++++
 5 files changed, 138 insertions(+), 25 deletions(-)

diffs (275 lines):

diff -r 8de047ceb600 -r 66d16a767878 lib/libpthread/Makefile
--- a/lib/libpthread/Makefile   Tue Dec 16 19:30:24 2014 +0000
+++ b/lib/libpthread/Makefile   Tue Dec 16 20:05:54 2014 +0000
@@ -1,7 +1,8 @@
-#      $NetBSD: Makefile,v 1.84 2014/08/10 23:25:49 matt Exp $
+#      $NetBSD: Makefile,v 1.85 2014/12/16 20:05:54 pooka Exp $
 #
 
 WARNS?=        5
+LIB=   pthread
 
 .include <bsd.own.mk>
 
@@ -35,7 +36,10 @@
 # XXX: This crappy poke at libc's internals needs to be fixed.
 CPPFLAGS+=-I${NETBSDSRCDIR}/sys -I${.CURDIR}/../libc
 
-LIB=   pthread
+# providing alternative MI implementations for creating an lwp is
+# possible by setting PTHREAD_MAKELWP.  Currently, alternatives are
+# set by the rumprun software stacks (see repo.rumpkernel.org)
+PTHREAD_MAKELWP?=      pthread_makelwp_netbsd.c
 
 #
 # NOTE: When you create a new file for libpthread, make sure that pthread.c
@@ -45,9 +49,13 @@
 SRCS=  pthread.c 
 SRCS+= pthread_attr.c
 SRCS+= pthread_barrier.c
+# used by rumprun-posix to work around symbol collisions
+.if ${PTHREAD_CANCELSTUB:Uyes} != "no"
 SRCS+= pthread_cancelstub.c
+.endif
 SRCS+= pthread_cond.c
 SRCS+= pthread_lock.c 
+SRCS+= ${PTHREAD_MAKELWP}
 SRCS+= pthread_misc.c
 SRCS+= pthread_mutex.c
 SRCS+= pthread_once.c
diff -r 8de047ceb600 -r 66d16a767878 lib/libpthread/pthread.c
--- a/lib/libpthread/pthread.c  Tue Dec 16 19:30:24 2014 +0000
+++ b/lib/libpthread/pthread.c  Tue Dec 16 20:05:54 2014 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: pthread.c,v 1.144 2014/01/31 20:44:01 christos Exp $   */
+/*     $NetBSD: pthread.c,v 1.145 2014/12/16 20:05:54 pooka 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.144 2014/01/31 20:44:01 christos Exp $");
+__RCSID("$NetBSD: pthread.c,v 1.145 2014/12/16 20:05:54 pooka Exp $");
 
 #define        __EXPOSE_STACK  1
 
@@ -59,6 +59,7 @@
 
 #include "pthread.h"
 #include "pthread_int.h"
+#include "pthread_makelwp.h"
 #include "reentrant.h"
 
 pthread_rwlock_t pthread__alltree_lock = PTHREAD_RWLOCK_INITIALIZER;
@@ -464,10 +465,6 @@
                        return ENOMEM;
                }
 
-               /* This is used only when creating the thread. */
-               _INITCONTEXT_U(&newthread->pt_uc);
-               newthread->pt_uc.uc_stack = newthread->pt_stack;
-               newthread->pt_uc.uc_link = NULL;
 #if defined(__HAVE_TLS_VARIANT_I) || defined(__HAVE_TLS_VARIANT_II)
                newthread->pt_tls = NULL;
 #endif
@@ -487,9 +484,6 @@
                        pthread_mutex_unlock(&pthread__deadqueue_lock);
                        return ENOMEM;
                }
-               _INITCONTEXT_U(&newthread->pt_uc);
-               newthread->pt_uc.uc_stack = newthread->pt_stack;
-               newthread->pt_uc.uc_link = NULL;
        }
 
        /*
@@ -505,15 +499,14 @@
        private_area = newthread;
 #endif
 
-       _lwp_makecontext(&newthread->pt_uc, pthread__create_tramp,
-           newthread, private_area, newthread->pt_stack.ss_sp,
-           newthread->pt_stack.ss_size);
-
        flag = LWP_DETACHED;
        if ((newthread->pt_flags & PT_FLAG_SUSPENDED) != 0 ||
            (nattr.pta_flags & PT_FLAG_EXPLICIT_SCHED) != 0)
                flag |= LWP_SUSPENDED;
-       ret = _lwp_create(&newthread->pt_uc, flag, &newthread->pt_lid);
+
+       ret = pthread__makelwp(pthread__create_tramp, newthread, private_area,
+           newthread->pt_stack.ss_sp, newthread->pt_stack.ss_size,
+           flag, &newthread->pt_lid);
        if (ret != 0) {
                ret = errno;
                pthread_mutex_lock(&newthread->pt_lock);
@@ -1325,7 +1318,9 @@
                    4 * pthread__pagesize / 1024);
 
        *newt = &pthread__main;
-#ifdef __HAVE___LWP_GETTCB_FAST
+#if defined(_PTHREAD_GETTCB_EXT)
+       pthread__main.pt_tls = _PTHREAD_GETTCB_EXT();
+#elif defined(__HAVE___LWP_GETTCB_FAST)
        pthread__main.pt_tls = __lwp_gettcb_fast();
 #else
        pthread__main.pt_tls = _lwp_getprivate();
diff -r 8de047ceb600 -r 66d16a767878 lib/libpthread/pthread_int.h
--- a/lib/libpthread/pthread_int.h      Tue Dec 16 19:30:24 2014 +0000
+++ b/lib/libpthread/pthread_int.h      Tue Dec 16 20:05:54 2014 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: pthread_int.h,v 1.89 2013/03/21 16:49:12 christos Exp $        */
+/*     $NetBSD: pthread_int.h,v 1.90 2014/12/16 20:05:54 pooka Exp $   */
 
 /*-
  * Copyright (c) 2001, 2002, 2003, 2006, 2007, 2008 The NetBSD Foundation, Inc.
@@ -152,12 +152,6 @@
                void *pts_value;
                PTQ_ENTRY(pt_specific) pts_next;
        } pt_specific[PTHREAD_KEYS_MAX];
-
-       /*
-        * Context for thread creation.  At the end as it's cached
-        * and then only ever passed to _lwp_create(). 
-        */
-       ucontext_t      pt_uc;
 };
 
 /* Thread states */
@@ -265,10 +259,16 @@
 #error Either __HAVE_TLS_VARIANT_I or __HAVE_TLS_VARIANT_II must be defined
 #endif
 
+#ifdef _PTHREAD_GETTCB_EXT
+struct tls_tcb *_PTHREAD_GETTCB_EXT(void);
+#endif
+
 static inline pthread_t __constfunc
 pthread__self(void)
 {
-#ifdef __HAVE___LWP_GETTCB_FAST
+#if defined(_PTHREAD_GETTCB_EXT)
+       struct tls_tcb * const tcb = _PTHREAD_GETTCB_EXT();
+#elif defined(__HAVE___LWP_GETTCB_FAST)
        struct tls_tcb * const tcb = __lwp_gettcb_fast();
 #else
        struct tls_tcb * const tcb = __lwp_getprivate_fast();
diff -r 8de047ceb600 -r 66d16a767878 lib/libpthread/pthread_makelwp.h
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/lib/libpthread/pthread_makelwp.h  Tue Dec 16 20:05:54 2014 +0000
@@ -0,0 +1,46 @@
+/*     $NetBSD: pthread_makelwp.h,v 1.1 2014/12/16 20:05:54 pooka Exp $        */
+
+/*-
+ * Copyright (c) 2001, 2002, 2003, 2006, 2007, 2008 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Nathan J. Williams and Andrew Doran.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _LIB_PTHREAD_MAKELWP_H_
+#define _LIB_PTHREAD_MAKELWP_H_
+
+#include <sys/param.h>
+
+#include <lwp.h>
+
+/* for PTHREAD_HIDE */
+#include <pthread.h>
+#include "pthread_int.h"
+
+int    pthread__makelwp(void (*)(void *), void *, void *, void *, size_t,
+                        unsigned long, lwpid_t *) PTHREAD_HIDE;
+
+#endif /* _LIB_PTHREAD_MAKELWP_H_ */
diff -r 8de047ceb600 -r 66d16a767878 lib/libpthread/pthread_makelwp_netbsd.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/lib/libpthread/pthread_makelwp_netbsd.c   Tue Dec 16 20:05:54 2014 +0000
@@ -0,0 +1,64 @@
+/*     $NetBSD: pthread_makelwp_netbsd.c,v 1.1 2014/12/16 20:05:54 pooka Exp $ */
+
+/*-
+ * Copyright (c) 2001, 2002, 2003, 2006, 2007, 2008 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Nathan J. Williams and Andrew Doran.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: pthread_makelwp_netbsd.c,v 1.1 2014/12/16 20:05:54 pooka Exp $");
+
+#include <sys/param.h>
+
+#include <lwp.h>
+#include <pthread.h>
+
+#include "pthread_int.h"
+#include "pthread_makelwp.h"
+
+int
+pthread__makelwp(void (*start_routine)(void *), void *arg, void *priv,
+       void *stack_base, size_t stack_size,
+       unsigned long flag, lwpid_t *newlid)
+{
+       ucontext_t uc;
+
+       /*
+        * XXX: most of the following chunk is these days
+        * performed also by _lwp_makecontext(), but there may
+        * be MD differences, so lug everything along for now.
+        */
+       memset(&uc, 0, sizeof(uc));
+       _INITCONTEXT_U(&uc);
+       uc.uc_stack.ss_sp = stack_base;
+       uc.uc_stack.ss_size = stack_size;
+       uc.uc_stack.ss_flags = 0;
+       uc.uc_link = NULL;
+
+       _lwp_makecontext(&uc, start_routine, arg, priv, stack_base, stack_size);
+       return _lwp_create(&uc, flag, newlid);
+}



Home | Main Index | Thread Index | Old Index