From 1eb8c61101afd79c1b21b3eeac68b4d1528df580 Mon Sep 17 00:00:00 2001 From: Sepherosa Ziehau Date: Sat, 14 Jan 2017 21:16:08 +0800 Subject: [PATCH] lwp: Add lwp_create2 syscll, which takes cpumask for scheduling. --- include/unistd.h | 2 ++ lib/libc/sys/Makefile.inc | 1 + lib/libc/sys/Symbol.map | 3 +++ lib/libc/sys/lwp_create.2 | 31 ++++++++++++++++++++++++----- sys/kern/init_sysent.c | 1 + sys/kern/kern_fork.c | 50 +++++++++++++++++++++++++++++++++++++---------- sys/kern/syscalls.c | 1 + sys/kern/syscalls.master | 1 + sys/kern/usched_dfly.c | 2 ++ sys/sys/param.h | 3 ++- sys/sys/syscall.h | 3 ++- sys/sys/syscall.mk | 3 ++- sys/sys/sysproto.h | 8 ++++++++ sys/sys/sysunion.h | 1 + 14 files changed, 92 insertions(+), 18 deletions(-) diff --git a/include/unistd.h b/include/unistd.h index 042755d70f..c33b210e49 100644 --- a/include/unistd.h +++ b/include/unistd.h @@ -37,6 +37,7 @@ #include /* XXX adds too much pollution. */ #include #include +#include #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 diff --git a/lib/libc/sys/Makefile.inc b/lib/libc/sys/Makefile.inc index 9d93f75c14..7e6800eba2 100644 --- a/lib/libc/sys/Makefile.inc +++ b/lib/libc/sys/Makefile.inc @@ -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 diff --git a/lib/libc/sys/Symbol.map b/lib/libc/sys/Symbol.map index c94de459b6..297f7352ae 100644 --- a/lib/libc/sys/Symbol.map +++ b/lib/libc/sys/Symbol.map @@ -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; diff --git a/lib/libc/sys/lwp_create.2 b/lib/libc/sys/lwp_create.2 index e6a730dd9a..c27b795900 100644 --- a/lib/libc/sys/lwp_create.2 +++ b/lib/libc/sys/lwp_create.2 @@ -32,11 +32,12 @@ .\" .\" $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 @@ -44,17 +45,25 @@ .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 . diff --git a/sys/kern/init_sysent.c b/sys/kern/init_sysent.c index e7bc12f51d..90d3de7816 100644 --- a/sys/kern/init_sysent.c +++ b/sys/kern/init_sysent.c @@ -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 */ }; diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c index e4a113361d..8482a92283 100644 --- a/sys/kern/kern_fork.c +++ b/sys/kern/kern_fork.c @@ -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, ¶ms, sizeof(params)); + error = copyin(uprm, ¶ms, 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, ¶ms); 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 diff --git a/sys/kern/syscalls.c b/sys/kern/syscalls.c index 091a70bd25..2f47e388cd 100644 --- a/sys/kern/syscalls.c +++ b/sys/kern/syscalls.c @@ -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 */ }; diff --git a/sys/kern/syscalls.master b/sys/kern/syscalls.master index 38f3d4ba15..01bf54da32 100644 --- a/sys/kern/syscalls.master +++ b/sys/kern/syscalls.master @@ -746,3 +746,4 @@ 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); } diff --git a/sys/kern/usched_dfly.c b/sys/kern/usched_dfly.c index 9691b176f6..da3320c096 100644 --- a/sys/kern/usched_dfly.c +++ b/sys/kern/usched_dfly.c @@ -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 /* diff --git a/sys/sys/param.h b/sys/sys/param.h index 5199b7e681..c0725ba597 100644 --- a/sys/sys/param.h +++ b/sys/sys/param.h @@ -142,9 +142,10 @@ * 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 diff --git a/sys/sys/syscall.h b/sys/sys/syscall.h index 588473f9a6..2094c4a37f 100644 --- a/sys/sys/syscall.h +++ b/sys/sys/syscall.h @@ -380,4 +380,5 @@ #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 diff --git a/sys/sys/syscall.mk b/sys/sys/syscall.mk index 95f57aa664..635a7e20a1 100644 --- a/sys/sys/syscall.mk +++ b/sys/sys/syscall.mk @@ -309,4 +309,5 @@ MIASM = \ lwp_setname.o \ ppoll.o \ lwp_setaffinity.o \ - lwp_getaffinity.o + lwp_getaffinity.o \ + lwp_create2.o diff --git a/sys/sys/sysproto.h b/sys/sys/sysproto.h index ea054af284..5e47f0063a 100644 --- a/sys/sys/sysproto.h +++ b/sys/sys/sysproto.h @@ -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_ diff --git a/sys/sys/sysunion.h b/sys/sys/sysunion.h index a48465a0f3..fde0762f88 100644 --- a/sys/sys/sysunion.h +++ b/sys/sys/sysunion.h @@ -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; }; -- 2.11.4.GIT