pthread: Implement pthread_attr_{get,set}affinity_np
authorSepherosa Ziehau <sephe@dragonflybsd.org>
Sun, 15 Jan 2017 08:53:39 +0000 (16:53 +0800)
committerSepherosa Ziehau <sephe@dragonflybsd.org>
Sun, 15 Jan 2017 11:13:33 +0000 (19:13 +0800)
15 files changed:
include/pthread_np.h
lib/libc/gen/Symbol.map
lib/libc/gen/_pthread_stubs.c
lib/libc/include/namespace.h
lib/libc/include/un-namespace.h
lib/libc_r/uthread/Makefile.inc
lib/libc_r/uthread/uthread_attr_getaffinity_np.c [copied from include/pthread_np.h with 50% similarity]
lib/libc_r/uthread/uthread_attr_setaffinity_np.c [copied from include/pthread_np.h with 50% similarity]
lib/libpthread/Makefile
lib/libpthread/pthread_attr_setaffinity_np.3 [new file with mode: 0644]
lib/libthread_xu/pthread.map
lib/libthread_xu/thread/thr_attr.c
lib/libthread_xu/thread/thr_create.c
lib/libthread_xu/thread/thr_private.h
sys/sys/param.h

index d6753a5..354d211 100644 (file)
@@ -42,8 +42,10 @@ typedef void (*pthread_switch_routine_t)(pthread_t, pthread_t);
  * Non-POSIX thread function prototype definitions:
  */
 __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, cpu_set_t *);
+int pthread_attr_setaffinity_np(pthread_attr_t *, size_t, const cpu_set_t *);
+int pthread_attr_setcreatesuspend_np(pthread_attr_t *);
 int pthread_getaffinity_np(pthread_t, size_t, cpu_set_t *);
 int pthread_main_np(void);
 int pthread_multi_np(void);
