Undo r285656.
It turns out that the CDDL sources already introduce a function called thread_create(). I'll investigate what we can do to make these functions coexist. Reported by: Ivan Klymenko
This commit is contained in:
parent
dac542123b
commit
fd054c2df9
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=285661
@ -89,39 +89,29 @@ suword_lwpid(void *addr, lwpid_t lwpid)
|
||||
#define suword_lwpid suword
|
||||
#endif
|
||||
|
||||
static int create_thread(struct thread *td, mcontext_t *ctx,
|
||||
void (*start_func)(void *), void *arg,
|
||||
char *stack_base, size_t stack_size,
|
||||
char *tls_base,
|
||||
long *child_tid, long *parent_tid,
|
||||
int flags, struct rtprio *rtp);
|
||||
|
||||
/*
|
||||
* System call interface.
|
||||
*/
|
||||
|
||||
struct thr_create_initthr_args {
|
||||
ucontext_t ctx;
|
||||
long *tid;
|
||||
};
|
||||
|
||||
static int
|
||||
thr_create_initthr(struct thread *td, void *thunk)
|
||||
{
|
||||
struct thr_create_initthr_args *args;
|
||||
|
||||
/* Copy out the child tid. */
|
||||
args = thunk;
|
||||
if (args->tid != NULL && suword_lwpid(args->tid, td->td_tid))
|
||||
return (EFAULT);
|
||||
|
||||
return (set_mcontext(td, &args->ctx.uc_mcontext));
|
||||
}
|
||||
|
||||
int
|
||||
sys_thr_create(struct thread *td, struct thr_create_args *uap)
|
||||
/* ucontext_t *ctx, long *id, int flags */
|
||||
{
|
||||
struct thr_create_initthr_args args;
|
||||
ucontext_t ctx;
|
||||
int error;
|
||||
|
||||
if ((error = copyin(uap->ctx, &args.ctx, sizeof(args.ctx))))
|
||||
if ((error = copyin(uap->ctx, &ctx, sizeof(ctx))))
|
||||
return (error);
|
||||
args.tid = uap->id;
|
||||
return (thread_create(td, NULL, thr_create_initthr, &args));
|
||||
|
||||
error = create_thread(td, &ctx.uc_mcontext, NULL, NULL,
|
||||
NULL, 0, NULL, uap->id, NULL, uap->flags, NULL);
|
||||
return (error);
|
||||
}
|
||||
|
||||
int
|
||||
@ -139,35 +129,6 @@ sys_thr_new(struct thread *td, struct thr_new_args *uap)
|
||||
return (kern_thr_new(td, ¶m));
|
||||
}
|
||||
|
||||
static int
|
||||
thr_new_initthr(struct thread *td, void *thunk)
|
||||
{
|
||||
stack_t stack;
|
||||
struct thr_param *param;
|
||||
|
||||
/*
|
||||
* Here we copy out tid to two places, one for child and one
|
||||
* for parent, because pthread can create a detached thread,
|
||||
* if parent wants to safely access child tid, it has to provide
|
||||
* its storage, because child thread may exit quickly and
|
||||
* memory is freed before parent thread can access it.
|
||||
*/
|
||||
param = thunk;
|
||||
if ((param->child_tid != NULL &&
|
||||
suword_lwpid(param->child_tid, td->td_tid)) ||
|
||||
(param->parent_tid != NULL &&
|
||||
suword_lwpid(param->parent_tid, td->td_tid)))
|
||||
return (EFAULT);
|
||||
|
||||
/* Set up our machine context. */
|
||||
stack.ss_sp = param->stack_base;
|
||||
stack.ss_size = param->stack_size;
|
||||
/* Set upcall address to user thread entry function. */
|
||||
cpu_set_upcall_kse(td, param->start_func, param->arg, &stack);
|
||||
/* Setup user TLS address and TLS pointer register. */
|
||||
return (cpu_set_user_tls(td, param->tls_base));
|
||||
}
|
||||
|
||||
int
|
||||
kern_thr_new(struct thread *td, struct thr_param *param)
|
||||
{
|
||||
@ -181,13 +142,22 @@ kern_thr_new(struct thread *td, struct thr_param *param)
|
||||
return (error);
|
||||
rtpp = &rtp;
|
||||
}
|
||||
return (thread_create(td, rtpp, thr_new_initthr, param));
|
||||
error = create_thread(td, NULL, param->start_func, param->arg,
|
||||
param->stack_base, param->stack_size, param->tls_base,
|
||||
param->child_tid, param->parent_tid, param->flags,
|
||||
rtpp);
|
||||
return (error);
|
||||
}
|
||||
|
||||
int
|
||||
thread_create(struct thread *td, struct rtprio *rtp,
|
||||
int (*initialize_thread)(struct thread *, void *), void *thunk)
|
||||
static int
|
||||
create_thread(struct thread *td, mcontext_t *ctx,
|
||||
void (*start_func)(void *), void *arg,
|
||||
char *stack_base, size_t stack_size,
|
||||
char *tls_base,
|
||||
long *child_tid, long *parent_tid,
|
||||
int flags, struct rtprio *rtp)
|
||||
{
|
||||
stack_t stack;
|
||||
struct thread *newtd;
|
||||
struct proc *p;
|
||||
int error;
|
||||
@ -229,6 +199,24 @@ thread_create(struct thread *td, struct rtprio *rtp,
|
||||
|
||||
cpu_set_upcall(newtd, td);
|
||||
|
||||
/*
|
||||
* Try the copyout as soon as we allocate the td so we don't
|
||||
* have to tear things down in a failure case below.
|
||||
* Here we copy out tid to two places, one for child and one
|
||||
* for parent, because pthread can create a detached thread,
|
||||
* if parent wants to safely access child tid, it has to provide
|
||||
* its storage, because child thread may exit quickly and
|
||||
* memory is freed before parent thread can access it.
|
||||
*/
|
||||
if ((child_tid != NULL &&
|
||||
suword_lwpid(child_tid, newtd->td_tid)) ||
|
||||
(parent_tid != NULL &&
|
||||
suword_lwpid(parent_tid, newtd->td_tid))) {
|
||||
thread_free(newtd);
|
||||
error = EFAULT;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
bzero(&newtd->td_startzero,
|
||||
__rangeof(struct thread, td_startzero, td_endzero));
|
||||
bcopy(&td->td_startcopy, &newtd->td_startcopy,
|
||||
@ -236,11 +224,26 @@ thread_create(struct thread *td, struct rtprio *rtp,
|
||||
newtd->td_proc = td->td_proc;
|
||||
thread_cow_get(newtd, td);
|
||||
|
||||
error = initialize_thread(newtd, thunk);
|
||||
if (error != 0) {
|
||||
thread_cow_free(newtd);
|
||||
thread_free(newtd);
|
||||
goto fail;
|
||||
if (ctx != NULL) { /* old way to set user context */
|
||||
error = set_mcontext(newtd, ctx);
|
||||
if (error != 0) {
|
||||
thread_cow_free(newtd);
|
||||
thread_free(newtd);
|
||||
goto fail;
|
||||
}
|
||||
} else {
|
||||
/* Set up our machine context. */
|
||||
stack.ss_sp = stack_base;
|
||||
stack.ss_size = stack_size;
|
||||
/* Set upcall address to user thread entry function. */
|
||||
cpu_set_upcall_kse(newtd, start_func, arg, &stack);
|
||||
/* Setup user TLS address and TLS pointer register. */
|
||||
error = cpu_set_user_tls(newtd, tls_base);
|
||||
if (error != 0) {
|
||||
thread_cow_free(newtd);
|
||||
thread_free(newtd);
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
PROC_LOCK(p);
|
||||
|
@ -992,8 +992,6 @@ void thread_cow_get_proc(struct thread *newtd, struct proc *p);
|
||||
void thread_cow_get(struct thread *newtd, struct thread *td);
|
||||
void thread_cow_free(struct thread *td);
|
||||
void thread_cow_update(struct thread *td);
|
||||
int thread_create(struct thread *td, struct rtprio *rtp,
|
||||
int (*initialize_thread)(struct thread *, void *), void *thunk);
|
||||
void thread_exit(void) __dead2;
|
||||
void thread_free(struct thread *td);
|
||||
void thread_link(struct thread *td, struct proc *p);
|
||||
|
Loading…
Reference in New Issue
Block a user