diff options
author | ed <ed@FreeBSD.org> | 2015-07-17 22:26:45 +0000 |
---|---|---|
committer | ed <ed@FreeBSD.org> | 2015-07-17 22:26:45 +0000 |
commit | 79b276d8ba0543d918bc771672aeb0f8dc95a2c6 (patch) | |
tree | 69e72957e7d6db2cc8db15aae394db829449c0d6 /sys/kern/kern_thr.c | |
parent | b6b17c200ad933a8f599b463810193a91d039d9c (diff) | |
download | FreeBSD-src-79b276d8ba0543d918bc771672aeb0f8dc95a2c6.zip FreeBSD-src-79b276d8ba0543d918bc771672aeb0f8dc95a2c6.tar.gz |
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
Diffstat (limited to 'sys/kern/kern_thr.c')
-rw-r--r-- | sys/kern/kern_thr.c | 125 |
1 files changed, 64 insertions, 61 deletions
diff --git a/sys/kern/kern_thr.c b/sys/kern/kern_thr.c index 9e878d8..7e7b88f 100644 --- a/sys/kern/kern_thr.c +++ b/sys/kern/kern_thr.c @@ -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); |