index dff18d2..7b2cdde 100644 (file)
@@ -26,6 +26,7 @@ DF404.0 {
     pthread_atfork;
     pthread_attr_destroy;
     pthread_attr_get_np;
+    pthread_attr_getaffinity_np;
     pthread_attr_getdetachstate;
     pthread_attr_getguardsize;
     pthread_attr_getinheritsched;
@@ -36,6 +37,7 @@ DF404.0 {
     pthread_attr_getstackaddr;
     pthread_attr_getstacksize;
     pthread_attr_init;
+    pthread_attr_setaffinity_np;
     pthread_attr_setcreatesuspend_np;
     pthread_attr_setdetachstate;
     pthread_attr_setguardsize;
@@ -462,6 +464,7 @@ DFprivate_1.0 {
     _pthread_atfork;
     _pthread_attr_destroy;
     _pthread_attr_get_np;
+    _pthread_attr_getaffinity_np;
     _pthread_attr_getdetachstate;
     _pthread_attr_getguardsize;
     _pthread_attr_getinheritsched;
@@ -472,6 +475,7 @@ DFprivate_1.0 {
     _pthread_attr_getstackaddr;
     _pthread_attr_getstacksize;
     _pthread_attr_init;
+    _pthread_attr_setaffinity_np;
     _pthread_attr_setcreatesuspend_np;
     _pthread_attr_setdetachstate;
     _pthread_attr_setguardsize;
index dd3e603..28a6564 100644 (file)
@@ -50,6 +50,7 @@
 WR(__atfork, pthread_atfork);
 WR(stub_zero, pthread_attr_destroy);
 WR(stub_zero, pthread_attr_get_np);
+WR(stub_zero, pthread_attr_getaffinity_np);
 WR(stub_zero, pthread_attr_getdetachstate);
 WR(stub_zero, pthread_attr_getguardsize);
 WR(stub_zero, pthread_attr_getinheritsched);
@@ -60,6 +61,7 @@ WR(stub_zero, pthread_attr_getstack);
 WR(stub_zero, pthread_attr_getstackaddr);
 WR(stub_zero, pthread_attr_getstacksize);
 WR(stub_zero, pthread_attr_init);
+WR(stub_zero, pthread_attr_setaffinity_np);
 WR(stub_zero, pthread_attr_setcreatesuspend_np);
 WR(stub_zero, pthread_attr_setdetachstate);
 WR(stub_zero, pthread_attr_setguardsize);
index 0c51d1a..a0f8ce9 100644 (file)
@@ -78,6 +78,7 @@
 #define                pthread_atfork                  _pthread_atfork
 #define                pthread_attr_destroy            _pthread_attr_destroy
 #define                pthread_attr_get_np             _pthread_attr_get_np
+#define                pthread_attr_getaffinity_np     _pthread_attr_getaffinity_np
 #define                pthread_attr_getdetachstate     _pthread_attr_getdetachstate
 #define                pthread_attr_getguardsize       _pthread_attr_getguardsize
 #define                pthread_attr_getinheritsched    _pthread_attr_getinheritsched
@@ -88,6 +89,7 @@
 #define                pthread_attr_getstackaddr       _pthread_attr_getstackaddr
 #define                pthread_attr_getstacksize       _pthread_attr_getstacksize
 #define                pthread_attr_init               _pthread_attr_init
+#define                pthread_attr_setaffinity_np     _pthread_attr_setaffinity_np
 #define                pthread_attr_setcreatesuspend_np _pthread_attr_setcreatesuspend_np
 #define                pthread_attr_setdetachstate     _pthread_attr_setdetachstate
 #define                pthread_attr_setguardsize       _pthread_attr_setguardsize
index 881c30b..17989e4 100644 (file)
@@ -59,6 +59,7 @@
 #undef         pthread_atfork
 #undef         pthread_attr_destroy
 #undef         pthread_attr_get_np
+#undef         pthread_attr_getaffinity_np
 #undef         pthread_attr_getdetachstate
 #undef         pthread_attr_getguardsize
 #undef         pthread_attr_getinheritsched
@@ -69,6 +70,7 @@
 #undef         pthread_attr_getstackaddr
 #undef         pthread_attr_getstacksize
 #undef         pthread_attr_init
+#undef         pthread_attr_setaffinity_np
 #undef         pthread_attr_setcreatesuspend_np
 #undef         pthread_attr_setdetachstate
 #undef         pthread_attr_setguardsize
index 200921c..5d2693e 100644 (file)
@@ -12,6 +12,7 @@ SRCS+= \
        uthread_attr_destroy.c \
        uthread_attr_get_np.c \
        uthread_attr_init.c \
+       uthread_attr_getaffinity_np.c \
        uthread_attr_getdetachstate.c \
        uthread_attr_getinheritsched.c \
        uthread_attr_getschedparam.c \
@@ -20,6 +21,7 @@ SRCS+= \
        uthread_attr_getstack.c \
        uthread_attr_getstackaddr.c \
        uthread_attr_getstacksize.c \
+       uthread_attr_setaffinity_np.c \
        uthread_attr_setcreatesuspend_np.c \
        uthread_attr_setdetachstate.c \
        uthread_attr_setinheritsched.c \
similarity index 50%
copy from include/pthread_np.h
copy to lib/libc_r/uthread/uthread_attr_getaffinity_np.c
index d6753a5..7352c6f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996-98 John Birrell <jb@cimlogic.com.au>.
+ * Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * 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. Neither the name of the author nor the names of any co-contributors
+ * 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
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  *
  * 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 REGENTS OR CONTRIBUTORS BE LIABLE
+ * 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)
  * 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: src/include/pthread_np.h,v 1.7.2.4 2003/01/10 15:41:17 fjoe Exp $
  */
-#ifndef _PTHREAD_NP_H_
-#define _PTHREAD_NP_H_
 
-#include <sched.h>
+#include <sys/types.h>
+#include <sys/sysctl.h>
 
-/*
- * Non-POSIX type definitions:
- */
-typedef void   (*pthread_switch_routine_t)(pthread_t, pthread_t);
+#include <errno.h>
+#include <pthread.h>
+#include <pthread_np.h>
+#include <string.h>
+#include "pthread_private.h"
 
-/*
- * Non-POSIX thread function prototype definitions:
- */
-__BEGIN_DECLS
-int pthread_attr_setcreatesuspend_np(pthread_attr_t *);
-int pthread_attr_get_np(pthread_t, pthread_attr_t *);
-int pthread_getaffinity_np(pthread_t, size_t, cpu_set_t *);
-int pthread_main_np(void);
-int pthread_multi_np(void);
-int pthread_mutexattr_getkind_np(pthread_mutexattr_t);
-int pthread_mutexattr_setkind_np(pthread_mutexattr_t *, int);
-void pthread_resume_all_np(void);
-int pthread_resume_np(pthread_t);
-void pthread_set_name_np(pthread_t, const char *);
-int pthread_setaffinity_np(pthread_t, size_t, const cpu_set_t *);
-int pthread_single_np(void);
-void pthread_suspend_all_np(void);
-int pthread_suspend_np(pthread_t);
-int pthread_switch_add_np(pthread_switch_routine_t);
-int pthread_switch_delete_np(pthread_switch_routine_t);
-int pthread_timedjoin_np(pthread_t, void **, const struct timespec *);
-__END_DECLS
+int
+_pthread_attr_getaffinity_np(const pthread_attr_t *attr __unused,
+    size_t cpusetsize, cpu_set_t *mask)
+{
+       cpu_set_t mask1;
+       size_t len;
+
+       len = sizeof(mask1);
+       if (sysctlbyname("machdep.smp_active", &mask1, &len, NULL, 0) < 0)
+               return (errno);
 
-#endif
+       if (cpusetsize > sizeof(mask1)) {
+               memset(mask, 0, cpusetsize);
+               memcpy(mask, &mask1, sizeof(mask1));
+       } else {
+               memcpy(mask, &mask1, cpusetsize);
+       }
+       return (0);
+}
+__strong_reference(_pthread_attr_getaffinity_np, pthread_attr_getaffinity_np);
similarity index 50%
copy from include/pthread_np.h
copy to lib/libc_r/uthread/uthread_attr_setaffinity_np.c
index d6753a5..d46e4f2 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996-98 John Birrell <jb@cimlogic.com.au>.
+ * Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * 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. Neither the name of the author nor the names of any co-contributors
+ * 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
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  *
  * 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 REGENTS OR CONTRIBUTORS BE LIABLE
+ * 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)
  * 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: src/include/pthread_np.h,v 1.7.2.4 2003/01/10 15:41:17 fjoe Exp $
  */
-#ifndef _PTHREAD_NP_H_
-#define _PTHREAD_NP_H_
-
-#include <sched.h>
 
-/*
- * Non-POSIX type definitions:
- */
-typedef void   (*pthread_switch_routine_t)(pthread_t, pthread_t);
+#include <errno.h>
+#include <pthread.h>
+#include <pthread_np.h>
+#include "pthread_private.h"
 
-/*
- * Non-POSIX thread function prototype definitions:
- */
-__BEGIN_DECLS
-int pthread_attr_setcreatesuspend_np(pthread_attr_t *);
-int pthread_attr_get_np(pthread_t, pthread_attr_t *);
-int pthread_getaffinity_np(pthread_t, size_t, cpu_set_t *);
-int pthread_main_np(void);
-int pthread_multi_np(void);
-int pthread_mutexattr_getkind_np(pthread_mutexattr_t);
-int pthread_mutexattr_setkind_np(pthread_mutexattr_t *, int);
-void pthread_resume_all_np(void);
-int pthread_resume_np(pthread_t);
-void pthread_set_name_np(pthread_t, const char *);
-int pthread_setaffinity_np(pthread_t, size_t, const cpu_set_t *);
-int pthread_single_np(void);
-void pthread_suspend_all_np(void);
-int pthread_suspend_np(pthread_t);
-int pthread_switch_add_np(pthread_switch_routine_t);
-int pthread_switch_delete_np(pthread_switch_routine_t);
-int pthread_timedjoin_np(pthread_t, void **, const struct timespec *);
-__END_DECLS
+int
+_pthread_attr_setaffinity_np(pthread_attr_t *attr __unused,
+    size_t cpusetsize __unused, const cpu_set_t *mask __unused)
+{
 
-#endif
+       return (EOPNOTSUPP);
+}
+__strong_reference(_pthread_attr_setaffinity_np, pthread_attr_setaffinity_np);
index 88a75e8..924822b 100644 (file)
@@ -10,6 +10,7 @@ MAN+= \
        pthread_atfork.3 \
        pthread_attr.3 \
        pthread_attr_get_np.3 \
+       pthread_attr_setaffinity_np.3 \
        pthread_attr_setcreatesuspend_np.3 \
        pthread_barrier_destroy.3 \
        pthread_barrierattr.3 \
@@ -100,6 +101,7 @@ MLINKS+= \
        pthread_attr.3 pthread_attr_setstack.3 \
        pthread_attr.3 pthread_attr_setstackaddr.3 \
        pthread_attr.3 pthread_attr_setstacksize.3 \
+       pthread_attr_setaffinity_np.3 pthread_attr_getaffinity_np.3 \
        pthread_barrierattr.3 pthread_barrierattr_destroy.3 \
        pthread_barrierattr.3 pthread_barrierattr_getpshared.3 \
        pthread_barrierattr.3 pthread_barrierattr_init.3 \
diff --git a/lib/libpthread/pthread_attr_setaffinity_np.3 b/lib/libpthread/pthread_attr_setaffinity_np.3
new file mode 100644 (file)
index 0000000..1567faa
--- /dev/null
@@ -0,0 +1,113 @@
+.\" Copyright (c) 2017 The DragonFly Project.  All rights reserved.
+.\"
+.\" This code is derived from software contributed to The DragonFly Project
+.\" by Sepherosa Ziehau <sepherosa@gmail.com>.
+.\"
+.\" 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.
+.\" 3. Neither the name of The DragonFly Project nor the names of its
+.\"    contributors may be used to endorse or promote products derived
+.\"    from this software without specific, prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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
+.\" COPYRIGHT HOLDERS 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.
+.\"
+.Dd January 15, 2017
+.Dt PTHREAD_ATTR_SETAFFINITY_NP 2
+.Os
+.Sh NAME
+.Nm pthread_attr_setaffinity_np,
+.Nm pthread_attr_getaffinity_np
+.Nd set and get the thread's CPU affinity mask attribute
+.Sh LIBRARY
+.Lb libpthread
+.Sh SYNOPSIS
+.In pthread.h
+.In pthread_np.h
+.Ft int
+.Fn pthread_attr_setaffinity_np "pthread_attr_t *attr" "size_t cpusetsize" "const cpu_set_t *mask"
+.Ft int
+.Fn pthread_attr_getaffinity_np "const pthread_attr_t *attr" "size_t cpusetsize" "cpu_set_t *mask"
+.Sh DESCRIPTION
+.Pp
+The
+.Fn pthread_attr_setaffinity_np
+sets the CPU affinity mask of the
+.Fa attr
+to the value specified by the
+.Fa mask .
+The
+.Fa cpusetsize
+is the length (in bytes) of the data pointed to by
+.Fa mask .
+Normally this argument would be specified as sizeof(cpu_set_t).
+The threads created by
+.Xr pthread_create 2
+with the
+.Fa attr
+will use the CPU affinity mask of the
+.Fa attr .
+.Pp
+.Fn pthread_attr_getaffinity_np
+writes the CPU affinity mask of the
+.Fa attr
+to the cpu_set_t structure pointed to by
+.Fa mask .
+.Pp
+The cpu_set_t data structure represents a set of CPUs.
+See
+.Xr sched_setaffinity 2
+for details.
+.Sh RETURN VALUES
+If successful,
+these functions will return zero.
+Otherwise an error number will be returned to indicate the error.
+.Sh ERRORS
+The
+.Fn pthread_attr_setaffinity_np
+and
+.Fn pthread_attr_getaffinity_np
+will fail if:
+.Bl -tag -width Er
+.It Bq Er EFAULT
+The
+.Fa mask
+parameter is outside the process's allocated address space.
+.It Bq Er EINVAL
+The
+.Fa attr
+parameter is invalid.
+.It Bq Er EPERM
+The
+.Fa mask
+does not contain a valid CPU.
+.El
+.Sh SEE ALSO
+.Xr pthread_create 3
+.Xr pthread_getaffinity_np 2
+.Xr pthread_setaffinity_np 2
+.Sh HISTORY
+The
+.Fn pthread_attr_setaffinity_np
+and
+.Fn pthread_attr_getaffinity_np
+functions first appeared in
+.Dx 4.7 .
index 71f0720..4b1bfe7 100644 (file)
@@ -47,6 +47,7 @@ global:
        _pthread_attr_default;
        _pthread_attr_destroy;
        _pthread_attr_get_np;
+       _pthread_attr_getaffinity_np;
        _pthread_attr_getdetachstate;
        _pthread_attr_getguardsize;
        _pthread_attr_getinheritsched;
@@ -57,6 +58,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;
@@ -209,6 +211,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;
@@ -219,6 +222,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;
index 8916c72..2db3f6f 100644 (file)
@@ -32,6 +32,8 @@
  */
 
 #include "namespace.h"
+#include <sys/types.h>
+#include <sys/sysctl.h>
 #include <machine/tls.h>
 #include <errno.h>
 #include <pthread.h>
@@ -91,6 +93,39 @@ _pthread_attr_get_np(pthread_t pid, pthread_attr_t *dst)
 
 __strong_reference(_pthread_attr_get_np, pthread_attr_get_np);
 
+int
+_pthread_attr_getaffinity_np(const pthread_attr_t *attr, size_t cpusetsize,
+    cpu_set_t *mask)
+{
+       const cpu_set_t *ret;
+       cpu_set_t mask1;
+
+       if (attr == NULL || *attr == NULL || mask == NULL)
+               return (EINVAL);
+
+       if (((*attr)->flags & THR_CPUMASK) == 0) {
+               size_t len;
+
+               len = sizeof(mask1);
+               if (sysctlbyname("machdep.smp_active", &mask1, &len,
+                   NULL, 0) < 0)
+                       return (errno);
+               ret = &mask1;
+       } else {
+               ret = &(*attr)->cpumask;
+       }
+
+       if (cpusetsize > sizeof(*ret)) {
+               memset(mask, 0, cpusetsize);
+               memcpy(mask, ret, sizeof(*ret));
+       } else {
+               memcpy(mask, ret, cpusetsize);
+       }
+       return (0);
+}
+
+__strong_reference(_pthread_attr_getaffinity_np, pthread_attr_getaffinity_np);
+
 int
 _pthread_attr_getdetachstate(const pthread_attr_t *attr, int *detachstate)
 {
@@ -277,6 +312,36 @@ _pthread_attr_init(pthread_attr_t *attr)
 
 __strong_reference(_pthread_attr_init, pthread_attr_init);
 
+int
+_pthread_attr_setaffinity_np(pthread_attr_t *attr, size_t cpusetsize,
+    const cpu_set_t *mask)
+{
+       cpu_set_t active, mask1;
+       size_t len, cplen = cpusetsize;
+
+       if (attr == NULL || *attr == NULL || mask == NULL)
+               return (EINVAL);
+
+       if (cplen > sizeof(mask1))
+               cplen = sizeof(mask1);
+       CPU_ZERO(&mask1);
+       memcpy(&mask1, mask, cplen);
+
+       len = sizeof(active);
+       if (sysctlbyname("machdep.smp_active", &active, &len, NULL, 0) < 0)
+               return (errno);
+
+       CPUMASK_ANDMASK(mask1, active);
+       if (CPUMASK_TESTZERO(mask1))
+               return (EPERM);
+
+       (*attr)->cpumask = mask1;
+       (*attr)->flags |= THR_CPUMASK;
+       return (0);
+}
+
+__strong_reference(_pthread_attr_setaffinity_np, pthread_attr_setaffinity_np);
+
 int
 _pthread_attr_setcreatesuspend_np(pthread_attr_t *attr)
 {
index 75ca76c..9148a95 100644 (file)
@@ -54,6 +54,7 @@ _pthread_create(pthread_t * thread, const pthread_attr_t * attr,
        void *stack;
        sigset_t sigmask, oldsigmask;
        struct pthread *curthread, *new_thread;
+       const cpu_set_t *cpumask = NULL;
        int ret = 0, locked;
 
        _thr_check_init();
@@ -85,6 +86,8 @@ _pthread_create(pthread_t * thread, const pthread_attr_t * attr,
                 * inherited in following code.
                 */
        }
+       if (new_thread->attr.flags & THR_CPUMASK)
+               cpumask = &new_thread->attr.cpumask;
 
        if (create_stack(&new_thread->attr) != 0) {
                /* Insufficient memory to create a stack: */
@@ -165,7 +168,7 @@ _pthread_create(pthread_t * thread, const pthread_attr_t * attr,
        SIGFILLSET(sigmask);
        __sys_sigprocmask(SIG_SETMASK, &sigmask, &oldsigmask);
        new_thread->sigmask = oldsigmask;
-       ret = lwp_create(&create_params);
+       ret = lwp_create2(&create_params, cpumask);
        __sys_sigprocmask(SIG_SETMASK, &oldsigmask, NULL);
        if (ret != 0) {
                if (!locked)
index 9b8bf57..7fc1ae5 100644 (file)
@@ -44,6 +44,7 @@
 #include <sys/queue.h>
 #include <sys/rtprio.h>
 #include <machine/atomic.h>
+#include <machine/cpumask.h>
 #include <errno.h>
 #include <limits.h>
 #include <signal.h>
@@ -237,10 +238,12 @@ struct pthread_attr {
        int     prio;
        int     suspend;
 #define        THR_STACK_USER          0x100   /* 0xFF reserved for <pthread.h> */
+#define THR_CPUMASK            0x200   /* cpumask is valid */
        int     flags;
        void    *stackaddr_attr;
        size_t  stacksize_attr;
        size_t  guardsize_attr;
+       cpumask_t cpumask;
 };
 
 /*
index c0725ba..83dc571 100644 (file)
  * 400706 - sched_{set,get}affinity()
  * 400707 - pthread_{set,get}affinity_np()
  * 400708 - lwp_create2()
+ * 400709 - pthread_attr_{set,get}affinity_np()
  */
 #undef __DragonFly_version
 #define __DragonFly_version 400708     /* propagated to newvers */