Module Name:    src
Committed By:   pooka
Date:           Tue Dec 16 20:05:54 UTC 2014

Modified Files:
        src/lib/libpthread: Makefile pthread.c pthread_int.h
Added Files:
        src/lib/libpthread: pthread_makelwp.h pthread_makelwp_netbsd.c

Log Message:
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


To generate a diff of this commit:
cvs rdiff -u -r1.84 -r1.85 src/lib/libpthread/Makefile
cvs rdiff -u -r1.144 -r1.145 src/lib/libpthread/pthread.c
cvs rdiff -u -r1.89 -r1.90 src/lib/libpthread/pthread_int.h
cvs rdiff -u -r0 -r1.1 src/lib/libpthread/pthread_makelwp.h \
    src/lib/libpthread/pthread_makelwp_netbsd.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/Makefile
diff -u src/lib/libpthread/Makefile:1.84 src/lib/libpthread/Makefile:1.85
--- src/lib/libpthread/Makefile:1.84	Sun Aug 10 23:25:49 2014
+++ src/lib/libpthread/Makefile	Tue Dec 16 20:05:54 2014
@@ -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 @@ CPPFLAGS+=	-D__LIBPTHREAD_SOURCE__ -D__L
 # 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 @@ LIB=	pthread
 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

Index: src/lib/libpthread/pthread.c
diff -u src/lib/libpthread/pthread.c:1.144 src/lib/libpthread/pthread.c:1.145
--- src/lib/libpthread/pthread.c:1.144	Fri Jan 31 20:44:01 2014
+++ src/lib/libpthread/pthread.c	Tue Dec 16 20:05:54 2014
@@ -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 @@ __RCSID("$NetBSD: pthread.c,v 1.144 2014
 
 #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 @@ pthread_create(pthread_t *thread, const 
 			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_create(pthread_t *thread, const 
 			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 @@ pthread_create(pthread_t *thread, const 
 	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 @@ pthread__initmain(pthread_t *newt)
 		    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();

Index: src/lib/libpthread/pthread_int.h
diff -u src/lib/libpthread/pthread_int.h:1.89 src/lib/libpthread/pthread_int.h:1.90
--- src/lib/libpthread/pthread_int.h:1.89	Thu Mar 21 16:49:12 2013
+++ src/lib/libpthread/pthread_int.h	Tue Dec 16 20:05:54 2014
@@ -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 @@ struct	__pthread_st {
 		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 @@ int	pthread__find(pthread_t) PTHREAD_HID
 #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();

Added files:

Index: src/lib/libpthread/pthread_makelwp.h
diff -u /dev/null src/lib/libpthread/pthread_makelwp.h:1.1
--- /dev/null	Tue Dec 16 20:05:54 2014
+++ src/lib/libpthread/pthread_makelwp.h	Tue Dec 16 20:05:54 2014
@@ -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_ */
Index: src/lib/libpthread/pthread_makelwp_netbsd.c
diff -u /dev/null src/lib/libpthread/pthread_makelwp_netbsd.c:1.1
--- /dev/null	Tue Dec 16 20:05:54 2014
+++ src/lib/libpthread/pthread_makelwp_netbsd.c	Tue Dec 16 20:05:54 2014
@@ -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);
+}

Reply via email to