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(¶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 <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