svn commit: r285661 - in head/sys: kern sys

Ed Schouten ed at FreeBSD.org
Fri Jul 17 22:26:46 UTC 2015


Author: ed
Date: Fri Jul 17 22:26:45 2015
New Revision: 285661
URL: https://svnweb.freebsd.org/changeset/base/285661

Log:
  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

Modified:
  head/sys/kern/kern_thr.c
  head/sys/sys/proc.h

Modified: head/sys/kern/kern_thr.c
==============================================================================
--- head/sys/kern/kern_thr.c	Fri Jul 17 20:30:30 2015	(r285660)
+++ head/sys/kern/kern_thr.c	Fri Jul 17 22:26:45 2015	(r285661)
@@ -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 th
 	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 t
 			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 
 
 	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 
 	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);

Modified: head/sys/sys/proc.h
==============================================================================
--- head/sys/sys/proc.h	Fri Jul 17 20:30:30 2015	(r285660)
+++ head/sys/sys/proc.h	Fri Jul 17 22:26:45 2015	(r285661)
@@ -992,8 +992,6 @@ void	thread_cow_get_proc(struct thread *
 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);


More information about the svn-src-head mailing list