From owner-svn-src-stable@FreeBSD.ORG Tue Mar 24 20:57:11 2009 Return-Path: Delivered-To: svn-src-stable@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 64D501065674; Tue, 24 Mar 2009 20:57:11 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 4E94C8FC30; Tue, 24 Mar 2009 20:57:11 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id n2OKvBxX056722; Tue, 24 Mar 2009 20:57:11 GMT (envelope-from kib@svn.freebsd.org) Received: (from kib@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id n2OKvAFb056699; Tue, 24 Mar 2009 20:57:10 GMT (envelope-from kib@svn.freebsd.org) Message-Id: <200903242057.n2OKvAFb056699@svn.freebsd.org> From: Konstantin Belousov Date: Tue, 24 Mar 2009 20:57:10 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-7@freebsd.org X-SVN-Group: stable-7 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: 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... X-BeenThere: svn-src-stable@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for all the -stable branches of the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 24 Mar 2009 20:57:13 -0000 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 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 +#include + /* * 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 +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 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 + * 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 +#include +#include +#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 #include #include +#include #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 #include #include +#include #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(¶m, 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 #include #include #include +#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 + * 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 +#include +#include +#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 #include #include +#include #include "un-namespace.h" #include "thr_private.h" @@ -50,12 +51,12 @@ (m)->m_qe.tqe_next = NULL; \ *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***