Date: Fri, 10 Aug 2012 13:13:02 +0300 From: Konstantin Belousov <kostikbel@gmail.com> To: Jilles Tjoelker <jilles@stack.nl> Cc: freebsd-hackers@freebsd.org, davidxu@freebsd.org Subject: Re: system() using vfork() or posix_spawn() and libthr Message-ID: <20120810101302.GF2425@deviant.kiev.zoral.com.ua> In-Reply-To: <20120809110850.GA2425@deviant.kiev.zoral.com.ua> References: <20120730102408.GA19983@stack.nl> <20120730105303.GU2676@deviant.kiev.zoral.com.ua> <20120805215432.GA28704@stack.nl> <20120806082535.GI2676@deviant.kiev.zoral.com.ua> <20120809105648.GA79814@stack.nl> <20120809110850.GA2425@deviant.kiev.zoral.com.ua>
next in thread | previous in thread | raw e-mail | index | archive | help
--GLp9dJVi+aaipsRk
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable
On Thu, Aug 09, 2012 at 02:08:50PM +0300, Konstantin Belousov wrote:
> Third alternative, which seems to be even better, is to restore
> single-threading of the parent for vfork().
I mean this patch.
diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c
index 6cb95cd..e59ee21 100644
--- a/sys/kern/kern_fork.c
+++ b/sys/kern/kern_fork.c
@@ -756,7 +756,7 @@ fork1(struct thread *td, int flags, int pages, struct p=
roc **procp,
struct thread *td2;
struct vmspace *vm2;
vm_ooffset_t mem_charged;
- int error;
+ int error, single_threaded;
static int curfail;
static struct timeval lastfail;
#ifdef PROCDESC
@@ -815,6 +815,19 @@ fork1(struct thread *td, int flags, int pages, struct =
proc **procp,
}
#endif
=20
+ if (((p1->p_flag & (P_HADTHREADS | P_SYSTEM)) =3D=3D P_HADTHREADS) &&
+ (flags & RFPPWAIT) !=3D 0) {
+ PROC_LOCK(p1);
+ if (thread_single(SINGLE_BOUNDARY)) {
+ PROC_UNLOCK(p1);
+ error =3D ERESTART;
+ goto fail2;
+ }
+ PROC_UNLOCK(p1);
+ single_threaded =3D 1;
+ } else
+ single_threaded =3D 0;
+
mem_charged =3D 0;
vm2 =3D NULL;
if (pages =3D=3D 0)
@@ -945,6 +958,12 @@ fail1:
if (vm2 !=3D NULL)
vmspace_free(vm2);
uma_zfree(proc_zone, newproc);
+ if (single_threaded) {
+ PROC_LOCK(p1);
+ thread_single_end();
+ PROC_UNLOCK(p1);
+ }
+fail2:
#ifdef PROCDESC
if (((flags & RFPROCDESC) !=3D 0) && (fp_procdesc !=3D NULL)) {
fdclose(td->td_proc->p_fd, fp_procdesc, *procdescp, td);
diff --git a/tools/test/pthread_vfork/pthread_vfork_test.c b/tools/test/pth=
read_vfork/pthread_vfork_test.c
index e004727..88956c2 100644
--- a/tools/test/pthread_vfork/pthread_vfork_test.c
+++ b/tools/test/pthread_vfork/pthread_vfork_test.c
@@ -29,6 +29,8 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
=20
+#include <sys/types.h>
+#include <sys/wait.h>
#include <err.h>
#include <pthread.h>
#include <signal.h>
@@ -39,10 +41,11 @@ __FBSDID("$FreeBSD$");
=20
#define NUM_THREADS 100
=20
-void *
-vfork_test(void *threadid)
+static void *
+vfork_test(void *threadid __unused)
{
- pid_t pid;
+ pid_t pid, wpid;
+ int status;
=20
for (;;) {
pid =3D vfork();
@@ -50,10 +53,20 @@ vfork_test(void *threadid)
_exit(0);
else if (pid =3D=3D -1)
err(1, "Failed to vfork");
+ else {
+ wpid =3D waitpid(pid, &status, 0);
+ if (wpid =3D=3D -1)
+ err(1, "waitpid");
+ }
}
return (NULL);
}
=20
+static void
+sighandler(int signo __unused)
+{
+}
+
/*
* This program invokes multiple threads and each thread calls
* vfork() system call.
@@ -63,19 +76,24 @@ main(void)
{
pthread_t threads[NUM_THREADS];
struct sigaction reapchildren;
+ sigset_t sigchld_mask;
int rc, t;
=20
memset(&reapchildren, 0, sizeof(reapchildren));
- reapchildren.sa_handler =3D SIG_IGN;
-
- /* Automatically reap zombies. */
+ reapchildren.sa_handler =3D sighandler;
if (sigaction(SIGCHLD, &reapchildren, NULL) =3D=3D -1)
err(1, "Could not sigaction(SIGCHLD)");
=20
+ sigemptyset(&sigchld_mask);
+ sigaddset(&sigchld_mask, SIGCHLD);
+ if (sigprocmask(SIG_BLOCK, &sigchld_mask, NULL) =3D=3D -1)
+ err(1, "sigprocmask");
+
for (t =3D 0; t < NUM_THREADS; t++) {
rc =3D pthread_create(&threads[t], NULL, vfork_test, (void *)t);
if (rc)
errc(1, rc, "pthread_create");
}
+ pause();
return (0);
}
--GLp9dJVi+aaipsRk
Content-Type: application/pgp-signature
Content-Disposition: inline
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.12 (FreeBSD)
iEYEARECAAYFAlAk3q4ACgkQC3+MBN1Mb4g29QCghHodkIf2zunuCoeJlrsux7QN
fP8AoJ/taKj2h5VQAco2vg/NY90ZmyZW
=c6ZU
-----END PGP SIGNATURE-----
--GLp9dJVi+aaipsRk--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20120810101302.GF2425>
