svn commit: r190393 - in stable/7: include lib/libc/gen lib/libc/include lib/libc/stdlib lib/libthr lib/libthr/arch/amd64/include lib/libthr/arch/i386 lib/libthr/thread libexec/rtld-elf sys/kern sy...

Konstantin Belousov kib at FreeBSD.org
Tue Mar 24 13:57:13 PDT 2009


Author: kib
Date: Tue Mar 24 20:57:10 2009
New Revision: 190393
URL: http://svn.freebsd.org/changeset/base/190393

Log:
  Mostly synchronize  lib/libthr and sys/kern/kern_umtx.c with the code
  from HEAD.
  
  Since libkse is still built on RELENG_7, pthread_cleanup_push/pop
  are left as the functions, but the support code in libthr is present for
  the macro versions.
  
  Malloc in RELENG_7 does not require thread exit hook, but I decided
  to add empty handler for it, instead of removing callback from thr_exit().
  
  No mergeinfo since this change is prepared by patching libthr and then
  bringing in required missed bits.
  
  Requested by:	bms
  Reviewed by:	davidxu
  Tested by:	bms, Mykola Dzham <i levsha org ua>
  Approved by:	re (kensmith)

Added:
  stable/7/lib/libthr/thread/thr_affinity.c   (contents, props changed)
  stable/7/lib/libthr/thread/thr_getcpuclockid.c   (contents, props changed)
Modified:
  stable/7/include/pthread.h
  stable/7/include/pthread_np.h
  stable/7/lib/libc/gen/Symbol.map
  stable/7/lib/libc/gen/dlfcn.c
  stable/7/lib/libc/include/libc_private.h
  stable/7/lib/libc/stdlib/Symbol.map
  stable/7/lib/libc/stdlib/malloc.c
  stable/7/lib/libthr/Makefile
  stable/7/lib/libthr/arch/amd64/include/pthread_md.h
  stable/7/lib/libthr/arch/i386/Makefile.inc
  stable/7/lib/libthr/pthread.map
  stable/7/lib/libthr/thread/Makefile.inc
  stable/7/lib/libthr/thread/thr_attr.c
  stable/7/lib/libthr/thread/thr_clean.c
  stable/7/lib/libthr/thread/thr_create.c
  stable/7/lib/libthr/thread/thr_event.c
  stable/7/lib/libthr/thread/thr_exit.c
  stable/7/lib/libthr/thread/thr_fork.c
  stable/7/lib/libthr/thread/thr_init.c
  stable/7/lib/libthr/thread/thr_mutex.c
  stable/7/lib/libthr/thread/thr_once.c
  stable/7/lib/libthr/thread/thr_private.h
  stable/7/lib/libthr/thread/thr_pspinlock.c
  stable/7/lib/libthr/thread/thr_resume_np.c
  stable/7/lib/libthr/thread/thr_rtld.c
  stable/7/lib/libthr/thread/thr_sem.c
  stable/7/lib/libthr/thread/thr_sig.c
  stable/7/lib/libthr/thread/thr_spinlock.c
  stable/7/lib/libthr/thread/thr_suspend_np.c
  stable/7/lib/libthr/thread/thr_syscalls.c
  stable/7/lib/libthr/thread/thr_umtx.c
  stable/7/lib/libthr/thread/thr_umtx.h
  stable/7/libexec/rtld-elf/Symbol.map
  stable/7/libexec/rtld-elf/rtld.c
  stable/7/libexec/rtld-elf/rtld_lock.c
  stable/7/libexec/rtld-elf/rtld_lock.h
  stable/7/sys/kern/kern_thr.c
  stable/7/sys/kern/kern_umtx.c
  stable/7/sys/sys/umtx.h

