1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 27 28 #pragma ident "%Z%%M% %I% %E% SMI" 29 30 #include <sys/param.h> 31 #include <sys/types.h> 32 #include <sys/sysmacros.h> 33 #include <sys/systm.h> 34 #include <sys/prsystm.h> 35 #include <sys/cred.h> 36 #include <sys/errno.h> 37 #include <sys/proc.h> 38 #include <sys/signal.h> 39 #include <sys/kmem.h> 40 #include <sys/unistd.h> 41 #include <sys/cmn_err.h> 42 #include <sys/schedctl.h> 43 #include <sys/debug.h> 44 #include <sys/contract/process_impl.h> 45 46 kthread_t * 47 idtot(proc_t *p, id_t lwpid) 48 { 49 lwpdir_t *ldp; 50 51 if ((ldp = lwp_hash_lookup(p, lwpid)) != NULL) 52 return (ldp->ld_entry->le_thread); 53 return (NULL); 54 } 55 56 /* 57 * Stop an lwp of the current process 58 */ 59 int 60 syslwp_suspend(id_t lwpid) 61 { 62 kthread_t *t; 63 int error; 64 proc_t *p = ttoproc(curthread); 65 66 mutex_enter(&p->p_lock); 67 if ((t = idtot(p, lwpid)) == NULL) 68 error = ESRCH; 69 else 70 error = lwp_suspend(t); 71 mutex_exit(&p->p_lock); 72 if (error) 73 return (set_errno(error)); 74 return (0); 75 } 76 77 int 78 syslwp_continue(id_t lwpid) 79 { 80 kthread_t *t; 81 proc_t *p = ttoproc(curthread); 82 83 mutex_enter(&p->p_lock); 84 if ((t = idtot(p, lwpid)) == NULL) { 85 mutex_exit(&p->p_lock); 86 return (set_errno(ESRCH)); 87 } 88 lwp_continue(t); 89 mutex_exit(&p->p_lock); 90 return (0); 91 } 92 93 int 94 lwp_kill(id_t lwpid, int sig) 95 { 96 sigqueue_t *sqp; 97 kthread_t *t; 98 proc_t *p = ttoproc(curthread); 99 100 if (sig < 0 || sig >= NSIG) 101 return (set_errno(EINVAL)); 102 if (sig != 0) 103 sqp = kmem_zalloc(sizeof (sigqueue_t), KM_SLEEP); 104 mutex_enter(&p->p_lock); 105 if ((t = idtot(p, lwpid)) == NULL) { 106 mutex_exit(&p->p_lock); 107 if (sig != 0) 108 kmem_free(sqp, sizeof (sigqueue_t)); 109 return (set_errno(ESRCH)); 110 } 111 if (sig == 0) { 112 mutex_exit(&p->p_lock); 113 return (0); 114 } 115 sqp->sq_info.si_signo = sig; 116 sqp->sq_info.si_code = SI_LWP; 117 sqp->sq_info.si_pid = p->p_pid; 118 sqp->sq_info.si_ctid = PRCTID(p); 119 sqp->sq_info.si_zoneid = getzoneid(); 120 sqp->sq_info.si_uid = crgetruid(CRED()); 121 sigaddqa(p, t, sqp); 122 mutex_exit(&p->p_lock); 123 return (0); 124 } 125 126 /* 127 * This is the specification of lwp_wait() from the _lwp_wait(2) manual page: 128 * 129 * The lwp_wait() function blocks the current lwp until the lwp specified 130 * by 'lwpid' terminates. If the specified lwp terminated prior to the call 131 * to lwp_wait(), then lwp_wait() returns immediately. If 'lwpid' is zero, 132 * then lwp_wait() waits for any undetached lwp in the current process. 133 * If 'lwpid' is not zero, then it must specify an undetached lwp in the 134 * current process. If 'departed' is not NULL, then it points to a location 135 * where the id of the exited lwp is stored. 136 * 137 * When an lwp exits and there are one or more lwps in the process waiting 138 * for this specific lwp to exit, then one of the waiting lwps is unblocked 139 * and it returns from lwp_wait() successfully. Any other lwps waiting for 140 * this same lwp to exit are also unblocked, however, they return from 141 * lwp_wait() with the error ESRCH. If there are no lwps in the process 142 * waiting for this specific lwp to exit but there are one or more lwps 143 * waiting for any lwp to exit, then one of the waiting lwps is unblocked 144 * and it returns from lwp_wait() successfully. 145 * 146 * If an lwp is waiting for any lwp to exit, it blocks until an undetached 147 * lwp for which no other lwp is waiting terminates, at which time it returns 148 * successfully, or until all other lwps in the process are either daemon 149 * lwps or lwps waiting in lwp_wait(), in which case it returns EDEADLK. 150 */ 151 int 152 lwp_wait(id_t lwpid, id_t *departed) 153 { 154 proc_t *p = ttoproc(curthread); 155 int error = 0; 156 int daemon = (curthread->t_proc_flag & TP_DAEMON)? 1 : 0; 157 lwpent_t *target_lep; 158 lwpdir_t *ldp; 159 lwpent_t *lep; 160 161 /* 162 * lwp_wait() is not supported for the /proc agent lwp. 163 */ 164 if (curthread == p->p_agenttp) 165 return (set_errno(ENOTSUP)); 166 167 mutex_enter(&p->p_lock); 168 prbarrier(p); 169 170 curthread->t_waitfor = lwpid; 171 p->p_lwpwait++; 172 p->p_lwpdwait += daemon; 173 174 if (lwpid != 0) { 175 if ((ldp = lwp_hash_lookup(p, lwpid)) == NULL) 176 target_lep = NULL; 177 else { 178 target_lep = ldp->ld_entry; 179 target_lep->le_waiters++; 180 target_lep->le_dwaiters += daemon; 181 } 182 } 183 184 while (error == 0) { 185 kthread_t *t; 186 id_t tid; 187 int i; 188 189 if (lwpid != 0) { 190 /* 191 * Look for a specific zombie lwp. 192 */ 193 if (target_lep == NULL) 194 error = ESRCH; 195 else if ((t = target_lep->le_thread) != NULL) { 196 if (!(t->t_proc_flag & TP_TWAIT)) 197 error = EINVAL; 198 } else { 199 /* 200 * We found the zombie we are waiting for. 201 */ 202 ASSERT(p->p_zombcnt > 0); 203 p->p_zombcnt--; 204 p->p_lwpwait--; 205 p->p_lwpdwait -= daemon; 206 curthread->t_waitfor = -1; 207 lwp_hash_out(p, lwpid); 208 mutex_exit(&p->p_lock); 209 if (departed != NULL && 210 copyout(&lwpid, departed, sizeof (id_t))) 211 return (set_errno(EFAULT)); 212 return (0); 213 } 214 } else { 215 /* 216 * Look for any zombie lwp. 217 */ 218 int some_non_daemon_will_return = 0; 219 220 /* for each entry in the lwp directory... */ 221 ldp = p->p_lwpdir; 222 for (i = 0; i < p->p_lwpdir_sz; i++, ldp++) { 223 224 if ((lep = ldp->ld_entry) == NULL || 225 lep->le_thread != NULL) 226 continue; 227 228 /* 229 * We found a zombie lwp. If there is some 230 * other thread waiting specifically for the 231 * zombie we just found, then defer to the other 232 * waiting thread and continue searching for 233 * another zombie. Also check to see if there 234 * is some non-daemon thread sleeping here in 235 * lwp_wait() that will succeed and return when 236 * we drop p->p_lock. This is tested below. 237 */ 238 tid = lep->le_lwpid; 239 if (lep->le_waiters != 0) { 240 if (lep->le_waiters - lep->le_dwaiters) 241 some_non_daemon_will_return = 1; 242 continue; 243 } 244 245 /* 246 * We found a zombie that no one else 247 * is specifically waiting for. 248 */ 249 ASSERT(p->p_zombcnt > 0); 250 p->p_zombcnt--; 251 p->p_lwpwait--; 252 p->p_lwpdwait -= daemon; 253 curthread->t_waitfor = -1; 254 lwp_hash_out(p, tid); 255 mutex_exit(&p->p_lock); 256 if (departed != NULL && 257 copyout(&tid, departed, sizeof (id_t))) 258 return (set_errno(EFAULT)); 259 return (0); 260 } 261 262 /* 263 * We are waiting for anyone. If all non-daemon lwps 264 * are waiting here, and if we determined above that 265 * no non-daemon lwp will return, we have deadlock. 266 */ 267 if (!some_non_daemon_will_return && 268 p->p_lwpcnt == p->p_lwpdaemon + 269 (p->p_lwpwait - p->p_lwpdwait)) 270 error = EDEADLK; 271 } 272 273 if (error == 0 && lwpid != 0) { 274 /* 275 * We are waiting for a specific non-zombie lwp. 276 * Fail if there is a deadlock loop. 277 */ 278 for (;;) { 279 if (t == curthread) { 280 error = EDEADLK; 281 break; 282 } 283 /* who is he waiting for? */ 284 if ((tid = t->t_waitfor) == -1) 285 break; 286 if (tid == 0) { 287 /* 288 * The lwp we are waiting for is 289 * waiting for anyone (transitively). 290 * If there are no zombies right now 291 * and if we would have deadlock due 292 * to all non-daemon lwps waiting here, 293 * wake up the lwp that is waiting for 294 * anyone so it can return EDEADLK. 295 */ 296 if (p->p_zombcnt == 0 && 297 p->p_lwpcnt == p->p_lwpdaemon + 298 p->p_lwpwait - p->p_lwpdwait) 299 cv_broadcast(&p->p_lwpexit); 300 break; 301 } 302 if ((ldp = lwp_hash_lookup(p, tid)) == NULL || 303 (t = ldp->ld_entry->le_thread) == NULL) 304 break; 305 } 306 } 307 308 if (error) 309 break; 310 311 /* 312 * Wait for some lwp to terminate. 313 */ 314 if (!cv_wait_sig(&p->p_lwpexit, &p->p_lock)) 315 error = EINTR; 316 prbarrier(p); 317 318 if (lwpid != 0) { 319 if ((ldp = lwp_hash_lookup(p, lwpid)) == NULL) 320 target_lep = NULL; 321 else 322 target_lep = ldp->ld_entry; 323 } 324 } 325 326 if (lwpid != 0 && target_lep != NULL) { 327 target_lep->le_waiters--; 328 target_lep->le_dwaiters -= daemon; 329 } 330 p->p_lwpwait--; 331 p->p_lwpdwait -= daemon; 332 curthread->t_waitfor = -1; 333 mutex_exit(&p->p_lock); 334 return (set_errno(error)); 335 } 336 337 int 338 lwp_detach(id_t lwpid) 339 { 340 kthread_t *t; 341 proc_t *p = ttoproc(curthread); 342 lwpdir_t *ldp; 343 int error = 0; 344 345 mutex_enter(&p->p_lock); 346 prbarrier(p); 347 if ((ldp = lwp_hash_lookup(p, lwpid)) == NULL) 348 error = ESRCH; 349 else if ((t = ldp->ld_entry->le_thread) != NULL) { 350 if (!(t->t_proc_flag & TP_TWAIT)) 351 error = EINVAL; 352 else { 353 t->t_proc_flag &= ~TP_TWAIT; 354 cv_broadcast(&p->p_lwpexit); 355 } 356 } else { 357 ASSERT(p->p_zombcnt > 0); 358 p->p_zombcnt--; 359 lwp_hash_out(p, lwpid); 360 } 361 mutex_exit(&p->p_lock); 362 363 if (error) 364 return (set_errno(error)); 365 return (0); 366 } 367 368 /* 369 * Unpark the specified lwp. 370 */ 371 static int 372 lwp_unpark(id_t lwpid) 373 { 374 proc_t *p = ttoproc(curthread); 375 kthread_t *t; 376 int error = 0; 377 378 mutex_enter(&p->p_lock); 379 if ((t = idtot(p, lwpid)) == NULL) 380 error = ESRCH; 381 else { 382 mutex_enter(&t->t_delay_lock); 383 t->t_unpark = 1; 384 cv_signal(&t->t_delay_cv); 385 mutex_exit(&t->t_delay_lock); 386 } 387 mutex_exit(&p->p_lock); 388 return (error); 389 } 390 391 /* 392 * Sleep until we are set running by lwp_unpark() or until we are 393 * interrupted by a signal or until we exhaust our timeout. 394 * timeoutp is an in/out parameter. On entry, it contains the relative 395 * time until timeout. On exit, we copyout the residual time left to it. 396 */ 397 static int 398 lwp_park(timespec_t *timeoutp, id_t lwpid) 399 { 400 timespec_t rqtime; 401 timespec_t rmtime; 402 timespec_t now; 403 timespec_t *rqtp = NULL; 404 kthread_t *t = curthread; 405 int error = 0; 406 model_t datamodel = ttoproc(t)->p_model; 407 408 if (lwpid != 0) /* unpark the other lwp, if any */ 409 (void) lwp_unpark(lwpid); 410 411 if (timeoutp) { 412 gethrestime(&now); 413 if (datamodel == DATAMODEL_NATIVE) { 414 if (copyin(timeoutp, &rqtime, sizeof (timespec_t))) { 415 error = EFAULT; 416 goto out; 417 } 418 } else { 419 timespec32_t timeout32; 420 421 if (copyin(timeoutp, &timeout32, sizeof (timeout32))) { 422 error = EFAULT; 423 goto out; 424 } 425 TIMESPEC32_TO_TIMESPEC(&rqtime, &timeout32) 426 } 427 428 if (itimerspecfix(&rqtime)) { 429 error = EINVAL; 430 goto out; 431 } 432 /* 433 * Convert the timespec value into absolute time. 434 */ 435 timespecadd(&rqtime, &now); 436 rqtp = &rqtime; 437 } 438 439 (void) new_mstate(t, LMS_USER_LOCK); 440 441 mutex_enter(&t->t_delay_lock); 442 if (!schedctl_is_park()) 443 error = EINTR; 444 while (error == 0 && t->t_unpark == 0) { 445 switch (cv_waituntil_sig(&t->t_delay_cv, 446 &t->t_delay_lock, rqtp)) { 447 case 0: 448 error = EINTR; 449 break; 450 case -1: 451 error = ETIME; 452 break; 453 } 454 } 455 t->t_unpark = 0; 456 mutex_exit(&t->t_delay_lock); 457 458 if (timeoutp != NULL) { 459 rmtime.tv_sec = rmtime.tv_nsec = 0; 460 if (error != ETIME) { 461 gethrestime(&now); 462 if ((now.tv_sec < rqtime.tv_sec) || 463 ((now.tv_sec == rqtime.tv_sec) && 464 (now.tv_nsec < rqtime.tv_nsec))) { 465 rmtime = rqtime; 466 timespecsub(&rmtime, &now); 467 } 468 } 469 if (datamodel == DATAMODEL_NATIVE) { 470 if (copyout(&rmtime, timeoutp, sizeof (rmtime))) 471 error = EFAULT; 472 } else { 473 timespec32_t rmtime32; 474 475 TIMESPEC_TO_TIMESPEC32(&rmtime32, &rmtime); 476 if (copyout(&rmtime32, timeoutp, sizeof (rmtime32))) 477 error = EFAULT; 478 } 479 } 480 out: 481 schedctl_unpark(); 482 if (t->t_mstate == LMS_USER_LOCK) 483 (void) new_mstate(t, LMS_SYSTEM); 484 return (error); 485 } 486 487 #define MAXLWPIDS 1024 488 489 /* 490 * Unpark all of the specified lwps. 491 * Do it in chunks of MAXLWPIDS to avoid allocating too much memory. 492 */ 493 static int 494 lwp_unpark_all(id_t *lwpidp, int nids) 495 { 496 proc_t *p = ttoproc(curthread); 497 kthread_t *t; 498 int error = 0; 499 id_t *lwpid; 500 size_t lwpidsz; 501 int n; 502 int i; 503 504 if (nids <= 0) 505 return (EINVAL); 506 507 lwpidsz = MIN(nids, MAXLWPIDS) * sizeof (id_t); 508 lwpid = kmem_alloc(lwpidsz, KM_SLEEP); 509 while (nids > 0) { 510 n = MIN(nids, MAXLWPIDS); 511 if (copyin(lwpidp, lwpid, n * sizeof (id_t))) { 512 error = EFAULT; 513 break; 514 } 515 mutex_enter(&p->p_lock); 516 for (i = 0; i < n; i++) { 517 if ((t = idtot(p, lwpid[i])) == NULL) 518 error = ESRCH; 519 else { 520 mutex_enter(&t->t_delay_lock); 521 t->t_unpark = 1; 522 cv_signal(&t->t_delay_cv); 523 mutex_exit(&t->t_delay_lock); 524 } 525 } 526 mutex_exit(&p->p_lock); 527 lwpidp += n; 528 nids -= n; 529 } 530 kmem_free(lwpid, lwpidsz); 531 return (error); 532 } 533 534 /* 535 * SYS_lwp_park() system call. 536 */ 537 int 538 syslwp_park(int which, uintptr_t arg1, uintptr_t arg2) 539 { 540 int error; 541 542 switch (which) { 543 case 0: 544 error = lwp_park((timespec_t *)arg1, (id_t)arg2); 545 break; 546 case 1: 547 error = lwp_unpark((id_t)arg1); 548 break; 549 case 2: 550 error = lwp_unpark_all((id_t *)arg1, (int)arg2); 551 break; 552 default: 553 error = EINVAL; 554 break; 555 } 556 557 if (error) 558 return (set_errno(error)); 559 return (0); 560 } 561