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:
Ed Schouten 2015-07-17 22:26:45 +00:00
parent dac542123b
commit fd054c2df9
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=285661
2 changed files with 64 additions and 63 deletions

View File

@ -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, &param));
}
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);

View File

@ -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);