From owner-freebsd-hackers@FreeBSD.ORG Sun Aug 12 00:11:41 2012 Return-Path: Delivered-To: freebsd-hackers@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 1D1E5106564A; Sun, 12 Aug 2012 00:11:41 +0000 (UTC) (envelope-from listlog2011@gmail.com) Received: from mail-pb0-f54.google.com (mail-pb0-f54.google.com [209.85.160.54]) by mx1.freebsd.org (Postfix) with ESMTP id D6B2F8FC08; Sun, 12 Aug 2012 00:11:40 +0000 (UTC) Received: by pbbrp2 with SMTP id rp2so5286746pbb.13 for ; Sat, 11 Aug 2012 17:11:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=message-id:date:from:user-agent:mime-version:to:cc:subject :references:in-reply-to:content-type:content-transfer-encoding; bh=ZP6GyUQZ8/4FvYMm8kWBFXORneiuwU2sLDfA/lWP5L8=; b=p8ciIF+E7+vngEcPrUruDj9zZ3gD18Z92okLC8ujKV0OlLTa1XyV09ClGYCd0qM/Hl p0F/ABA5NtrZyjh3VBWBLf27bFhQ+Z1UPIBFLG9iulKOwnT6fMjceLNYrWYQeqLrNZGi h8Fx/s/hEd5/xL/sKcAQQU44qYsfxStOxxa8U3K/gEpWR0mAoJlW+V7U7zRPIEwy2NFb vQdXN1w73d9YkLgE9/WifKYnhISV9yC/2c07rgaiDqiUXYAIl0UMB2ohO+U1jg4IgRhM +f5NRUuNnnh446/UlpMxrs6D6mN543hIS6sVlBw+fJLwwsDEFWD3FhQfCd+lAiNUgO5q gCDA== Received: by 10.66.73.202 with SMTP id n10mr8501410pav.80.1344730299451; Sat, 11 Aug 2012 17:11:39 -0700 (PDT) Received: from xp5k.my.domain ([220.184.76.3]) by mx.google.com with ESMTPS id nr2sm2232899pbc.48.2012.08.11.17.11.36 (version=SSLv3 cipher=OTHER); Sat, 11 Aug 2012 17:11:38 -0700 (PDT) Message-ID: <5026F4B1.5030000@gmail.com> Date: Sun, 12 Aug 2012 08:11:29 +0800 From: David Xu User-Agent: Mozilla/5.0 (X11; FreeBSD amd64; rv:13.0) Gecko/20120808 Thunderbird/13.0.1 MIME-Version: 1.0 To: Konstantin Belousov 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> <20120810101302.GF2425@deviant.kiev.zoral.com.ua> In-Reply-To: <20120810101302.GF2425@deviant.kiev.zoral.com.ua> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit X-Mailman-Approved-At: Sun, 12 Aug 2012 01:39:58 +0000 Cc: freebsd-hackers@freebsd.org, davidxu@freebsd.org, Jilles Tjoelker Subject: Re: system() using vfork() or posix_spawn() and libthr X-BeenThere: freebsd-hackers@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Technical Discussions relating to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 12 Aug 2012 00:11:41 -0000 On 2012/08/10 18:13, Konstantin Belousov wrote: > 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(). single-threading is slow for large threaded process, don't know if it is necessary for vfork(), POSIX says nothing about threaded process. > 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 proc **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 > > + if (((p1->p_flag & (P_HADTHREADS | P_SYSTEM)) == P_HADTHREADS) && > + (flags & RFPPWAIT) != 0) { > + PROC_LOCK(p1); > + if (thread_single(SINGLE_BOUNDARY)) { > + PROC_UNLOCK(p1); > + error = ERESTART; > + goto fail2; > + } > + PROC_UNLOCK(p1); > + single_threaded = 1; > + } else > + single_threaded = 0; > + > mem_charged = 0; > vm2 = NULL; > if (pages == 0) > @@ -945,6 +958,12 @@ fail1: > if (vm2 != 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) != 0) && (fp_procdesc != 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/pthread_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 > __FBSDID("$FreeBSD$"); > > +#include > +#include > #include > #include > #include > @@ -39,10 +41,11 @@ __FBSDID("$FreeBSD$"); > > #define NUM_THREADS 100 > > -void * > -vfork_test(void *threadid) > +static void * > +vfork_test(void *threadid __unused) > { > - pid_t pid; > + pid_t pid, wpid; > + int status; > > for (;;) { > pid = vfork(); > @@ -50,10 +53,20 @@ vfork_test(void *threadid) > _exit(0); > else if (pid == -1) > err(1, "Failed to vfork"); > + else { > + wpid = waitpid(pid, &status, 0); > + if (wpid == -1) > + err(1, "waitpid"); > + } > } > return (NULL); > } > > +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; > > memset(&reapchildren, 0, sizeof(reapchildren)); > - reapchildren.sa_handler = SIG_IGN; > - > - /* Automatically reap zombies. */ > + reapchildren.sa_handler = sighandler; > if (sigaction(SIGCHLD, &reapchildren, NULL) == -1) > err(1, "Could not sigaction(SIGCHLD)"); > > + sigemptyset(&sigchld_mask); > + sigaddset(&sigchld_mask, SIGCHLD); > + if (sigprocmask(SIG_BLOCK, &sigchld_mask, NULL) == -1) > + err(1, "sigprocmask"); > + > for (t = 0; t < NUM_THREADS; t++) { > rc = pthread_create(&threads[t], NULL, vfork_test, (void *)t); > if (rc) > errc(1, rc, "pthread_create"); > } > + pause(); > return (0); > }