lwp: Add lwp_create2 syscll, which takes cpumask for scheduling.
authorSepherosa Ziehau <sephe@dragonflybsd.org>
Sat, 14 Jan 2017 13:16:08 +0000 (21:16 +0800)
committerSepherosa Ziehau <sephe@dragonflybsd.org>
Sun, 15 Jan 2017 11:13:33 +0000 (19:13 +0800)
14 files changed:
include/unistd.h
lib/libc/sys/Makefile.inc
lib/libc/sys/Symbol.map
lib/libc/sys/lwp_create.2
sys/kern/init_sysent.c
sys/kern/kern_fork.c
sys/kern/syscalls.c
sys/kern/syscalls.master
sys/kern/usched_dfly.c
sys/sys/param.h
sys/sys/syscall.h
sys/sys/syscall.mk
sys/sys/sysproto.h
sys/sys/sysunion.h

index 042755d..c33b210 100644 (file)
@@ -37,6 +37,7 @@
 #include <sys/types.h>                 /* XXX adds too much pollution. */
 #include <sys/unistd.h>
 #include <sys/_null.h>
+#include <machine/cpumask.h>
 
 #ifndef _GID_T_DECLARED
 typedef        __uint32_t      gid_t;          /* XXX __gid_t */
@@ -552,6 +553,7 @@ int  iruserok_sa(const void *, int, int, const char *, const char *);
 int     issetugid(void);
 long    lpathconf(const char *, int);
 int     lwp_create(struct lwp_params *);
+int     lwp_create2(struct lwp_params *, const cpumask_t *);
 lwpid_t         lwp_gettid(void);
 int     lwp_setname(lwpid_t, const char *);
 #ifndef        _MKNOD_DECLARED
index 9d93f75..7e6800e 100644 (file)
@@ -142,6 +142,7 @@ MLINKS+=kqueue.2 EV_SET.2 \
        kqueue.2 kevent.2
 MLINKS+=link.2 linkat.2
 MLINKS+=lseek.2 seek.2
+MLINKS+=lwp_create.2 lwp_create2.2
 MLINKS+=lwp_setaffinity.2 lwp_getaffinity.2
 MLINKS+=madvise.2 mcontrol.2 \
        madvise.2 posix_madvise.3
