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 <davi...@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 <davi...@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 ***
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to