From owner-freebsd-java@FreeBSD.ORG Wed Nov 5 13:16:24 2003 Return-Path: Delivered-To: freebsd-java@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 2472C16A4CE for ; Wed, 5 Nov 2003 13:16:24 -0800 (PST) Received: from phantom.cris.net (phantom.cris.net [212.110.130.74]) by mx1.FreeBSD.org (Postfix) with ESMTP id A8F8643FBD for ; Wed, 5 Nov 2003 13:16:19 -0800 (PST) (envelope-from phantom@FreeBSD.org.ua) Received: (from phantom@localhost) by phantom.cris.net (8.12.6/8.12.6) id hA5LPhDT099503; Wed, 5 Nov 2003 23:25:43 +0200 (EET) (envelope-from phantom) Date: Wed, 5 Nov 2003 23:25:43 +0200 From: Alexey Zelkin To: java@freebsd.org Message-ID: <20031105232543.A99393@phantom.cris.net> References: <20031023122839.A75570@phantom.cris.net> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.2.5i In-Reply-To: <20031023122839.A75570@phantom.cris.net>; from phantom@FreeBSD.org.ua on Thu, Oct 23, 2003 at 12:28:39PM +0300 X-Operating-System: FreeBSD 4.7-STABLE i386 Subject: Re: jdk14 fork() problem fix X-BeenThere: freebsd-java@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Porting Java to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 05 Nov 2003 21:16:24 -0000 hi, Though patch is working it has some limitations. Under high load java applications which utilize many parallel fork()'s may hang. It's reproducible with testcase then least 5 threads calling Runtime.exec() After finding a reason I had to rethink logic of 'critical section' while calling to fork. We can't use pthread_{suspend,resume}_all_np() in order to not to create race conditions. Updated version of patch to this fork problem is attached. On Thu, Oct 23, 2003 at 12:28:39PM +0300, Alexey Zelkin wrote: > hi, > > This is an intermediate version of fix of jdk fork problem (i.e. > Runtime.getRuntime().exec() and friends). > > It does affect only people who use libc_r (kse and thr should not > be affected). > > Please try this one and report me if it fixes problems for you. > > PS: If you are rebuilding already built jdk (i.e. object files are > already compiled) remove 'control/build/bsd-i586/tmp/java/java.lang' directory > before restarting of build. Index: UNIXProcess_md.c.bsd =================================================================== RCS file: /home/jdk14-cvs/jdk142-src/j2se/src/solaris/native/java/lang/UNIXProcess_md.c.bsd,v retrieving revision 1.2 retrieving revision 1.4 diff -u -u -r1.2 -r1.4 --- UNIXProcess_md.c.bsd 15 Oct 2003 15:49:39 -0000 1.2 +++ UNIXProcess_md.c.bsd 5 Nov 2003 22:48:47 -0000 1.4 @@ -22,6 +22,12 @@ #include #include +#if defined(__FreeBSD__) +#include +#include +#include +#endif + /* path in the environment */ static char **PATH = 0; /* effective uid */ @@ -228,6 +234,58 @@ } } +#if defined(__FreeBSD__) + +extern pid_t __sys_fork(void); + +static pid_t +jdk_fork_wrapper() +{ + pid_t resultPid; + typedef void (*void_func)(); + static void_func func_defer = NULL; + static void_func func_undefer = NULL; + static int is_libc_r = -1; + + if (is_libc_r == -1) { + + /* + * BSDNOTE: Check for loaded symbols. + * + * If "_thread_kern_sig_defer" symbol is found assume we are + * libc_r + * + * If libc_r is loaded, use fork system call drectly to avoid + * problems with using protected pages. + * + * --phantom + */ + func_defer = + (void_func)dlsym(RTLD_DEFAULT, "_thread_kern_sig_defer"); + func_undefer = + (void_func)dlsym(RTLD_DEFAULT, "_thread_kern_sig_undefer"); + if (func_defer != NULL) + is_libc_r = 1; + else { + is_libc_r = 0; + } + } + + if (is_libc_r == 0) { + /* Not a libc_r */ + resultPid = fork(); + } else { + (*func_defer)(); /* call _thread_kern_sig_defer() */ + resultPid = __sys_fork(); + if (resultPid != 0) + (*func_undefer)(); /* call _thread_kern_sig_undefer() */ + /* leave child with signals disabled, but reenable in parent */ + } + + return resultPid; +} +#endif /* __FreeBSD__ */ + JNIEXPORT jint JNICALL Java_java_lang_UNIXProcess_forkAndExec(JNIEnv *env, jobject process, @@ -335,8 +393,12 @@ if (path != NULL) { cwd = (char *)JNU_GetStringPlatformChars(env, path, NULL); } - + +#if defined(__FreeBSD__) + resultPid = jdk_fork_wrapper(); +#else resultPid = fork(); +#endif if (resultPid < 0) { char errmsg[128];