index c94de45..297f735 100644 (file)
@@ -145,6 +145,7 @@ DF404.0 {
     lstat;
     lutimes;
     lwp_create;
+    lwp_create2;
     lwp_getaffinity;
     lwp_gettid;
     lwp_kill;
@@ -450,6 +451,7 @@ DFprivate_1.0 {
     __sys_lstat;
     __sys_lutimes;
     __sys_lwp_create;
+    __sys_lwp_create2;
     __sys_lwp_getaffinity;
     __sys_lwp_gettid;
     __sys_lwp_kill;
@@ -747,6 +749,7 @@ DFprivate_1.0 {
     _lstat;
     _lutimes;
     _lwp_create;
+    _lwp_create2;
     _lwp_getaffinity;
     _lwp_gettid;
     _lwp_kill;
index e6a730d..c27b795 100644 (file)
 .\"
 .\" $DragonFly: src/lib/libc/sys/lwp_create.2,v 1.2 2007/03/13 10:16:56 swildner Exp $
 .\"
-.Dd March 12, 2007
+.Dd January 14, 2017
 .Dt LWP_CREATE 2
 .Os
 .Sh NAME
-.Nm lwp_create
+.Nm lwp_create,
+.Nm lwp_create2
 .Nd spawn a new lwp
 .Sh LIBRARY
 .Lb libc
 .In unistd.h
 .Ft int
 .Fn lwp_create "struct lwp_params *params"
+.Ft int
+.Fn lwp_create2 "struct lwp_params *params" "const cpumask_t *mask"
 .Sh DESCRIPTION
 The
 .Fn lwp_create
-function spawns a new lwp in the current process.
+and the
+.Fn lwp_create2
+function spawn a new lwp in the current process.
 In a way,
 .Fn lwp_create
-is similar to
+and
+.Fn lwp_create2
+are similar to
 .Xr fork 2 .
 However,
 .Fn lwp_create
-does not return twice as parent and child.
+and
+.Fn lwp_create2
+do not return twice as parent and child.
 Instead, the new lwp will execute a function provided by the
 .Fa params
 argument which is a pointer to a
@@ -104,6 +113,14 @@ point to variables where the tid of the new lwp shall be stored.
 Two parameters are provided so that storage for both parent
 and child can be specified separately.
 Setting any of these to NULL causes the respective tid not to be copied out.
+.Pp
+The
+.Fa mask
+argument to
+.Fn lwp_create2
+specifies the new lwp's CPU affinity mask.
+.Va NULL
+means no special CPU affinity settings.
 .Sh RETURN VALUES
 .Rv -std
 .Sh SEE ALSO
@@ -115,3 +132,7 @@ The
 .Fn lwp_create
 function first appeared in
 .Dx 1.9 .
+The
+.Fn lwp_create2
+function first appeared in
+.Dx 4.7 .
index e7bc12f..90d3de7 100644 (file)
@@ -562,4 +562,5 @@ struct sysent sysent[] = {
        { AS(ppoll_args), (sy_call_t *)sys_ppoll },     /* 543 = ppoll */
        { AS(lwp_setaffinity_args), (sy_call_t *)sys_lwp_setaffinity }, /* 544 = lwp_setaffinity */
        { AS(lwp_getaffinity_args), (sy_call_t *)sys_lwp_getaffinity }, /* 545 = lwp_getaffinity */
+       { AS(lwp_create2_args), (sy_call_t *)sys_lwp_create2 }, /* 546 = lwp_create2 */
 };
index e4a1133..8482a92 100644 (file)
@@ -81,7 +81,10 @@ struct forklist {
 TAILQ_HEAD(forklist_head, forklist);
 static struct forklist_head fork_list = TAILQ_HEAD_INITIALIZER(fork_list);
 
-static struct lwp *lwp_fork(struct lwp *, struct proc *, int flags);
+static struct lwp      *lwp_fork(struct lwp *, struct proc *, int flags,
+                           const cpumask_t *mask);
+static int             lwp_create1(struct lwp_params *params,
+                           const cpumask_t *mask);
 
 int forksleep; /* Place for fork1() to sleep on. */
 
@@ -180,24 +183,31 @@ sys_rfork(struct rfork_args *uap)
        return error;
 }
 
-/*
- * Low level thread create used by pthreads.
- */
-int
-sys_lwp_create(struct lwp_create_args *uap)
+static int
+lwp_create1(struct lwp_params *uprm, const cpumask_t *umask)
 {
        struct proc *p = curproc;
        struct lwp *lp;
        struct lwp_params params;
+       cpumask_t *mask = NULL, mask0;
        int error;
 
-       error = copyin(uap->params, &params, sizeof(params));
+       error = copyin(uprm, &params, sizeof(params));
        if (error)
                goto fail2;
 
+       if (umask != NULL) {
+               error = copyin(umask, &mask0, sizeof(mask0));
+               if (error)
+                       goto fail2;
+               CPUMASK_ANDMASK(mask0, smp_active_mask);
+               if (CPUMASK_TESTNZERO(mask0))
+                       mask = &mask0;
+       }
+
        lwkt_gettoken(&p->p_token);
        plimit_lwp_fork(p);     /* force exclusive access */
-       lp = lwp_fork(curthread->td_lwp, p, RFPROC | RFMEM);
+       lp = lwp_fork(curthread->td_lwp, p, RFPROC | RFMEM, mask);
        error = cpu_prepare_lwp(lp, &params);
        if (error)
                goto fail;
@@ -243,6 +253,23 @@ fail2:
        return (error);
 }
 
+/*
+ * Low level thread create used by pthreads.
+ */
+int
+sys_lwp_create(struct lwp_create_args *uap)
+{
+
+       return (lwp_create1(uap->params, NULL));
+}
+
+int
+sys_lwp_create2(struct lwp_create2_args *uap)
+{
+
+       return (lwp_create1(uap->params, uap->mask));
+}
+
 int    nprocs = 1;             /* process 0 */
 
 int
@@ -601,7 +628,7 @@ fork1(struct lwp *lp1, int flags, struct proc **procp)
         * into userland, after it was put on the runq by
         * start_forked_proc().
         */
-       lwp_fork(lp1, p2, flags);
+       lwp_fork(lp1, p2, flags, NULL);
 
        if (flags == (RFFDG | RFPROC | RFPGLOCK)) {
                mycpu->gd_cnt.v_forks++;
@@ -659,7 +686,8 @@ done:
 }
 
 static struct lwp *
-lwp_fork(struct lwp *origlp, struct proc *destproc, int flags)
+lwp_fork(struct lwp *origlp, struct proc *destproc, int flags,
+    const cpumask_t *mask)
 {
        globaldata_t gd = mycpu;
        struct lwp *lp;
@@ -673,6 +701,8 @@ lwp_fork(struct lwp *origlp, struct proc *destproc, int flags)
        bcopy(&origlp->lwp_startcopy, &lp->lwp_startcopy,
            (unsigned) ((caddr_t)&lp->lwp_endcopy -
                        (caddr_t)&lp->lwp_startcopy));
+       if (mask != NULL)
+               lp->lwp_cpumask = *mask;
 
        /*
         * Reset the sigaltstack if memory is shared, otherwise inherit
index 091a70b..2f47e38 100644 (file)
@@ -552,4 +552,5 @@ const char *syscallnames[] = {
        "ppoll",                        /* 543 = ppoll */
        "lwp_setaffinity",                      /* 544 = lwp_setaffinity */
        "lwp_getaffinity",                      /* 545 = lwp_getaffinity */
+       "lwp_create2",                  /* 546 = lwp_create2 */
 };
index 38f3d4b..01bf54d 100644 (file)
                        const struct timespec *ts, const sigset_t *sigmask); }
 544    STD     { int lwp_setaffinity(pid_t pid, lwpid_t tid, const cpumask_t *mask); }
 545    STD     { int lwp_getaffinity(pid_t pid, lwpid_t tid, cpumask_t *mask); }
+546    STD     { int lwp_create2(struct lwp_params *params, const cpumask_t *mask); }
index 9691b17..da3320c 100644 (file)
@@ -1262,6 +1262,8 @@ dfly_forking(struct lwp *plp, struct lwp *lp)
        lp->lwp_qcpu = ++save_cpu % ncpus;
 #else
        lp->lwp_qcpu = plp->lwp_qcpu;
+       if (CPUMASK_TESTBIT(lp->lwp_cpumask, lp->lwp_qcpu) == 0)
+               lp->lwp_qcpu = BSFCPUMASK(lp->lwp_cpumask);
 #endif
 
        /*
index 5199b7e..c0725ba 100644 (file)
  * 400705 - lwp_{set,get}affinity()
  * 400706 - sched_{set,get}affinity()
  * 400707 - pthread_{set,get}affinity_np()
+ * 400708 - lwp_create2()
  */
 #undef __DragonFly_version
-#define __DragonFly_version 400707     /* propagated to newvers */
+#define __DragonFly_version 400708     /* propagated to newvers */
 
 #include <sys/_null.h>
 
index 588473f..2094c4a 100644 (file)
 #define        SYS_ppoll       543
 #define        SYS_lwp_setaffinity     544
 #define        SYS_lwp_getaffinity     545
-#define        SYS_MAXSYSCALL  546
+#define        SYS_lwp_create2 546
+#define        SYS_MAXSYSCALL  547
index 95f57aa..635a7e2 100644 (file)
@@ -309,4 +309,5 @@ MIASM =  \
        lwp_setname.o \
        ppoll.o \
        lwp_setaffinity.o \
-       lwp_getaffinity.o
+       lwp_getaffinity.o \
+       lwp_create2.o
index ea054af..5e47f00 100644 (file)
@@ -2341,6 +2341,13 @@ struct   lwp_getaffinity_args {
        lwpid_t tid;    char tid_[PAD_(lwpid_t)];
        cpumask_t *     mask;   char mask_[PAD_(cpumask_t *)];
 };
+struct lwp_create2_args {
+#ifdef _KERNEL
+       struct sysmsg sysmsg;
+#endif
+       struct lwp_params *     params; char params_[PAD_(struct lwp_params *)];
+       const cpumask_t *       mask;   char mask_[PAD_(const cpumask_t *)];
+};
 struct olseek_args {
 #ifdef _KERNEL
        struct sysmsg sysmsg;
@@ -2836,6 +2843,7 @@ int       sys_lwp_setname (struct lwp_setname_args *);
 int    sys_ppoll (struct ppoll_args *);
 int    sys_lwp_setaffinity (struct lwp_setaffinity_args *);
 int    sys_lwp_getaffinity (struct lwp_getaffinity_args *);
+int    sys_lwp_create2 (struct lwp_create2_args *);
 
 #endif /* !_SYS_SYSPROTO_H_ */
 #undef PAD_
index a48465a..fde0762 100644 (file)
@@ -318,4 +318,5 @@ union sysunion {
        struct  ppoll_args ppoll;
        struct  lwp_setaffinity_args lwp_setaffinity;
        struct  lwp_getaffinity_args lwp_getaffinity;
+       struct  lwp_create2_args lwp_create2;
 };