2 * Copyright (c) 2003, Jeffrey Roberson <jeff@freebsd.org>
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice unmodified, this list of conditions, and the following
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 #include <sys/cdefs.h>
28 __FBSDID("$FreeBSD$");
30 #include "opt_compat.h"
31 #include "opt_posix.h"
32 #include <sys/param.h>
33 #include <sys/kernel.h>
35 #include <sys/mutex.h>
38 #include <sys/posix4.h>
39 #include <sys/resourcevar.h>
40 #include <sys/sched.h>
41 #include <sys/sysctl.h>
43 #include <sys/syscallsubr.h>
44 #include <sys/sysent.h>
45 #include <sys/systm.h>
46 #include <sys/sysproto.h>
47 #include <sys/signalvar.h>
48 #include <sys/ucontext.h>
50 #include <sys/rtprio.h>
52 #include <sys/limits.h>
54 #include <machine/frame.h>
56 #include <security/audit/audit.h>
60 extern struct sysentvec ia32_freebsd_sysvec
;
63 suword_lwpid(void *addr
, lwpid_t lwpid
)
67 if (curproc
->p_sysent
!= &ia32_freebsd_sysvec
)
68 error
= suword(addr
, lwpid
);
70 error
= suword32(addr
, lwpid
);
75 #define suword_lwpid suword
78 extern int max_threads_per_proc
;
80 static int create_thread(struct thread
*td
, mcontext_t
*ctx
,
81 void (*start_func
)(void *), void *arg
,
82 char *stack_base
, size_t stack_size
,
84 long *child_tid
, long *parent_tid
,
85 int flags
, struct rtprio
*rtp
);
88 * System call interface.
91 thr_create(struct thread
*td
, struct thr_create_args
*uap
)
92 /* ucontext_t *ctx, long *id, int flags */
97 if ((error
= copyin(uap
->ctx
, &ctx
, sizeof(ctx
))))
100 error
= create_thread(td
, &ctx
.uc_mcontext
, NULL
, NULL
,
101 NULL
, 0, NULL
, uap
->id
, NULL
, uap
->flags
, NULL
);
106 thr_new(struct thread
*td
, struct thr_new_args
*uap
)
107 /* struct thr_param * */
109 struct thr_param param
;
112 if (uap
->param_size
< 0 || uap
->param_size
> sizeof(param
))
114 bzero(¶m
, sizeof(param
));
115 if ((error
= copyin(uap
->param
, ¶m
, uap
->param_size
)))
117 return (kern_thr_new(td
, ¶m
));
121 kern_thr_new(struct thread
*td
, struct thr_param
*param
)
123 struct rtprio rtp
, *rtpp
;
127 if (param
->rtp
!= 0) {
128 error
= copyin(param
->rtp
, &rtp
, sizeof(struct rtprio
));
131 error
= create_thread(td
, NULL
, param
->start_func
, param
->arg
,
132 param
->stack_base
, param
->stack_size
, param
->tls_base
,
133 param
->child_tid
, param
->parent_tid
, param
->flags
,
139 create_thread(struct thread
*td
, mcontext_t
*ctx
,
140 void (*start_func
)(void *), void *arg
,
141 char *stack_base
, size_t stack_size
,
143 long *child_tid
, long *parent_tid
,
144 int flags
, struct rtprio
*rtp
)
147 struct thread
*newtd
;
154 /* Have race condition but it is cheap. */
155 if (p
->p_numthreads
>= max_threads_per_proc
)
160 case RTP_PRIO_REALTIME
:
162 /* Only root can set scheduler policy */
163 if (priv_check(td
, PRIV_SCHED_SETPOLICY
) != 0)
165 if (rtp
->prio
> RTP_PRIO_MAX
)
168 case RTP_PRIO_NORMAL
:
176 /* Initialize our td */
177 newtd
= thread_alloc();
182 * Try the copyout as soon as we allocate the td so we don't
183 * have to tear things down in a failure case below.
184 * Here we copy out tid to two places, one for child and one
185 * for parent, because pthread can create a detached thread,
186 * if parent wants to safely access child tid, it has to provide
187 * its storage, because child thread may exit quickly and
188 * memory is freed before parent thread can access it.
190 if ((child_tid
!= NULL
&&
191 suword_lwpid(child_tid
, newtd
->td_tid
)) ||
192 (parent_tid
!= NULL
&&
193 suword_lwpid(parent_tid
, newtd
->td_tid
))) {
198 bzero(&newtd
->td_startzero
,
199 __rangeof(struct thread
, td_startzero
, td_endzero
));
200 bcopy(&td
->td_startcopy
, &newtd
->td_startcopy
,
201 __rangeof(struct thread
, td_startcopy
, td_endcopy
));
202 newtd
->td_proc
= td
->td_proc
;
203 newtd
->td_ucred
= crhold(td
->td_ucred
);
205 cpu_set_upcall(newtd
, td
);
207 if (ctx
!= NULL
) { /* old way to set user context */
208 error
= set_mcontext(newtd
, ctx
);
211 crfree(td
->td_ucred
);
215 /* Set up our machine context. */
216 stack
.ss_sp
= stack_base
;
217 stack
.ss_size
= stack_size
;
218 /* Set upcall address to user thread entry function. */
219 cpu_set_upcall_kse(newtd
, start_func
, arg
, &stack
);
220 /* Setup user TLS address and TLS pointer register. */
221 error
= cpu_set_user_tls(newtd
, tls_base
);
224 crfree(td
->td_ucred
);
229 PROC_LOCK(td
->td_proc
);
230 td
->td_proc
->p_flag
|= P_HADTHREADS
;
231 newtd
->td_sigmask
= td
->td_sigmask
;
232 thread_link(newtd
, p
);
233 bcopy(p
->p_comm
, newtd
->td_name
, sizeof(newtd
->td_name
));
235 /* let the scheduler know about these things. */
236 sched_fork_thread(td
, newtd
);
239 newtd
->td_flags
|= TDF_ASTPENDING
| TDF_NEEDSUSPCHK
;
243 if (!(td
->td_pri_class
== PRI_TIMESHARE
&&
244 rtp
->type
== RTP_PRIO_NORMAL
)) {
245 rtp_to_pri(rtp
, newtd
);
246 sched_prio(newtd
, newtd
->td_user_pri
);
247 } /* ignore timesharing class */
249 TD_SET_CAN_RUN(newtd
);
250 sched_add(newtd
, SRQ_BORING
);
251 thread_unlock(newtd
);
257 thr_self(struct thread
*td
, struct thr_self_args
*uap
)
262 error
= suword_lwpid(uap
->id
, (unsigned)td
->td_tid
);
269 thr_exit(struct thread
*td
, struct thr_exit_args
*uap
)
276 /* Signal userland that it can free the stack. */
277 if ((void *)uap
->state
!= NULL
) {
278 suword_lwpid(uap
->state
, 1);
279 kern_umtx_wake(td
, uap
->state
, INT_MAX
, 0);
283 sigqueue_flush(&td
->td_sigqueue
);
287 * Shutting down last thread in the proc. This will actually
288 * call exit() in the trampoline when it returns.
290 if (p
->p_numthreads
!= 1) {
301 thr_kill(struct thread
*td
, struct thr_kill_args
*uap
)
302 /* long id, int sig */
312 if (uap
->sig
!= 0 && !_SIG_VALID(uap
->sig
)) {
316 FOREACH_THREAD_IN_PROC(p
, ttd
) {
321 tdsignal(p
, ttd
, uap
->sig
, NULL
);
326 if (uap
->id
!= td
->td_tid
)
327 ttd
= thread_find(p
, uap
->id
);
332 else if (uap
->sig
== 0)
334 else if (!_SIG_VALID(uap
->sig
))
337 tdsignal(p
, ttd
, uap
->sig
, NULL
);
344 thr_kill2(struct thread
*td
, struct thr_kill2_args
*uap
)
345 /* pid_t pid, long id, int sig */
351 AUDIT_ARG(signum
, uap
->sig
);
353 if (uap
->pid
== td
->td_proc
->p_pid
) {
356 } else if ((p
= pfind(uap
->pid
)) == NULL
) {
359 AUDIT_ARG(process
, p
);
361 error
= p_cansignal(td
, p
, uap
->sig
);
364 if (uap
->sig
!= 0 && !_SIG_VALID(uap
->sig
)) {
368 FOREACH_THREAD_IN_PROC(p
, ttd
) {
373 tdsignal(p
, ttd
, uap
->sig
, NULL
);
378 if (uap
->id
!= td
->td_tid
)
379 ttd
= thread_find(p
, uap
->id
);
384 else if (uap
->sig
== 0)
386 else if (!_SIG_VALID(uap
->sig
))
389 tdsignal(p
, ttd
, uap
->sig
, NULL
);
397 thr_suspend(struct thread
*td
, struct thr_suspend_args
*uap
)
398 /* const struct timespec *timeout */
400 struct timespec ts
, *tsp
;
405 if (uap
->timeout
!= NULL
) {
406 error
= copyin((const void *)uap
->timeout
, (void *)&ts
,
407 sizeof(struct timespec
));
413 return (kern_thr_suspend(td
, tsp
));
417 kern_thr_suspend(struct thread
*td
, struct timespec
*tsp
)
420 int error
= 0, hz
= 0;
423 if (tsp
->tv_nsec
< 0 || tsp
->tv_nsec
> 1000000000)
425 if (tsp
->tv_sec
== 0 && tsp
->tv_nsec
== 0)
427 TIMESPEC_TO_TIMEVAL(&tv
, tsp
);
431 if (td
->td_pflags
& TDP_WAKEUP
) {
432 td
->td_pflags
&= ~TDP_WAKEUP
;
436 PROC_LOCK(td
->td_proc
);
437 if ((td
->td_flags
& TDF_THRWAKEUP
) == 0)
438 error
= msleep((void *)td
, &td
->td_proc
->p_mtx
, PCATCH
, "lthr",
440 if (td
->td_flags
& TDF_THRWAKEUP
) {
442 td
->td_flags
&= ~TDF_THRWAKEUP
;
444 PROC_UNLOCK(td
->td_proc
);
447 PROC_UNLOCK(td
->td_proc
);
448 if (error
== EWOULDBLOCK
)
450 else if (error
== ERESTART
) {
458 thr_wake(struct thread
*td
, struct thr_wake_args
*uap
)
464 if (uap
->id
== td
->td_tid
) {
465 td
->td_pflags
|= TDP_WAKEUP
;
471 ttd
= thread_find(p
, uap
->id
);
477 ttd
->td_flags
|= TDF_THRWAKEUP
;
485 thr_set_name(struct thread
*td
, struct thr_set_name_args
*uap
)
487 struct proc
*p
= td
->td_proc
;
488 char name
[MAXCOMLEN
+ 1];
494 if (uap
->name
!= NULL
) {
495 error
= copyinstr(uap
->name
, name
, sizeof(name
),
501 if (uap
->id
== td
->td_tid
)
504 ttd
= thread_find(p
, uap
->id
);
506 strcpy(ttd
->td_name
, name
);