Home | History | Annotate | Line # | Download | only in kern
sys_lwp.c revision 1.52.14.1.2.1
      1  1.52.14.1.2.1      matt /*	$NetBSD: sys_lwp.c,v 1.52.14.1.2.1 2012/11/01 16:45:03 matt Exp $	*/
      2            1.2        ad 
      3            1.2        ad /*-
      4           1.36        ad  * Copyright (c) 2001, 2006, 2007, 2008 The NetBSD Foundation, Inc.
      5            1.2        ad  * All rights reserved.
      6            1.2        ad  *
      7            1.2        ad  * This code is derived from software contributed to The NetBSD Foundation
      8            1.2        ad  * by Nathan J. Williams, and Andrew Doran.
      9            1.2        ad  *
     10            1.2        ad  * Redistribution and use in source and binary forms, with or without
     11            1.2        ad  * modification, are permitted provided that the following conditions
     12            1.2        ad  * are met:
     13            1.2        ad  * 1. Redistributions of source code must retain the above copyright
     14            1.2        ad  *    notice, this list of conditions and the following disclaimer.
     15            1.2        ad  * 2. Redistributions in binary form must reproduce the above copyright
     16            1.2        ad  *    notice, this list of conditions and the following disclaimer in the
     17            1.2        ad  *    documentation and/or other materials provided with the distribution.
     18            1.2        ad  *
     19            1.2        ad  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     20            1.2        ad  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     21            1.2        ad  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     22            1.2        ad  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     23            1.2        ad  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     24            1.2        ad  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     25            1.2        ad  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     26            1.2        ad  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     27            1.2        ad  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     28            1.2        ad  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     29            1.2        ad  * POSSIBILITY OF SUCH DAMAGE.
     30            1.2        ad  */
     31            1.2        ad 
     32            1.2        ad /*
     33            1.2        ad  * Lightweight process (LWP) system calls.  See kern_lwp.c for a description
     34            1.2        ad  * of LWPs.
     35            1.2        ad  */
     36            1.2        ad 
     37            1.2        ad #include <sys/cdefs.h>
     38  1.52.14.1.2.1      matt __KERNEL_RCSID(0, "$NetBSD: sys_lwp.c,v 1.52.14.1.2.1 2012/11/01 16:45:03 matt Exp $");
     39            1.2        ad 
     40            1.2        ad #include <sys/param.h>
     41            1.2        ad #include <sys/systm.h>
     42            1.2        ad #include <sys/pool.h>
     43            1.2        ad #include <sys/proc.h>
     44            1.2        ad #include <sys/types.h>
     45            1.2        ad #include <sys/syscallargs.h>
     46            1.2        ad #include <sys/kauth.h>
     47            1.2        ad #include <sys/kmem.h>
     48            1.2        ad #include <sys/sleepq.h>
     49           1.30        ad #include <sys/lwpctl.h>
     50           1.45        ad #include <sys/cpu.h>
     51            1.2        ad 
     52            1.2        ad #include <uvm/uvm_extern.h>
     53            1.2        ad 
     54           1.42  wrstuden #include "opt_sa.h"
     55           1.42  wrstuden 
     56            1.2        ad #define	LWP_UNPARK_MAX		1024
     57            1.2        ad 
     58           1.47     rmind static syncobj_t lwp_park_sobj = {
     59           1.26        ad 	SOBJ_SLEEPQ_LIFO,
     60            1.2        ad 	sleepq_unsleep,
     61            1.7      yamt 	sleepq_changepri,
     62            1.7      yamt 	sleepq_lendpri,
     63            1.7      yamt 	syncobj_noowner,
     64            1.2        ad };
     65            1.2        ad 
     66           1.47     rmind static sleeptab_t	lwp_park_tab;
     67            1.2        ad 
     68            1.2        ad void
     69            1.2        ad lwp_sys_init(void)
     70            1.2        ad {
     71            1.2        ad 	sleeptab_init(&lwp_park_tab);
     72            1.2        ad }
     73            1.2        ad 
     74            1.2        ad int
     75      1.52.14.1       riz do_lwp_create(lwp_t *l, void *arg, u_long flags, lwpid_t *new_lwp)
     76            1.2        ad {
     77      1.52.14.1       riz  	struct proc *p = l->l_proc;
     78      1.52.14.1       riz  	struct lwp *l2;
     79      1.52.14.1       riz  	struct schedstate_percpu *spc;
     80      1.52.14.1       riz  	vaddr_t uaddr;
     81      1.52.14.1       riz 	int error;
     82            1.2        ad 
     83           1.42  wrstuden #ifdef KERN_SA
     84           1.42  wrstuden 	mutex_enter(p->p_lock);
     85           1.42  wrstuden 	if ((p->p_sflag & (PS_SA | PS_WEXIT)) != 0 || p->p_sa != NULL) {
     86           1.42  wrstuden 		mutex_exit(p->p_lock);
     87           1.42  wrstuden 		return EINVAL;
     88           1.42  wrstuden 	}
     89           1.42  wrstuden 	mutex_exit(p->p_lock);
     90           1.42  wrstuden #endif
     91           1.42  wrstuden 
     92            1.2        ad 	/* XXX check against resource limits */
     93            1.2        ad 
     94           1.46     rmind 	uaddr = uvm_uarea_alloc();
     95      1.52.14.1       riz 	if (__predict_false(uaddr == 0))
     96            1.2        ad 		return ENOMEM;
     97            1.2        ad 
     98      1.52.14.1       riz 	error = lwp_create(l, p, uaddr, flags & LWP_DETACHED,
     99      1.52.14.1       riz 	    NULL, 0, p->p_emul->e_startlwp, arg, &l2, l->l_class);
    100           1.46     rmind 	if (__predict_false(error)) {
    101           1.46     rmind 		uvm_uarea_free(uaddr);
    102           1.18     rmind 		return error;
    103           1.18     rmind 	}
    104            1.2        ad 
    105      1.52.14.1       riz 	*new_lwp = l2->l_lid;
    106           1.21     rmind 
    107            1.2        ad 	/*
    108            1.2        ad 	 * Set the new LWP running, unless the caller has requested that
    109            1.2        ad 	 * it be created in suspended state.  If the process is stopping,
    110            1.2        ad 	 * then the LWP is created stopped.
    111            1.2        ad 	 */
    112           1.39        ad 	mutex_enter(p->p_lock);
    113            1.2        ad 	lwp_lock(l2);
    114           1.50     skrll 	spc = &l2->l_cpu->ci_schedstate;
    115      1.52.14.1       riz 	if ((flags & LWP_SUSPENDED) == 0 &&
    116            1.4     pavel 	    (l->l_flag & (LW_WREBOOT | LW_WSUSPEND | LW_WEXIT)) == 0) {
    117           1.50     skrll 	    	if (p->p_stat == SSTOP || (p->p_sflag & PS_STOPPING) != 0) {
    118           1.50     skrll 			KASSERT(l2->l_wchan == NULL);
    119            1.2        ad 	    		l2->l_stat = LSSTOP;
    120           1.51      yamt 			p->p_nrlwps--;
    121           1.50     skrll 			lwp_unlock_to(l2, spc->spc_lwplock);
    122           1.50     skrll 		} else {
    123           1.50     skrll 			KASSERT(lwp_locked(l2, spc->spc_mutex));
    124            1.2        ad 			l2->l_stat = LSRUN;
    125           1.19      yamt 			sched_enqueue(l2, false);
    126           1.50     skrll 			lwp_unlock(l2);
    127            1.2        ad 		}
    128           1.31        ad 	} else {
    129            1.2        ad 		l2->l_stat = LSSUSPENDED;
    130           1.51      yamt 		p->p_nrlwps--;
    131           1.50     skrll 		lwp_unlock_to(l2, spc->spc_lwplock);
    132           1.31        ad 	}
    133           1.39        ad 	mutex_exit(p->p_lock);
    134            1.2        ad 
    135            1.2        ad 	return 0;
    136            1.2        ad }
    137            1.2        ad 
    138            1.2        ad int
    139      1.52.14.1       riz sys__lwp_create(struct lwp *l, const struct sys__lwp_create_args *uap,
    140      1.52.14.1       riz     register_t *retval)
    141      1.52.14.1       riz {
    142      1.52.14.1       riz 	/* {
    143      1.52.14.1       riz 		syscallarg(const ucontext_t *) ucp;
    144      1.52.14.1       riz 		syscallarg(u_long) flags;
    145      1.52.14.1       riz 		syscallarg(lwpid_t *) new_lwp;
    146      1.52.14.1       riz 	} */
    147      1.52.14.1       riz 	struct proc *p = l->l_proc;
    148      1.52.14.1       riz 	ucontext_t *newuc = NULL;
    149      1.52.14.1       riz 	lwpid_t lid;
    150      1.52.14.1       riz 	int error;
    151      1.52.14.1       riz 
    152      1.52.14.1       riz 	newuc = kmem_alloc(sizeof(ucontext_t), KM_SLEEP);
    153      1.52.14.1       riz 	error = copyin(SCARG(uap, ucp), newuc, p->p_emul->e_ucsize);
    154      1.52.14.1       riz 	if (error)
    155      1.52.14.1       riz 		goto fail;
    156      1.52.14.1       riz 
    157      1.52.14.1       riz 	/* validate the ucontext */
    158      1.52.14.1       riz 	if ((newuc->uc_flags & _UC_CPU) == 0) {
    159      1.52.14.1       riz 		error = EINVAL;
    160      1.52.14.1       riz 		goto fail;
    161      1.52.14.1       riz 	}
    162      1.52.14.1       riz 	error = cpu_mcontext_validate(l, &newuc->uc_mcontext);
    163      1.52.14.1       riz 	if (error)
    164      1.52.14.1       riz 		goto fail;
    165      1.52.14.1       riz 
    166      1.52.14.1       riz 	error = do_lwp_create(l, newuc, SCARG(uap, flags), &lid);
    167      1.52.14.1       riz 	if (error)
    168      1.52.14.1       riz 		goto fail;
    169      1.52.14.1       riz 
    170      1.52.14.1       riz 	/*
    171      1.52.14.1       riz 	 * do not free ucontext in case of an error here,
    172      1.52.14.1       riz 	 * the lwp will actually run and access it
    173      1.52.14.1       riz 	 */
    174      1.52.14.1       riz 	return copyout(&lid, SCARG(uap, new_lwp), sizeof(lid));
    175      1.52.14.1       riz 
    176      1.52.14.1       riz fail:
    177      1.52.14.1       riz 	kmem_free(newuc, sizeof(ucontext_t));
    178      1.52.14.1       riz 	return error;
    179      1.52.14.1       riz }
    180      1.52.14.1       riz 
    181      1.52.14.1       riz int
    182           1.32       dsl sys__lwp_exit(struct lwp *l, const void *v, register_t *retval)
    183            1.2        ad {
    184            1.2        ad 
    185            1.2        ad 	lwp_exit(l);
    186            1.2        ad 	return 0;
    187            1.2        ad }
    188            1.2        ad 
    189            1.2        ad int
    190           1.32       dsl sys__lwp_self(struct lwp *l, const void *v, register_t *retval)
    191            1.2        ad {
    192            1.2        ad 
    193            1.2        ad 	*retval = l->l_lid;
    194            1.2        ad 	return 0;
    195            1.2        ad }
    196            1.2        ad 
    197            1.2        ad int
    198           1.32       dsl sys__lwp_getprivate(struct lwp *l, const void *v, register_t *retval)
    199            1.2        ad {
    200            1.2        ad 
    201            1.2        ad 	*retval = (uintptr_t)l->l_private;
    202            1.2        ad 	return 0;
    203            1.2        ad }
    204            1.2        ad 
    205            1.2        ad int
    206           1.47     rmind sys__lwp_setprivate(struct lwp *l, const struct sys__lwp_setprivate_args *uap,
    207           1.47     rmind     register_t *retval)
    208            1.2        ad {
    209           1.32       dsl 	/* {
    210            1.2        ad 		syscallarg(void *) ptr;
    211           1.32       dsl 	} */
    212            1.2        ad 
    213           1.52       chs 	return lwp_setprivate(l, SCARG(uap, ptr));
    214            1.2        ad }
    215            1.2        ad 
    216            1.2        ad int
    217           1.47     rmind sys__lwp_suspend(struct lwp *l, const struct sys__lwp_suspend_args *uap,
    218           1.47     rmind     register_t *retval)
    219            1.2        ad {
    220           1.32       dsl 	/* {
    221            1.2        ad 		syscallarg(lwpid_t) target;
    222           1.32       dsl 	} */
    223            1.2        ad 	struct proc *p = l->l_proc;
    224            1.2        ad 	struct lwp *t;
    225            1.2        ad 	int error;
    226            1.2        ad 
    227           1.39        ad 	mutex_enter(p->p_lock);
    228           1.42  wrstuden 
    229           1.42  wrstuden #ifdef KERN_SA
    230           1.42  wrstuden 	if ((p->p_sflag & PS_SA) != 0 || p->p_sa != NULL) {
    231           1.42  wrstuden 		mutex_exit(p->p_lock);
    232           1.42  wrstuden 		return EINVAL;
    233           1.42  wrstuden 	}
    234           1.42  wrstuden #endif
    235           1.42  wrstuden 
    236            1.2        ad 	if ((t = lwp_find(p, SCARG(uap, target))) == NULL) {
    237           1.39        ad 		mutex_exit(p->p_lock);
    238            1.2        ad 		return ESRCH;
    239            1.2        ad 	}
    240            1.2        ad 
    241            1.2        ad 	/*
    242            1.2        ad 	 * Check for deadlock, which is only possible when we're suspending
    243            1.2        ad 	 * ourself.  XXX There is a short race here, as p_nrlwps is only
    244            1.2        ad 	 * incremented when an LWP suspends itself on the kernel/user
    245            1.2        ad 	 * boundary.  It's still possible to kill -9 the process so we
    246            1.2        ad 	 * don't bother checking further.
    247            1.2        ad 	 */
    248            1.2        ad 	lwp_lock(t);
    249            1.2        ad 	if ((t == l && p->p_nrlwps == 1) ||
    250            1.4     pavel 	    (l->l_flag & (LW_WCORE | LW_WEXIT)) != 0) {
    251            1.2        ad 		lwp_unlock(t);
    252           1.39        ad 		mutex_exit(p->p_lock);
    253            1.2        ad 		return EDEADLK;
    254            1.2        ad 	}
    255            1.2        ad 
    256            1.2        ad 	/*
    257            1.2        ad 	 * Suspend the LWP.  XXX If it's on a different CPU, we should wait
    258            1.2        ad 	 * for it to be preempted, where it will put itself to sleep.
    259            1.2        ad 	 *
    260            1.2        ad 	 * Suspension of the current LWP will happen on return to userspace.
    261            1.2        ad 	 */
    262            1.2        ad 	error = lwp_suspend(l, t);
    263           1.23     rmind 	if (error) {
    264           1.39        ad 		mutex_exit(p->p_lock);
    265           1.23     rmind 		return error;
    266           1.23     rmind 	}
    267           1.23     rmind 
    268           1.23     rmind 	/*
    269           1.23     rmind 	 * Wait for:
    270           1.23     rmind 	 *  o process exiting
    271           1.23     rmind 	 *  o target LWP suspended
    272           1.23     rmind 	 *  o target LWP not suspended and L_WSUSPEND clear
    273           1.23     rmind 	 *  o target LWP exited
    274           1.23     rmind 	 */
    275           1.23     rmind 	for (;;) {
    276           1.39        ad 		error = cv_wait_sig(&p->p_lwpcv, p->p_lock);
    277           1.23     rmind 		if (error) {
    278           1.23     rmind 			error = ERESTART;
    279           1.23     rmind 			break;
    280           1.23     rmind 		}
    281           1.25     rmind 		if (lwp_find(p, SCARG(uap, target)) == NULL) {
    282           1.25     rmind 			error = ESRCH;
    283           1.25     rmind 			break;
    284           1.25     rmind 		}
    285           1.23     rmind 		if ((l->l_flag | t->l_flag) & (LW_WCORE | LW_WEXIT)) {
    286           1.23     rmind 			error = ERESTART;
    287           1.23     rmind 			break;
    288           1.23     rmind 		}
    289           1.23     rmind 		if (t->l_stat == LSSUSPENDED ||
    290           1.23     rmind 		    (t->l_flag & LW_WSUSPEND) == 0)
    291           1.23     rmind 			break;
    292           1.23     rmind 	}
    293           1.39        ad 	mutex_exit(p->p_lock);
    294            1.2        ad 
    295            1.2        ad 	return error;
    296            1.2        ad }
    297            1.2        ad 
    298            1.2        ad int
    299           1.47     rmind sys__lwp_continue(struct lwp *l, const struct sys__lwp_continue_args *uap,
    300           1.47     rmind     register_t *retval)
    301            1.2        ad {
    302           1.32       dsl 	/* {
    303            1.2        ad 		syscallarg(lwpid_t) target;
    304           1.32       dsl 	} */
    305            1.2        ad 	int error;
    306            1.2        ad 	struct proc *p = l->l_proc;
    307            1.2        ad 	struct lwp *t;
    308            1.2        ad 
    309            1.2        ad 	error = 0;
    310            1.2        ad 
    311           1.39        ad 	mutex_enter(p->p_lock);
    312            1.2        ad 	if ((t = lwp_find(p, SCARG(uap, target))) == NULL) {
    313           1.39        ad 		mutex_exit(p->p_lock);
    314            1.2        ad 		return ESRCH;
    315            1.2        ad 	}
    316            1.2        ad 
    317            1.2        ad 	lwp_lock(t);
    318            1.2        ad 	lwp_continue(t);
    319           1.39        ad 	mutex_exit(p->p_lock);
    320            1.2        ad 
    321            1.2        ad 	return error;
    322            1.2        ad }
    323            1.2        ad 
    324            1.2        ad int
    325           1.47     rmind sys__lwp_wakeup(struct lwp *l, const struct sys__lwp_wakeup_args *uap,
    326           1.47     rmind     register_t *retval)
    327            1.2        ad {
    328           1.32       dsl 	/* {
    329            1.2        ad 		syscallarg(lwpid_t) target;
    330           1.32       dsl 	} */
    331            1.2        ad 	struct lwp *t;
    332            1.2        ad 	struct proc *p;
    333            1.2        ad 	int error;
    334            1.2        ad 
    335            1.2        ad 	p = l->l_proc;
    336           1.39        ad 	mutex_enter(p->p_lock);
    337            1.2        ad 
    338            1.2        ad 	if ((t = lwp_find(p, SCARG(uap, target))) == NULL) {
    339           1.39        ad 		mutex_exit(p->p_lock);
    340            1.2        ad 		return ESRCH;
    341            1.2        ad 	}
    342            1.2        ad 
    343            1.2        ad 	lwp_lock(t);
    344           1.15        ad 	t->l_flag |= (LW_CANCELLED | LW_UNPARKED);
    345            1.2        ad 
    346            1.2        ad 	if (t->l_stat != LSSLEEP) {
    347           1.16        ad 		lwp_unlock(t);
    348            1.2        ad 		error = ENODEV;
    349           1.16        ad 	} else if ((t->l_flag & LW_SINTR) == 0) {
    350           1.16        ad 		lwp_unlock(t);
    351            1.2        ad 		error = EBUSY;
    352           1.16        ad 	} else {
    353           1.16        ad 		/* Wake it up.  lwp_unsleep() will release the LWP lock. */
    354           1.46     rmind 		lwp_unsleep(t, true);
    355           1.16        ad 		error = 0;
    356            1.2        ad 	}
    357            1.2        ad 
    358           1.39        ad 	mutex_exit(p->p_lock);
    359            1.2        ad 
    360            1.2        ad 	return error;
    361            1.2        ad }
    362            1.2        ad 
    363            1.2        ad int
    364           1.47     rmind sys__lwp_wait(struct lwp *l, const struct sys__lwp_wait_args *uap,
    365           1.47     rmind     register_t *retval)
    366            1.2        ad {
    367           1.32       dsl 	/* {
    368            1.2        ad 		syscallarg(lwpid_t) wait_for;
    369            1.2        ad 		syscallarg(lwpid_t *) departed;
    370           1.32       dsl 	} */
    371            1.2        ad 	struct proc *p = l->l_proc;
    372            1.2        ad 	int error;
    373            1.2        ad 	lwpid_t dep;
    374            1.2        ad 
    375           1.39        ad 	mutex_enter(p->p_lock);
    376  1.52.14.1.2.1      matt 	error = lwp_wait(l, SCARG(uap, wait_for), &dep, false);
    377           1.39        ad 	mutex_exit(p->p_lock);
    378            1.2        ad 
    379  1.52.14.1.2.1      matt 	if (!error && SCARG(uap, departed)) {
    380            1.2        ad 		error = copyout(&dep, SCARG(uap, departed), sizeof(dep));
    381            1.2        ad 	}
    382            1.2        ad 
    383  1.52.14.1.2.1      matt 	return error;
    384            1.2        ad }
    385            1.2        ad 
    386            1.2        ad int
    387           1.47     rmind sys__lwp_kill(struct lwp *l, const struct sys__lwp_kill_args *uap,
    388           1.47     rmind     register_t *retval)
    389            1.2        ad {
    390           1.32       dsl 	/* {
    391            1.2        ad 		syscallarg(lwpid_t)	target;
    392            1.2        ad 		syscallarg(int)		signo;
    393           1.32       dsl 	} */
    394            1.2        ad 	struct proc *p = l->l_proc;
    395            1.2        ad 	struct lwp *t;
    396            1.2        ad 	ksiginfo_t ksi;
    397            1.2        ad 	int signo = SCARG(uap, signo);
    398            1.2        ad 	int error = 0;
    399            1.2        ad 
    400            1.2        ad 	if ((u_int)signo >= NSIG)
    401            1.2        ad 		return EINVAL;
    402            1.2        ad 
    403            1.2        ad 	KSI_INIT(&ksi);
    404            1.2        ad 	ksi.ksi_signo = signo;
    405           1.43        ad 	ksi.ksi_code = SI_LWP;
    406            1.2        ad 	ksi.ksi_pid = p->p_pid;
    407            1.2        ad 	ksi.ksi_uid = kauth_cred_geteuid(l->l_cred);
    408            1.2        ad 	ksi.ksi_lid = SCARG(uap, target);
    409            1.2        ad 
    410           1.38        ad 	mutex_enter(proc_lock);
    411           1.39        ad 	mutex_enter(p->p_lock);
    412            1.2        ad 	if ((t = lwp_find(p, ksi.ksi_lid)) == NULL)
    413            1.2        ad 		error = ESRCH;
    414            1.2        ad 	else if (signo != 0)
    415            1.2        ad 		kpsignal2(p, &ksi);
    416           1.39        ad 	mutex_exit(p->p_lock);
    417           1.38        ad 	mutex_exit(proc_lock);
    418            1.2        ad 
    419            1.2        ad 	return error;
    420            1.2        ad }
    421            1.2        ad 
    422            1.2        ad int
    423           1.47     rmind sys__lwp_detach(struct lwp *l, const struct sys__lwp_detach_args *uap,
    424           1.47     rmind     register_t *retval)
    425            1.2        ad {
    426           1.32       dsl 	/* {
    427            1.2        ad 		syscallarg(lwpid_t)	target;
    428           1.32       dsl 	} */
    429            1.2        ad 	struct proc *p;
    430            1.2        ad 	struct lwp *t;
    431            1.2        ad 	lwpid_t target;
    432            1.2        ad 	int error;
    433            1.2        ad 
    434            1.2        ad 	target = SCARG(uap, target);
    435            1.2        ad 	p = l->l_proc;
    436            1.2        ad 
    437           1.39        ad 	mutex_enter(p->p_lock);
    438            1.2        ad 
    439            1.2        ad 	if (l->l_lid == target)
    440            1.2        ad 		t = l;
    441            1.2        ad 	else {
    442            1.2        ad 		/*
    443            1.2        ad 		 * We can't use lwp_find() here because the target might
    444            1.2        ad 		 * be a zombie.
    445            1.2        ad 		 */
    446            1.2        ad 		LIST_FOREACH(t, &p->p_lwps, l_sibling)
    447            1.2        ad 			if (t->l_lid == target)
    448            1.2        ad 				break;
    449            1.2        ad 	}
    450            1.2        ad 
    451            1.2        ad 	/*
    452            1.2        ad 	 * If the LWP is already detached, there's nothing to do.
    453            1.2        ad 	 * If it's a zombie, we need to clean up after it.  LSZOMB
    454            1.2        ad 	 * is visible with the proc mutex held.
    455            1.2        ad 	 *
    456            1.2        ad 	 * After we have detached or released the LWP, kick any
    457            1.2        ad 	 * other LWPs that may be sitting in _lwp_wait(), waiting
    458            1.2        ad 	 * for the target LWP to exit.
    459            1.2        ad 	 */
    460            1.2        ad 	if (t != NULL && t->l_stat != LSIDL) {
    461            1.2        ad 		if ((t->l_prflag & LPR_DETACHED) == 0) {
    462            1.2        ad 			p->p_ndlwps++;
    463            1.2        ad 			t->l_prflag |= LPR_DETACHED;
    464            1.2        ad 			if (t->l_stat == LSZOMB) {
    465           1.17        ad 				/* Releases proc mutex. */
    466           1.17        ad 				lwp_free(t, false, false);
    467            1.2        ad 				return 0;
    468            1.2        ad 			}
    469            1.2        ad 			error = 0;
    470           1.17        ad 
    471           1.17        ad 			/*
    472           1.17        ad 			 * Have any LWPs sleeping in lwp_wait() recheck
    473           1.17        ad 			 * for deadlock.
    474           1.17        ad 			 */
    475           1.17        ad 			cv_broadcast(&p->p_lwpcv);
    476            1.2        ad 		} else
    477            1.2        ad 			error = EINVAL;
    478            1.2        ad 	} else
    479            1.2        ad 		error = ESRCH;
    480            1.2        ad 
    481           1.39        ad 	mutex_exit(p->p_lock);
    482            1.2        ad 
    483            1.2        ad 	return error;
    484            1.2        ad }
    485            1.2        ad 
    486            1.2        ad static inline wchan_t
    487            1.2        ad lwp_park_wchan(struct proc *p, const void *hint)
    488            1.2        ad {
    489           1.22        ad 
    490            1.2        ad 	return (wchan_t)((uintptr_t)p ^ (uintptr_t)hint);
    491            1.2        ad }
    492            1.2        ad 
    493            1.2        ad int
    494           1.24        ad lwp_unpark(lwpid_t target, const void *hint)
    495            1.2        ad {
    496           1.24        ad 	sleepq_t *sq;
    497           1.24        ad 	wchan_t wchan;
    498           1.41        ad 	kmutex_t *mp;
    499           1.24        ad 	proc_t *p;
    500           1.24        ad 	lwp_t *t;
    501           1.24        ad 
    502           1.24        ad 	/*
    503           1.24        ad 	 * Easy case: search for the LWP on the sleep queue.  If
    504           1.24        ad 	 * it's parked, remove it from the queue and set running.
    505           1.24        ad 	 */
    506           1.24        ad 	p = curproc;
    507           1.24        ad 	wchan = lwp_park_wchan(p, hint);
    508           1.41        ad 	sq = sleeptab_lookup(&lwp_park_tab, wchan, &mp);
    509           1.24        ad 
    510           1.41        ad 	TAILQ_FOREACH(t, sq, l_sleepchain)
    511           1.24        ad 		if (t->l_proc == p && t->l_lid == target)
    512           1.24        ad 			break;
    513           1.24        ad 
    514           1.24        ad 	if (__predict_true(t != NULL)) {
    515           1.46     rmind 		sleepq_remove(sq, t);
    516           1.41        ad 		mutex_spin_exit(mp);
    517           1.24        ad 		return 0;
    518           1.24        ad 	}
    519           1.24        ad 
    520           1.24        ad 	/*
    521           1.24        ad 	 * The LWP hasn't parked yet.  Take the hit and mark the
    522           1.24        ad 	 * operation as pending.
    523           1.24        ad 	 */
    524           1.41        ad 	mutex_spin_exit(mp);
    525           1.20       dsl 
    526           1.39        ad 	mutex_enter(p->p_lock);
    527           1.24        ad 	if ((t = lwp_find(p, target)) == NULL) {
    528           1.39        ad 		mutex_exit(p->p_lock);
    529           1.24        ad 		return ESRCH;
    530           1.24        ad 	}
    531           1.20       dsl 
    532           1.24        ad 	/*
    533           1.24        ad 	 * It may not have parked yet, we may have raced, or it
    534           1.24        ad 	 * is parked on a different user sync object.
    535           1.24        ad 	 */
    536           1.24        ad 	lwp_lock(t);
    537           1.24        ad 	if (t->l_syncobj == &lwp_park_sobj) {
    538           1.24        ad 		/* Releases the LWP lock. */
    539           1.46     rmind 		lwp_unsleep(t, true);
    540           1.24        ad 	} else {
    541           1.24        ad 		/*
    542           1.24        ad 		 * Set the operation pending.  The next call to _lwp_park
    543           1.24        ad 		 * will return early.
    544           1.24        ad 		 */
    545           1.24        ad 		t->l_flag |= LW_UNPARKED;
    546           1.24        ad 		lwp_unlock(t);
    547           1.24        ad 	}
    548           1.20       dsl 
    549           1.39        ad 	mutex_exit(p->p_lock);
    550           1.24        ad 	return 0;
    551           1.20       dsl }
    552           1.20       dsl 
    553           1.20       dsl int
    554           1.24        ad lwp_park(struct timespec *ts, const void *hint)
    555           1.20       dsl {
    556            1.2        ad 	sleepq_t *sq;
    557           1.41        ad 	kmutex_t *mp;
    558            1.2        ad 	wchan_t wchan;
    559            1.2        ad 	int timo, error;
    560           1.24        ad 	lwp_t *l;
    561            1.2        ad 
    562            1.2        ad 	/* Fix up the given timeout value. */
    563           1.20       dsl 	if (ts != NULL) {
    564           1.48     rmind 		error = abstimeout2timo(ts, &timo);
    565           1.48     rmind 		if (error) {
    566            1.2        ad 			return error;
    567           1.48     rmind 		}
    568           1.24        ad 		KASSERT(timo != 0);
    569           1.48     rmind 	} else {
    570            1.2        ad 		timo = 0;
    571           1.48     rmind 	}
    572            1.2        ad 
    573            1.2        ad 	/* Find and lock the sleep queue. */
    574           1.24        ad 	l = curlwp;
    575           1.20       dsl 	wchan = lwp_park_wchan(l->l_proc, hint);
    576           1.41        ad 	sq = sleeptab_lookup(&lwp_park_tab, wchan, &mp);
    577            1.2        ad 
    578            1.2        ad 	/*
    579            1.2        ad 	 * Before going the full route and blocking, check to see if an
    580            1.2        ad 	 * unpark op is pending.
    581            1.2        ad 	 */
    582           1.19      yamt 	lwp_lock(l);
    583            1.8        ad 	if ((l->l_flag & (LW_CANCELLED | LW_UNPARKED)) != 0) {
    584            1.8        ad 		l->l_flag &= ~(LW_CANCELLED | LW_UNPARKED);
    585           1.19      yamt 		lwp_unlock(l);
    586           1.41        ad 		mutex_spin_exit(mp);
    587            1.2        ad 		return EALREADY;
    588            1.2        ad 	}
    589           1.41        ad 	lwp_unlock_to(l, mp);
    590           1.24        ad 	l->l_biglocks = 0;
    591           1.27        ad 	sleepq_enqueue(sq, wchan, "parked", &lwp_park_sobj);
    592           1.19      yamt 	error = sleepq_block(timo, true);
    593           1.13      yamt 	switch (error) {
    594           1.14      yamt 	case EWOULDBLOCK:
    595           1.14      yamt 		error = ETIMEDOUT;
    596           1.14      yamt 		break;
    597           1.14      yamt 	case ERESTART:
    598           1.14      yamt 		error = EINTR;
    599           1.14      yamt 		break;
    600           1.14      yamt 	default:
    601           1.14      yamt 		/* nothing */
    602           1.14      yamt 		break;
    603           1.13      yamt 	}
    604           1.13      yamt 	return error;
    605            1.2        ad }
    606            1.2        ad 
    607           1.24        ad /*
    608           1.24        ad  * 'park' an LWP waiting on a user-level synchronisation object.  The LWP
    609           1.24        ad  * will remain parked until another LWP in the same process calls in and
    610           1.24        ad  * requests that it be unparked.
    611           1.24        ad  */
    612            1.2        ad int
    613           1.44  christos sys____lwp_park50(struct lwp *l, const struct sys____lwp_park50_args *uap,
    614           1.44  christos     register_t *retval)
    615            1.2        ad {
    616           1.32       dsl 	/* {
    617           1.24        ad 		syscallarg(const struct timespec *)	ts;
    618           1.24        ad 		syscallarg(lwpid_t)			unpark;
    619           1.24        ad 		syscallarg(const void *)		hint;
    620           1.24        ad 		syscallarg(const void *)		unparkhint;
    621           1.32       dsl 	} */
    622           1.24        ad 	struct timespec ts, *tsp;
    623           1.24        ad 	int error;
    624            1.2        ad 
    625           1.24        ad 	if (SCARG(uap, ts) == NULL)
    626           1.24        ad 		tsp = NULL;
    627           1.24        ad 	else {
    628           1.24        ad 		error = copyin(SCARG(uap, ts), &ts, sizeof(ts));
    629           1.24        ad 		if (error != 0)
    630           1.24        ad 			return error;
    631           1.24        ad 		tsp = &ts;
    632           1.24        ad 	}
    633            1.2        ad 
    634           1.24        ad 	if (SCARG(uap, unpark) != 0) {
    635           1.24        ad 		error = lwp_unpark(SCARG(uap, unpark), SCARG(uap, unparkhint));
    636           1.24        ad 		if (error != 0)
    637           1.24        ad 			return error;
    638           1.15        ad 	}
    639           1.15        ad 
    640           1.24        ad 	return lwp_park(tsp, SCARG(uap, hint));
    641           1.24        ad }
    642            1.2        ad 
    643           1.24        ad int
    644           1.47     rmind sys__lwp_unpark(struct lwp *l, const struct sys__lwp_unpark_args *uap,
    645           1.47     rmind     register_t *retval)
    646           1.24        ad {
    647           1.32       dsl 	/* {
    648           1.24        ad 		syscallarg(lwpid_t)		target;
    649           1.24        ad 		syscallarg(const void *)	hint;
    650           1.32       dsl 	} */
    651            1.2        ad 
    652           1.24        ad 	return lwp_unpark(SCARG(uap, target), SCARG(uap, hint));
    653            1.2        ad }
    654            1.2        ad 
    655            1.2        ad int
    656           1.47     rmind sys__lwp_unpark_all(struct lwp *l, const struct sys__lwp_unpark_all_args *uap,
    657           1.47     rmind     register_t *retval)
    658            1.2        ad {
    659           1.32       dsl 	/* {
    660            1.2        ad 		syscallarg(const lwpid_t *)	targets;
    661            1.2        ad 		syscallarg(size_t)		ntargets;
    662            1.2        ad 		syscallarg(const void *)	hint;
    663           1.32       dsl 	} */
    664            1.2        ad 	struct proc *p;
    665            1.2        ad 	struct lwp *t;
    666            1.2        ad 	sleepq_t *sq;
    667            1.2        ad 	wchan_t wchan;
    668            1.2        ad 	lwpid_t targets[32], *tp, *tpp, *tmax, target;
    669           1.46     rmind 	int error;
    670           1.41        ad 	kmutex_t *mp;
    671           1.15        ad 	u_int ntargets;
    672            1.2        ad 	size_t sz;
    673            1.2        ad 
    674            1.2        ad 	p = l->l_proc;
    675            1.2        ad 	ntargets = SCARG(uap, ntargets);
    676            1.2        ad 
    677            1.2        ad 	if (SCARG(uap, targets) == NULL) {
    678            1.2        ad 		/*
    679            1.2        ad 		 * Let the caller know how much we are willing to do, and
    680            1.2        ad 		 * let it unpark the LWPs in blocks.
    681            1.2        ad 		 */
    682            1.2        ad 		*retval = LWP_UNPARK_MAX;
    683            1.2        ad 		return 0;
    684            1.2        ad 	}
    685            1.2        ad 	if (ntargets > LWP_UNPARK_MAX || ntargets == 0)
    686            1.2        ad 		return EINVAL;
    687            1.2        ad 
    688            1.2        ad 	/*
    689            1.2        ad 	 * Copy in the target array.  If it's a small number of LWPs, then
    690            1.2        ad 	 * place the numbers on the stack.
    691            1.2        ad 	 */
    692            1.2        ad 	sz = sizeof(target) * ntargets;
    693            1.2        ad 	if (sz <= sizeof(targets))
    694            1.2        ad 		tp = targets;
    695            1.2        ad 	else {
    696            1.2        ad 		tp = kmem_alloc(sz, KM_SLEEP);
    697            1.2        ad 		if (tp == NULL)
    698            1.2        ad 			return ENOMEM;
    699            1.2        ad 	}
    700            1.2        ad 	error = copyin(SCARG(uap, targets), tp, sz);
    701            1.2        ad 	if (error != 0) {
    702            1.2        ad 		if (tp != targets) {
    703            1.2        ad 			kmem_free(tp, sz);
    704            1.2        ad 		}
    705            1.2        ad 		return error;
    706            1.2        ad 	}
    707            1.2        ad 
    708            1.2        ad 	wchan = lwp_park_wchan(p, SCARG(uap, hint));
    709           1.41        ad 	sq = sleeptab_lookup(&lwp_park_tab, wchan, &mp);
    710            1.2        ad 
    711            1.2        ad 	for (tmax = tp + ntargets, tpp = tp; tpp < tmax; tpp++) {
    712            1.2        ad 		target = *tpp;
    713            1.2        ad 
    714            1.2        ad 		/*
    715            1.2        ad 		 * Easy case: search for the LWP on the sleep queue.  If
    716            1.2        ad 		 * it's parked, remove it from the queue and set running.
    717            1.2        ad 		 */
    718           1.41        ad 		TAILQ_FOREACH(t, sq, l_sleepchain)
    719            1.2        ad 			if (t->l_proc == p && t->l_lid == target)
    720            1.2        ad 				break;
    721            1.2        ad 
    722            1.2        ad 		if (t != NULL) {
    723           1.46     rmind 			sleepq_remove(sq, t);
    724            1.2        ad 			continue;
    725            1.2        ad 		}
    726            1.2        ad 
    727            1.2        ad 		/*
    728            1.2        ad 		 * The LWP hasn't parked yet.  Take the hit and
    729            1.2        ad 		 * mark the operation as pending.
    730            1.2        ad 		 */
    731           1.41        ad 		mutex_spin_exit(mp);
    732           1.39        ad 		mutex_enter(p->p_lock);
    733            1.2        ad 		if ((t = lwp_find(p, target)) == NULL) {
    734           1.39        ad 			mutex_exit(p->p_lock);
    735           1.41        ad 			mutex_spin_enter(mp);
    736            1.2        ad 			continue;
    737            1.2        ad 		}
    738            1.2        ad 		lwp_lock(t);
    739            1.2        ad 
    740           1.15        ad 		/*
    741           1.15        ad 		 * It may not have parked yet, we may have raced, or
    742           1.15        ad 		 * it is parked on a different user sync object.
    743           1.15        ad 		 */
    744           1.15        ad 		if (t->l_syncobj == &lwp_park_sobj) {
    745           1.15        ad 			/* Releases the LWP lock. */
    746           1.46     rmind 			lwp_unsleep(t, true);
    747            1.2        ad 		} else {
    748            1.2        ad 			/*
    749           1.15        ad 			 * Set the operation pending.  The next call to
    750           1.15        ad 			 * _lwp_park will return early.
    751            1.2        ad 			 */
    752            1.8        ad 			t->l_flag |= LW_UNPARKED;
    753            1.2        ad 			lwp_unlock(t);
    754            1.2        ad 		}
    755           1.15        ad 
    756           1.39        ad 		mutex_exit(p->p_lock);
    757           1.41        ad 		mutex_spin_enter(mp);
    758            1.2        ad 	}
    759            1.2        ad 
    760           1.41        ad 	mutex_spin_exit(mp);
    761           1.33        ad 	if (tp != targets)
    762            1.2        ad 		kmem_free(tp, sz);
    763           1.15        ad 
    764            1.2        ad 	return 0;
    765            1.2        ad }
    766           1.28        ad 
    767           1.28        ad int
    768           1.47     rmind sys__lwp_setname(struct lwp *l, const struct sys__lwp_setname_args *uap,
    769           1.47     rmind     register_t *retval)
    770           1.28        ad {
    771           1.32       dsl 	/* {
    772           1.28        ad 		syscallarg(lwpid_t)		target;
    773           1.28        ad 		syscallarg(const char *)	name;
    774           1.32       dsl 	} */
    775           1.28        ad 	char *name, *oname;
    776           1.30        ad 	lwpid_t target;
    777           1.28        ad 	proc_t *p;
    778           1.28        ad 	lwp_t *t;
    779           1.28        ad 	int error;
    780           1.28        ad 
    781           1.30        ad 	if ((target = SCARG(uap, target)) == 0)
    782           1.30        ad 		target = l->l_lid;
    783           1.30        ad 
    784           1.28        ad 	name = kmem_alloc(MAXCOMLEN, KM_SLEEP);
    785           1.28        ad 	if (name == NULL)
    786           1.28        ad 		return ENOMEM;
    787           1.28        ad 	error = copyinstr(SCARG(uap, name), name, MAXCOMLEN, NULL);
    788           1.28        ad 	switch (error) {
    789           1.28        ad 	case ENAMETOOLONG:
    790           1.28        ad 	case 0:
    791           1.28        ad 		name[MAXCOMLEN - 1] = '\0';
    792           1.28        ad 		break;
    793           1.28        ad 	default:
    794           1.28        ad 		kmem_free(name, MAXCOMLEN);
    795           1.28        ad 		return error;
    796           1.28        ad 	}
    797           1.28        ad 
    798           1.28        ad 	p = curproc;
    799           1.39        ad 	mutex_enter(p->p_lock);
    800           1.30        ad 	if ((t = lwp_find(p, target)) == NULL) {
    801           1.39        ad 		mutex_exit(p->p_lock);
    802           1.28        ad 		kmem_free(name, MAXCOMLEN);
    803           1.28        ad 		return ESRCH;
    804           1.28        ad 	}
    805           1.28        ad 	lwp_lock(t);
    806           1.28        ad 	oname = t->l_name;
    807           1.28        ad 	t->l_name = name;
    808           1.28        ad 	lwp_unlock(t);
    809           1.39        ad 	mutex_exit(p->p_lock);
    810           1.28        ad 
    811           1.28        ad 	if (oname != NULL)
    812           1.28        ad 		kmem_free(oname, MAXCOMLEN);
    813           1.28        ad 
    814           1.28        ad 	return 0;
    815           1.28        ad }
    816           1.28        ad 
    817           1.28        ad int
    818           1.47     rmind sys__lwp_getname(struct lwp *l, const struct sys__lwp_getname_args *uap,
    819           1.47     rmind     register_t *retval)
    820           1.28        ad {
    821           1.32       dsl 	/* {
    822           1.28        ad 		syscallarg(lwpid_t)		target;
    823           1.28        ad 		syscallarg(char *)		name;
    824           1.28        ad 		syscallarg(size_t)		len;
    825           1.32       dsl 	} */
    826           1.28        ad 	char name[MAXCOMLEN];
    827           1.30        ad 	lwpid_t target;
    828           1.28        ad 	proc_t *p;
    829           1.28        ad 	lwp_t *t;
    830           1.28        ad 
    831           1.30        ad 	if ((target = SCARG(uap, target)) == 0)
    832           1.30        ad 		target = l->l_lid;
    833           1.30        ad 
    834           1.28        ad 	p = curproc;
    835           1.39        ad 	mutex_enter(p->p_lock);
    836           1.30        ad 	if ((t = lwp_find(p, target)) == NULL) {
    837           1.39        ad 		mutex_exit(p->p_lock);
    838           1.28        ad 		return ESRCH;
    839           1.28        ad 	}
    840           1.28        ad 	lwp_lock(t);
    841           1.28        ad 	if (t->l_name == NULL)
    842           1.28        ad 		name[0] = '\0';
    843           1.28        ad 	else
    844           1.28        ad 		strcpy(name, t->l_name);
    845           1.28        ad 	lwp_unlock(t);
    846           1.39        ad 	mutex_exit(p->p_lock);
    847           1.28        ad 
    848           1.28        ad 	return copyoutstr(name, SCARG(uap, name), SCARG(uap, len), NULL);
    849           1.28        ad }
    850           1.30        ad 
    851           1.30        ad int
    852           1.47     rmind sys__lwp_ctl(struct lwp *l, const struct sys__lwp_ctl_args *uap,
    853           1.47     rmind     register_t *retval)
    854           1.30        ad {
    855           1.32       dsl 	/* {
    856           1.30        ad 		syscallarg(int)			features;
    857           1.30        ad 		syscallarg(struct lwpctl **)	address;
    858           1.32       dsl 	} */
    859           1.30        ad 	int error, features;
    860           1.30        ad 	vaddr_t vaddr;
    861           1.30        ad 
    862           1.30        ad 	features = SCARG(uap, features);
    863           1.35        ad 	features &= ~(LWPCTL_FEATURE_CURCPU | LWPCTL_FEATURE_PCTR);
    864           1.35        ad 	if (features != 0)
    865           1.30        ad 		return ENODEV;
    866           1.30        ad 	if ((error = lwp_ctl_alloc(&vaddr)) != 0)
    867           1.30        ad 		return error;
    868           1.30        ad 	return copyout(&vaddr, SCARG(uap, address), sizeof(void *));
    869           1.30        ad }
    870