Modified: stable/7/include/pthread.h
==============================================================================
--- stable/7/include/pthread.h	Tue Mar 24 20:46:02 2009	(r190392)
+++ stable/7/include/pthread.h	Tue Mar 24 20:57:10 2009	(r190393)
@@ -135,6 +135,10 @@ enum pthread_mutextype {
 
 #define PTHREAD_MUTEX_DEFAULT		PTHREAD_MUTEX_ERRORCHECK
 
+struct _pthread_cleanup_info {
+	__uintptr_t	pthread_cleanup_pad[8];
+};
+
 /*
  * Thread function prototype definitions:
  */
@@ -185,6 +189,7 @@ int		pthread_detach(pthread_t);
 int		pthread_equal(pthread_t, pthread_t);
 void		pthread_exit(void *) __dead2;
 void		*pthread_getspecific(pthread_key_t);
+int		pthread_getcpuclockid(pthread_t, clockid_t *);
 int		pthread_join(pthread_t, void **);
 int		pthread_key_create(pthread_key_t *,
 			void (*) (void *));
@@ -267,6 +272,10 @@ int		pthread_setschedparam(pthread_t, in
 			const struct sched_param *);
 int		pthread_getconcurrency(void);
 int		pthread_setconcurrency(int);
+
+void		__pthread_cleanup_push_imp(void (*)(void *), void *,
+			struct _pthread_cleanup_info *);
+void		__pthread_cleanup_pop_imp(int);
 __END_DECLS
 
 #endif

Modified: stable/7/include/pthread_np.h
==============================================================================
--- stable/7/include/pthread_np.h	Tue Mar 24 20:46:02 2009	(r190392)
+++ stable/7/include/pthread_np.h	Tue Mar 24 20:57:10 2009	(r190393)
@@ -10,10 +10,7 @@
  * 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.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by John Birrell.
- * 4. Neither the name of the author nor the names of any co-contributors
+ * 3. Neither the name of the author nor the names of any co-contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  *
@@ -34,6 +31,9 @@
 #ifndef _PTHREAD_NP_H_
 #define _PTHREAD_NP_H_
 
+#include <sys/param.h>
+#include <sys/cpuset.h>
+
 /*
  * Non-POSIX type definitions:
  */
@@ -45,6 +45,9 @@ typedef void	(*pthread_switch_routine_t)
 __BEGIN_DECLS
 int pthread_attr_setcreatesuspend_np(pthread_attr_t *);
 int pthread_attr_get_np(pthread_t, pthread_attr_t *);
+int pthread_attr_getaffinity_np(const pthread_attr_t *, size_t, cpuset_t *);
+int pthread_attr_setaffinity_np(pthread_attr_t *, size_t, const cpuset_t *);
+int pthread_getaffinity_np(pthread_t, size_t, cpuset_t *);
 int pthread_main_np(void);
 int pthread_multi_np(void);
 int pthread_mutexattr_getkind_np(pthread_mutexattr_t);
@@ -52,6 +55,12 @@ int pthread_mutexattr_setkind_np(pthread
 void pthread_resume_all_np(void);
 int pthread_resume_np(pthread_t);
 void pthread_set_name_np(pthread_t, const char *);
+int pthread_mutex_getspinloops_np(pthread_mutex_t *mutex, int *count);
+int pthread_mutex_setspinloops_np(pthread_mutex_t *mutex, int count);
+int pthread_mutex_getyieldloops_np(pthread_mutex_t *mutex, int *count);
+int pthread_mutex_setyieldloops_np(pthread_mutex_t *mutex, int count);
+int pthread_mutex_isowned_np(pthread_mutex_t *mutex);
+int pthread_setaffinity_np(pthread_t, size_t, const cpuset_t *);
 int pthread_single_np(void);
 void pthread_suspend_all_np(void);
 int pthread_suspend_np(pthread_t);

Modified: stable/7/lib/libc/gen/Symbol.map
==============================================================================
--- stable/7/lib/libc/gen/Symbol.map	Tue Mar 24 20:46:02 2009	(r190392)
+++ stable/7/lib/libc/gen/Symbol.map	Tue Mar 24 20:57:10 2009	(r190393)
@@ -403,6 +403,8 @@ FBSDprivate_1.0 {
 	_spinlock;
 	_spinlock_debug;
 	_spinunlock;
+	_rtld_atfork_pre;
+	_rtld_atfork_post;
 	_rtld_error;		/* for private use */
 	_rtld_thread_init;	/* for private use */
 	_err;

Modified: stable/7/lib/libc/gen/dlfcn.c
==============================================================================
--- stable/7/lib/libc/gen/dlfcn.c	Tue Mar 24 20:46:02 2009	(r190392)
+++ stable/7/lib/libc/gen/dlfcn.c	Tue Mar 24 20:57:10 2009	(r190393)
@@ -137,3 +137,15 @@ dl_iterate_phdr(int (*callback)(struct d
 	_rtld_error(sorry);
 	return 0;
 }
+
+#pragma weak _rtld_atfork_pre
+void
+_rtld_atfork_pre(int *locks)
+{
+}
+
+#pragma weak _rtld_atfork_post
+void
+_rtld_atfork_post(int *locks)
+{
+}

Modified: stable/7/lib/libc/include/libc_private.h
==============================================================================
--- stable/7/lib/libc/include/libc_private.h	Tue Mar 24 20:46:02 2009	(r190392)
+++ stable/7/lib/libc/include/libc_private.h	Tue Mar 24 20:57:10 2009	(r190393)
@@ -158,6 +158,12 @@ void _set_tp(void *tp);
 extern const char *__progname;
 
 /*
+ * This function is used by the threading libraries to notify malloc that a
+ * thread is exiting.
+ */
+void _malloc_thread_cleanup(void);
+
+/*
  * These functions are used by the threading libraries in order to protect
  * malloc across fork().
  */

Modified: stable/7/lib/libc/stdlib/Symbol.map
==============================================================================
--- stable/7/lib/libc/stdlib/Symbol.map	Tue Mar 24 20:46:02 2009	(r190392)
+++ stable/7/lib/libc/stdlib/Symbol.map	Tue Mar 24 20:57:10 2009	(r190393)
@@ -95,6 +95,7 @@ FBSD_1.0 {
 
 FBSDprivate_1.0 {
 	__use_pts;
+	_malloc_thread_cleanup;
 	_malloc_prefork;
 	_malloc_postfork;
 	__system;

Modified: stable/7/lib/libc/stdlib/malloc.c
==============================================================================
--- stable/7/lib/libc/stdlib/malloc.c	Tue Mar 24 20:46:02 2009	(r190392)
+++ stable/7/lib/libc/stdlib/malloc.c	Tue Mar 24 20:57:10 2009	(r190393)
@@ -4693,6 +4693,17 @@ malloc_usable_size(const void *ptr)
 /*
  * End non-standard functions.
  */
+
+/*
+ * We provide an unpublished interface in order to receive notifications from
+ * the pthreads library whenever a thread exits.  This allows us to clean up
+ * thread caches.
+ */
+void
+_malloc_thread_cleanup(void)
+{
+}
+
 /******************************************************************************/
 /*
  * Begin library-private functions, used by threading libraries for protection

Modified: stable/7/lib/libthr/Makefile
==============================================================================
--- stable/7/lib/libthr/Makefile	Tue Mar 24 20:46:02 2009	(r190392)
+++ stable/7/lib/libthr/Makefile	Tue Mar 24 20:57:10 2009	(r190393)
@@ -9,6 +9,7 @@
 # system call stubs.
 
 .include <bsd.own.mk>
+MK_SSP=	no
 
 .if (${DEFAULT_THREAD_LIB} == "libthr" || ${MK_LIBKSE} == "no") && \
     ${SHLIBDIR} == "/usr/lib"
@@ -17,7 +18,7 @@ SHLIBDIR= /lib
 
 LIB=thr
 SHLIB_MAJOR= 3
-WARNS?= 2
+WARNS?=	3
 CFLAGS+=-DPTHREAD_KERNEL
 CFLAGS+=-I${.CURDIR}/../libc/include -I${.CURDIR}/thread \
 	-I${.CURDIR}/../../include
@@ -28,9 +29,8 @@ CFLAGS+=-I${.CURDIR}/../../libexec/rtld-
 CFLAGS+=-I${.CURDIR}/../libthread_db
 CFLAGS+=-Winline
 
-# CFLAGS+=-DSYSTEM_SCOPE_ONLY
-
-VERSION_MAP=${.CURDIR}/pthread.map
+VERSION_DEF=${.CURDIR}/../libc/Versions.def
+SYMBOL_MAPS=${.CURDIR}/pthread.map
 
 MAN=	libthr.3
 
@@ -54,4 +54,8 @@ SYMLINKS+=lib${LIB}_p.a ${LIBDIR}/libpth
 .endif
 .endif
 
+.if !defined(WITHOUT_SYSCALL_COMPAT)
+CFLAGS+=-DSYSCALL_COMPAT
+.endif
+
 .include <bsd.lib.mk>

Modified: stable/7/lib/libthr/arch/amd64/include/pthread_md.h
==============================================================================
--- stable/7/lib/libthr/arch/amd64/include/pthread_md.h	Tue Mar 24 20:46:02 2009	(r190392)
+++ stable/7/lib/libthr/arch/amd64/include/pthread_md.h	Tue Mar 24 20:57:10 2009	(r190393)
@@ -98,6 +98,6 @@ _get_curthread(void)
 	return (TCB_GET64(tcb_thread));
 }
 
-#define HAS__UMTX_OP_ERR	1
+#define	HAS__UMTX_OP_ERR	1
 
 #endif

Modified: stable/7/lib/libthr/arch/i386/Makefile.inc
==============================================================================
--- stable/7/lib/libthr/arch/i386/Makefile.inc	Tue Mar 24 20:46:02 2009	(r190392)
+++ stable/7/lib/libthr/arch/i386/Makefile.inc	Tue Mar 24 20:57:10 2009	(r190393)
@@ -2,4 +2,4 @@
 
 .PATH: ${.CURDIR}/arch/${MACHINE_ARCH}/${MACHINE_ARCH}
 
-SRCS+=	pthread_md.c  _umtx_op_err.S
+SRCS+=	pthread_md.c _umtx_op_err.S

Modified: stable/7/lib/libthr/pthread.map
==============================================================================
--- stable/7/lib/libthr/pthread.map	Tue Mar 24 20:46:02 2009	(r190392)
+++ stable/7/lib/libthr/pthread.map	Tue Mar 24 20:57:10 2009	(r190393)
@@ -6,7 +6,6 @@
  * Use the same naming scheme as libc.
  */
 FBSD_1.0 {
-global:
 	__error;
 	accept;
 	aio_suspend;
@@ -118,8 +117,8 @@ global:
 	pthread_rwlockattr_getpshared;
 	pthread_rwlockattr_init;
 	pthread_rwlockattr_setpshared;
-	pthread_self;
 	pthread_set_name_np;
+	pthread_self;
 	pthread_setcancelstate;
 	pthread_setcanceltype;
 	pthread_setconcurrency;
@@ -165,15 +164,12 @@ global:
 	system;
 	tcdrain;
 	usleep;
-	vfork;
 	wait;
 	wait3;
 	wait4;
 	waitpid;
 	write;
 	writev;
-local:
-	*;
 };
 
 /*
@@ -181,7 +177,6 @@ local:
  * These are not part of our application ABI.
  */
 FBSDprivate_1.0 {
-global:
 	___creat;
 	___pause;
 	___pselect;
@@ -233,6 +228,7 @@ global:
 	_pthread_barrierattr_setpshared;
 	_pthread_attr_destroy;
 	_pthread_attr_get_np;
+	_pthread_attr_getaffinity_np;
 	_pthread_attr_getdetachstate;
 	_pthread_attr_getguardsize;
 	_pthread_attr_getinheritsched;
@@ -243,6 +239,7 @@ global:
 	_pthread_attr_getstackaddr;
 	_pthread_attr_getstacksize;
 	_pthread_attr_init;
+	_pthread_attr_setaffinity_np;
 	_pthread_attr_setcreatesuspend_np;
 	_pthread_attr_setdetachstate;
 	_pthread_attr_setguardsize;
@@ -272,7 +269,9 @@ global:
 	_pthread_detach;
 	_pthread_equal;
 	_pthread_exit;
+	_pthread_getaffinity_np;
 	_pthread_getconcurrency;
+	_pthread_getcpuclockid;
 	_pthread_getprio;
 	_pthread_getschedparam;
 	_pthread_getspecific;
@@ -284,10 +283,15 @@ global:
 	_pthread_multi_np;
 	_pthread_mutex_destroy;
 	_pthread_mutex_getprioceiling;
+	_pthread_mutex_getspinloops_np;
+	_pthread_mutex_getyieldloops_np;
 	_pthread_mutex_init;
 	_pthread_mutex_init_calloc_cb;
+	_pthread_mutex_isowned_np;
 	_pthread_mutex_lock;
 	_pthread_mutex_setprioceiling;
+	_pthread_mutex_setspinloops_np;
+	_pthread_mutex_setyieldloops_np;
 	_pthread_mutex_timedlock;
 	_pthread_mutex_trylock;
 	_pthread_mutex_unlock;
@@ -321,6 +325,7 @@ global:
 	_pthread_rwlockattr_setpshared;
 	_pthread_self;
 	_pthread_set_name_np;
+	_pthread_setaffinity_np;
 	_pthread_setcancelstate;
 	_pthread_setcanceltype;
 	_pthread_setconcurrency;
@@ -358,7 +363,6 @@ global:
 	_spinlock;
 	_spinlock_debug;
 	_spinunlock;
-	_vfork;
 
 	/* Debugger needs these. */
 	_libthr_debug;
@@ -386,6 +390,19 @@ global:
 	_thread_size_key;
 	_thread_state_running;
 	_thread_state_zoombie;
-local:
-	*;
+};
+
+FBSD_1.1 {
+	__pthread_cleanup_pop_imp;
+	__pthread_cleanup_push_imp;
+	pthread_attr_getaffinity_np;
+	pthread_attr_setaffinity_np;
+	pthread_getaffinity_np;
+	pthread_getcpuclockid;
+	pthread_setaffinity_np;
+	pthread_mutex_getspinloops_np;
+	pthread_mutex_getyieldloops_np;
+	pthread_mutex_isowned_np;
+	pthread_mutex_setspinloops_np;
+	pthread_mutex_setyieldloops_np;
 };

Modified: stable/7/lib/libthr/thread/Makefile.inc
==============================================================================
--- stable/7/lib/libthr/thread/Makefile.inc	Tue Mar 24 20:46:02 2009	(r190392)
+++ stable/7/lib/libthr/thread/Makefile.inc	Tue Mar 24 20:57:10 2009	(r190393)
@@ -4,6 +4,7 @@
 .PATH: ${.CURDIR}/thread
 
 SRCS+= \
+	thr_affinity.c \
 	thr_attr.c \
 	thr_barrier.c \
 	thr_barrierattr.c \
@@ -19,6 +20,7 @@ SRCS+= \
 	thr_exit.c \
 	thr_fork.c \
 	thr_getprio.c \
+	thr_getcpuclockid.c \
 	thr_getschedparam.c \
 	thr_info.c \
 	thr_init.c \

Added: stable/7/lib/libthr/thread/thr_affinity.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ stable/7/lib/libthr/thread/thr_affinity.c	Tue Mar 24 20:57:10 2009	(r190393)
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2008, David Xu <davidxu at freebsd.org>
+ * All rights reserved.
+ *
+ * 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 unmodified, 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 AUTHOR ``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 AUTHOR 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.
+ *
+ * $FreeBSD$
+ *
+ */
+
+#include "namespace.h"
+#include <pthread_np.h>
+#include <sys/param.h>
+#include <sys/cpuset.h>
+#include "un-namespace.h"
+
+#include "thr_private.h"
+
+__weak_reference(_pthread_getaffinity_np, pthread_getaffinity_np);
+__weak_reference(_pthread_setaffinity_np, pthread_setaffinity_np);
+
+int
+_pthread_setaffinity_np(pthread_t td, size_t cpusetsize, const cpuset_t *cpusetp)
+{
+	struct pthread	*curthread = _get_curthread();
+	lwpid_t		tid;
+	int		error;
+
+	if (td == curthread) {
+		error = cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_TID,
+			-1, cpusetsize, cpusetp);
+		if (error == -1)
+			error = errno;
+	} else {
+		THR_THREAD_LOCK(curthread, td);
+		if (td->state == PS_DEAD) {
+			THR_THREAD_UNLOCK(curthread, td);
+			return (EINVAL);
+		}
+		tid = TID(td);
+		error = cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_TID, tid,
+			cpusetsize, cpusetp);
+		if (error == -1)
+			error = errno;
+		THR_THREAD_UNLOCK(curthread, td);
+	}
+	return (error);
+}
+
+int
+_pthread_getaffinity_np(pthread_t td, size_t cpusetsize, cpuset_t *cpusetp)
+{
+	struct pthread	*curthread = _get_curthread();
+	lwpid_t tid;
+	int error;
+
+	tid = TID(td);
+	error = cpuset_getaffinity(CPU_LEVEL_WHICH, CPU_WHICH_TID,
+		(td == curthread) ? -1 : tid, cpusetsize, cpusetp);
+	if (error == -1)
+		error = errno;
+	return (error);
+}

Modified: stable/7/lib/libthr/thread/thr_attr.c
==============================================================================
--- stable/7/lib/libthr/thread/thr_attr.c	Tue Mar 24 20:46:02 2009	(r190392)
+++ stable/7/lib/libthr/thread/thr_attr.c	Tue Mar 24 20:57:10 2009	(r190393)
@@ -99,6 +99,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <pthread_np.h>
+#include <sys/sysctl.h>
 #include "un-namespace.h"
 
 #include "thr_private.h"
@@ -148,7 +149,9 @@ _pthread_attr_get_np(pthread_t pid, pthr
 		attr.flags |= PTHREAD_DETACHED;
 	_thr_ref_delete(curthread, pid);
 	memcpy(*dst, &attr, sizeof(struct pthread_attr));
-
+	/* XXX */
+	(*dst)->cpuset = NULL;
+	(*dst)->cpusetsize = 0;
 	return (0);
 }
 
@@ -543,3 +546,92 @@ _pthread_attr_setstacksize(pthread_attr_
 	}
 	return(ret);
 }
+
+static size_t
+_get_kern_cpuset_size(void)
+{
+	static int kern_cpuset_size = 0;
+
+	if (kern_cpuset_size == 0) {
+		size_t len;
+
+		len = sizeof(kern_cpuset_size);
+		if (sysctlbyname("kern.smp.maxcpus", &kern_cpuset_size,
+		    &len, NULL, 0))
+			PANIC("failed to get sysctl kern.smp.maxcpus");
+
+		kern_cpuset_size = (kern_cpuset_size + 7) / 8;
+	}
+
+	return (kern_cpuset_size);
+}
+
+__weak_reference(_pthread_attr_setaffinity_np, pthread_attr_setaffinity_np);
+int
+_pthread_attr_setaffinity_np(pthread_attr_t *pattr, size_t cpusetsize,
+	const cpuset_t *cpusetp)
+{
+	pthread_attr_t attr;
+	int ret;
+
+	if (pattr == NULL || (attr = (*pattr)) == NULL)
+		ret = EINVAL;
+	else {
+		if (cpusetsize == 0 || cpusetp == NULL) {
+			if (attr->cpuset != NULL) {
+				free(attr->cpuset);
+				attr->cpuset = NULL;
+				attr->cpusetsize = 0;
+			}
+			return (0);
+		}
+			
+		if (cpusetsize > attr->cpusetsize) {
+			size_t kern_size = _get_kern_cpuset_size();
+			if (cpusetsize > kern_size) {
+				size_t i;
+				for (i = kern_size; i < cpusetsize; ++i) {
+					if (((char *)cpusetp)[i])
+						return (EINVAL);
+				}
+			}
+			void *newset = realloc(attr->cpuset, cpusetsize);
+       			if (newset == NULL)
+		            return (ENOMEM);
+			attr->cpuset = newset;
+			attr->cpusetsize = cpusetsize;
+		} else {
+			memset(((char *)attr->cpuset) + cpusetsize, 0,
+				attr->cpusetsize - cpusetsize);
+			attr->cpusetsize = cpusetsize;
+		}
+		memcpy(attr->cpuset, cpusetp, cpusetsize);
+		ret = 0;
+	}
+	return (ret);
+}
+
+__weak_reference(_pthread_attr_getaffinity_np, pthread_attr_getaffinity_np);
+int
+_pthread_attr_getaffinity_np(const pthread_attr_t *pattr, size_t cpusetsize,
+	cpuset_t *cpusetp)
+{
+	pthread_attr_t attr;
+	int ret = 0;
+
+	if (pattr == NULL || (attr = (*pattr)) == NULL)
+		ret = EINVAL;
+	else if (attr->cpuset != NULL) {
+		memcpy(cpusetp, attr->cpuset, MIN(cpusetsize, attr->cpusetsize));
+		if (cpusetsize > attr->cpusetsize)
+			memset(((char *)cpusetp) + attr->cpusetsize, 0, 
+				cpusetsize - attr->cpusetsize);
+	} else {
+		size_t kern_size = _get_kern_cpuset_size();
+		memset(cpusetp, -1, MIN(cpusetsize, kern_size));
+		if (cpusetsize > kern_size)
+			memset(((char *)cpusetp) + kern_size, 0,
+				cpusetsize - kern_size);
+	}
+	return (ret);
+}

Modified: stable/7/lib/libthr/thread/thr_clean.c
==============================================================================
--- stable/7/lib/libthr/thread/thr_clean.c	Tue Mar 24 20:46:02 2009	(r190392)
+++ stable/7/lib/libthr/thread/thr_clean.c	Tue Mar 24 20:57:10 2009	(r190393)
@@ -38,38 +38,61 @@
 
 #include "thr_private.h"
 
+#undef pthread_cleanup_push
+#undef pthread_cleanup_pop
+
+/* old binary compatible interfaces */
 __weak_reference(_pthread_cleanup_push, pthread_cleanup_push);
 __weak_reference(_pthread_cleanup_pop, pthread_cleanup_pop);
 
 void
-_pthread_cleanup_push(void (*routine) (void *), void *routine_arg)
+__pthread_cleanup_push_imp(void (*routine)(void *), void *arg,
+	struct _pthread_cleanup_info *info)
 {
 	struct pthread	*curthread = _get_curthread();
-	struct pthread_cleanup *new;
-
-	if ((new = (struct pthread_cleanup *)
-	    malloc(sizeof(struct pthread_cleanup))) != NULL) {
-		new->routine = routine;
-		new->routine_arg = routine_arg;
-		new->onstack = 0;
-		new->next = curthread->cleanup;
+	struct pthread_cleanup *newbuf;
 
-		curthread->cleanup = new;
-	}
+	newbuf = (void *)info;
+	newbuf->routine = routine;
+	newbuf->routine_arg = arg;
+	newbuf->onheap = 0;
+	newbuf->prev = curthread->cleanup;
+	curthread->cleanup = newbuf;
 }
 
 void
-_pthread_cleanup_pop(int execute)
+__pthread_cleanup_pop_imp(int execute)
 {
 	struct pthread	*curthread = _get_curthread();
 	struct pthread_cleanup *old;
 
 	if ((old = curthread->cleanup) != NULL) {
-		curthread->cleanup = old->next;
-		if (execute) {
+		curthread->cleanup = old->prev;
+		if (execute)
 			old->routine(old->routine_arg);
-		}
-		if (old->onstack == 0)
+		if (old->onheap)
 			free(old);
 	}
 }
+
+void
+_pthread_cleanup_push(void (*routine) (void *), void *arg)
+{
+	struct pthread	*curthread = _get_curthread();
+	struct pthread_cleanup *newbuf;
+
+	if ((newbuf = (struct pthread_cleanup *)
+	    malloc(sizeof(struct _pthread_cleanup_info))) != NULL) {
+		newbuf->routine = routine;
+		newbuf->routine_arg = arg;
+		newbuf->onheap = 1;
+		newbuf->prev = curthread->cleanup;
+		curthread->cleanup = newbuf;
+	}
+}
+
+void
+_pthread_cleanup_pop(int execute)
+{
+	__pthread_cleanup_pop_imp(execute);
+}

Modified: stable/7/lib/libthr/thread/thr_create.c
==============================================================================
--- stable/7/lib/libthr/thread/thr_create.c	Tue Mar 24 20:46:02 2009	(r190392)
+++ stable/7/lib/libthr/thread/thr_create.c	Tue Mar 24 20:57:10 2009	(r190393)
@@ -36,6 +36,7 @@
 #include <string.h>
 #include <stddef.h>
 #include <pthread.h>
+#include <pthread_np.h>
 #include "un-namespace.h"
 
 #include "thr_private.h"
@@ -55,6 +56,8 @@ _pthread_create(pthread_t * thread, cons
 	struct rtprio rtp;
 	int ret = 0, locked, create_suspended;
 	sigset_t set, oset;
+	cpuset_t *cpusetp = NULL;
+	int cpusetsize = 0;
 
 	_thr_check_init();
 
@@ -73,8 +76,13 @@ _pthread_create(pthread_t * thread, cons
 	if (attr == NULL || *attr == NULL)
 		/* Use the default thread attributes: */
 		new_thread->attr = _pthread_attr_default;
-	else
+	else {
 		new_thread->attr = *(*attr);
+		cpusetp = new_thread->attr.cpuset;
+		cpusetsize = new_thread->attr.cpusetsize;
+		new_thread->attr.cpuset = NULL;
+		new_thread->attr.cpusetsize = 0;
+	}
 	if (new_thread->attr.sched_inherit == PTHREAD_INHERIT_SCHED) {
 		/* inherit scheduling contention scope */
 		if (curthread->attr.flags & PTHREAD_SCOPE_SYSTEM)
@@ -129,7 +137,7 @@ _pthread_create(pthread_t * thread, cons
 	_thr_link(curthread, new_thread);
 	/* Return thread pointer eariler so that new thread can use it. */
 	(*thread) = new_thread;
-	if (SHOULD_REPORT_EVENT(curthread, TD_CREATE)) {
+	if (SHOULD_REPORT_EVENT(curthread, TD_CREATE) || cpusetp != NULL) {
 		THR_THREAD_LOCK(curthread, new_thread);
 		locked = 1;
 	} else
@@ -147,7 +155,7 @@ _pthread_create(pthread_t * thread, cons
 		param.flags |= THR_SYSTEM_SCOPE;
 	if (new_thread->attr.sched_inherit == PTHREAD_INHERIT_SCHED)
 		param.rtp = NULL;
-	else {
+	else { 	 
 		sched_param.sched_priority = new_thread->attr.prio;
 		_schedparam_to_rtp(new_thread->attr.sched_policy,
 			&sched_param, &rtp);
@@ -160,6 +168,7 @@ _pthread_create(pthread_t * thread, cons
 		SIGDELSET(set, SIGTRAP);
 		__sys_sigprocmask(SIG_SETMASK, &set, &oset);
 		new_thread->sigmask = oset;
+		SIGDELSET(new_thread->sigmask, SIGCANCEL);
 	}
 
 	ret = thr_new(&param, sizeof(param));
@@ -183,7 +192,7 @@ _pthread_create(pthread_t * thread, cons
 		new_thread->tid = TID_TERMINATED;
 		if (new_thread->flags & THR_FLAGS_NEED_SUSPEND) {
 			new_thread->cycle++;
-			_thr_umtx_wake(&new_thread->cycle, INT_MAX);
+			_thr_umtx_wake(&new_thread->cycle, INT_MAX, 0);
 		}
 		THR_THREAD_UNLOCK(curthread, new_thread);
 		THREAD_LIST_LOCK(curthread);
@@ -191,11 +200,31 @@ _pthread_create(pthread_t * thread, cons
 		new_thread->tlflags |= TLFLAGS_DETACHED;
 		_thr_ref_delete_unlocked(curthread, new_thread);
 		THREAD_LIST_UNLOCK(curthread);
-		(*thread) = 0;
 	} else if (locked) {
+		if (cpusetp != NULL) {
+			if (cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_TID,
+				TID(new_thread), cpusetsize, cpusetp)) {
+				ret = errno;
+				/* kill the new thread */
+				new_thread->force_exit = 1;
+				THR_THREAD_UNLOCK(curthread, new_thread);
+				goto out;
+			}
+		}
+
 		_thr_report_creation(curthread, new_thread);
 		THR_THREAD_UNLOCK(curthread, new_thread);
+out:
+		if (ret) {
+			THREAD_LIST_LOCK(curthread);
+			new_thread->tlflags |= TLFLAGS_DETACHED;
+			THR_GCLIST_ADD(new_thread);
+			THREAD_LIST_UNLOCK(curthread);
+		}
 	}
+
+	if (ret)
+		(*thread) = 0;
 	return (ret);
 }
 
@@ -231,6 +260,9 @@ thread_start(struct pthread *curthread)
 	THR_LOCK(curthread);
 	THR_UNLOCK(curthread);
 
+	if (curthread->force_exit)
+		_pthread_exit(PTHREAD_CANCELED);
+
 	if (curthread->unblock_sigcancel) {
 		sigset_t set1;
 

Modified: stable/7/lib/libthr/thread/thr_event.c
==============================================================================
--- stable/7/lib/libthr/thread/thr_event.c	Tue Mar 24 20:46:02 2009	(r190392)
+++ stable/7/lib/libthr/thread/thr_event.c	Tue Mar 24 20:57:10 2009	(r190393)
@@ -42,7 +42,7 @@ void
 _thr_report_creation(struct pthread *curthread, struct pthread *newthread)
 {
 	curthread->event_buf.event = TD_CREATE;
-	curthread->event_buf.th_p = (td_thrhandle_t *)newthread;
+	curthread->event_buf.th_p = (uintptr_t)newthread;
 	curthread->event_buf.data = 0;
 	THR_UMUTEX_LOCK(curthread, &_thr_event_lock);
 	_thread_last_event = curthread;
@@ -55,7 +55,7 @@ void
 _thr_report_death(struct pthread *curthread)
 {
 	curthread->event_buf.event = TD_DEATH;
-	curthread->event_buf.th_p = (td_thrhandle_t *)curthread;
+	curthread->event_buf.th_p = (uintptr_t)curthread;
 	curthread->event_buf.data = 0;
 	THR_UMUTEX_LOCK(curthread, &_thr_event_lock);
 	_thread_last_event = curthread;

Modified: stable/7/lib/libthr/thread/thr_exit.c
==============================================================================
--- stable/7/lib/libthr/thread/thr_exit.c	Tue Mar 24 20:46:02 2009	(r190392)
+++ stable/7/lib/libthr/thread/thr_exit.c	Tue Mar 24 20:57:10 2009	(r190393)
@@ -29,11 +29,14 @@
  * $FreeBSD$
  */
 
+#include "namespace.h"
 #include <errno.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <pthread.h>
+#include "un-namespace.h"
 
+#include "libc_private.h"
 #include "thr_private.h"
 
 void	_pthread_exit(void *status);
@@ -60,22 +63,6 @@ _thread_exit(const char *fname, int line
 void
 _thr_exit_cleanup(void)
 {
-	struct pthread	*curthread = _get_curthread();
-
-	/*
-	 * POSIX states that cancellation/termination of a thread should
-	 * not release any visible resources (such as mutexes) and that
-	 * it is the applications responsibility.  Resources that are
-	 * internal to the threads library, including file and fd locks,
-	 * are not visible to the application and need to be released.
-	 */
-	/* Unlock all private mutexes: */
-	_mutex_unlock_private(curthread);
-
-	/*
-	 * This still isn't quite correct because we don't account
-	 * for held spinlocks (see libc/stdlib/malloc.c).
-	 */
 }
 
 void
@@ -100,7 +87,7 @@ _pthread_exit(void *status)
 	/* Save the return value: */
 	curthread->ret = status;
 	while (curthread->cleanup != NULL) {
-		pthread_cleanup_pop(1);
+		_pthread_cleanup_pop(1);
 	}
 
 	/* Check if there is thread specific data: */
@@ -119,8 +106,18 @@ _pthread_exit(void *status)
 		exit(0);
 		/* Never reach! */
 	}
+	THREAD_LIST_UNLOCK(curthread);
+
+	/* Tell malloc that the thread is exiting. */
+	_malloc_thread_cleanup();
+
+	THREAD_LIST_LOCK(curthread);
 	THR_LOCK(curthread);
 	curthread->state = PS_DEAD;
+	if (curthread->flags & THR_FLAGS_NEED_SUSPEND) {
+		curthread->cycle++;
+		_thr_umtx_wake(&curthread->cycle, INT_MAX, 0);
+	}
 	THR_UNLOCK(curthread);
 	/*
 	 * Thread was created with initial refcount 1, we drop the
@@ -130,7 +127,7 @@ _pthread_exit(void *status)
 	if (curthread->tlflags & TLFLAGS_DETACHED)
 		THR_GCLIST_ADD(curthread);
 	THREAD_LIST_UNLOCK(curthread);
-	if (SHOULD_REPORT_EVENT(curthread, TD_DEATH))
+	if (!curthread->force_exit && SHOULD_REPORT_EVENT(curthread, TD_DEATH))
 		_thr_report_death(curthread);
 
 	/*

Modified: stable/7/lib/libthr/thread/thr_fork.c
==============================================================================
--- stable/7/lib/libthr/thread/thr_fork.c	Tue Mar 24 20:46:02 2009	(r190392)
+++ stable/7/lib/libthr/thread/thr_fork.c	Tue Mar 24 20:57:10 2009	(r190393)
@@ -67,6 +67,7 @@
 #include "un-namespace.h"
 
 #include "libc_private.h"
+#include "rtld_lock.h"
 #include "thr_private.h"
 
 __weak_reference(_pthread_atfork, pthread_atfork);
@@ -105,6 +106,7 @@ _fork(void)
 	pid_t ret;
 	int errsave;
 	int unlock_malloc;
+	int rtld_locks[MAX_RTLD_LOCKS];
 
 	if (!_thr_is_inited())
 		return (__sys_fork());
@@ -127,6 +129,7 @@ _fork(void)
 	if (_thr_isthreaded() != 0) {
 		unlock_malloc = 1;
 		_malloc_prefork();
+		_rtld_atfork_pre(rtld_locks);
 	} else {
 		unlock_malloc = 0;
 	}
@@ -155,6 +158,9 @@ _fork(void)
 		/* clear other threads locked us. */
 		_thr_umutex_init(&curthread->lock);
 		_thr_umutex_init(&_thr_atfork_lock);
+
+		if (unlock_malloc)
+			_rtld_atfork_post(rtld_locks);
 		_thr_setthreaded(0);
 
 		/* reinitialize libc spinlocks. */
@@ -167,6 +173,12 @@ _fork(void)
 		/* Ready to continue, unblock signals. */ 
 		_thr_signal_unblock(curthread);
 
+		if (unlock_malloc) {
+			__isthreaded = 1;
+			_malloc_postfork();
+			__isthreaded = 0;
+		}
+
 		/* Run down atfork child handlers. */
 		TAILQ_FOREACH(af, &_thr_atfork_list, qe) {
 			if (af->child != NULL)
@@ -179,8 +191,10 @@ _fork(void)
 		/* Ready to continue, unblock signals. */ 
 		_thr_signal_unblock(curthread);
 
-		if (unlock_malloc)
+		if (unlock_malloc) {
+			_rtld_atfork_post(rtld_locks);
 			_malloc_postfork();
+		}
 
 		/* Run down atfork parent handlers. */
 		TAILQ_FOREACH(af, &_thr_atfork_list, qe) {

Added: stable/7/lib/libthr/thread/thr_getcpuclockid.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ stable/7/lib/libthr/thread/thr_getcpuclockid.c	Tue Mar 24 20:57:10 2009	(r190393)
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2008 David Xu <davidxu at freebsd.org>
+ * All rights reserved.
+ *
+ * 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 JOHN BIRRELL 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 AUTHOR 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.
+ *
+ * $FreeBSD$
+ */
+
+#include "namespace.h"
+#include <errno.h>
+#include <pthread.h>
+#include <sys/time.h>
+#include "un-namespace.h"
+
+#include "thr_private.h"
+
+__weak_reference(_pthread_getcpuclockid, pthread_getcpuclockid);
+
+int
+_pthread_getcpuclockid(pthread_t pthread, clockid_t *clock_id)
+{
+	if (pthread == NULL)
+		return (EINVAL);
+
+	*clock_id = CLOCK_THREAD_CPUTIME_ID;
+	return (0);
+}

Modified: stable/7/lib/libthr/thread/thr_init.c
==============================================================================
--- stable/7/lib/libthr/thread/thr_init.c	Tue Mar 24 20:46:02 2009	(r190392)
+++ stable/7/lib/libthr/thread/thr_init.c	Tue Mar 24 20:57:10 2009	(r190393)
@@ -75,20 +75,21 @@ struct pthread_prio	_thr_priorities[3] =
 
 struct pthread_attr _pthread_attr_default = {
 	.sched_policy = SCHED_OTHER,
-	.sched_inherit = 0,
+	.sched_inherit = PTHREAD_INHERIT_SCHED,
 	.prio = 0,
 	.suspend = THR_CREATE_RUNNING,
 	.flags = PTHREAD_SCOPE_SYSTEM,
 	.stackaddr_attr = NULL,
 	.stacksize_attr = THR_STACK_DEFAULT,
-	.guardsize_attr = 0
+	.guardsize_attr = 0,
+	.cpusetsize = 0,
+	.cpuset = NULL
 };
 
 struct pthread_mutex_attr _pthread_mutexattr_default = {
 	.m_type = PTHREAD_MUTEX_DEFAULT,
 	.m_protocol = PTHREAD_PRIO_NONE,
-	.m_ceiling = 0,
-	.m_flags = 0
+	.m_ceiling = 0
 };
 
 /* Default condition variable attributes: */
@@ -158,7 +159,6 @@ STATIC_LIB_REQUIRE(_spinlock);
 STATIC_LIB_REQUIRE(_spinlock_debug);
 STATIC_LIB_REQUIRE(_spinunlock);
 STATIC_LIB_REQUIRE(_thread_init_hack);
-STATIC_LIB_REQUIRE(_vfork);
 
 /*
  * These are needed when linking statically.  All references within

Modified: stable/7/lib/libthr/thread/thr_mutex.c
==============================================================================
--- stable/7/lib/libthr/thread/thr_mutex.c	Tue Mar 24 20:46:02 2009	(r190392)
+++ stable/7/lib/libthr/thread/thr_mutex.c	Tue Mar 24 20:57:10 2009	(r190393)
@@ -40,6 +40,7 @@
 #include <sys/param.h>
 #include <sys/queue.h>
 #include <pthread.h>
+#include <pthread_np.h>
 #include "un-namespace.h"
 
 #include "thr_private.h"
@@ -50,12 +51,12 @@
 	(m)->m_qe.tqe_next = NULL;			\

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***


More information about the svn-src-all mailing list