Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 03 Jun 2003 00:01:43 +0900 (JST)
From:      Munehiro Matsuda <haro@h4.dion.ne.jp>
To:        sheldonh@starjuice.net, freebsd-java@freebsd.org
Subject:   Re: Native JDK with libthr/libkse
Message-ID:  <20030603.000143.74755686.haro@h4.dion.ne.jp>
In-Reply-To: <20030602123445.GK84604@starjuice.net>
References:  <20030602123445.GK84604@starjuice.net>

next in thread | previous in thread | raw e-mail | index | archive | help
----Next_Part(Tue_Jun__3_00:01:43_2003_142)--
Content-Type: Text/Plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

From: Sheldon Hearn <sheldonh@starjuice.net>
Date: Mon, 2 Jun 2003 14:34:45 +0200
::I think this message fraom Daniel Eischen to the freebsd-current list is
::worth noting.
::
::Ciao,
::Sheldon.
::
::----- Forwarded message from Daniel Eischen <eischen@pcnet.com> -----
::
::Date: Mon, 2 Jun 2003 07:49:14 -0400 (EDT)
::From: Daniel Eischen <eischen@pcnet.com>
::To: Sheldon Hearn <sheldonh@starjuice.net>
::cc: Narvi <narvi@haldjas.folklore.ee>, freebsd-current@freebsd.org
::Subject: Re: Native JDK with libthr/libkse
<snip>
::
::And I encourage the java developers to let us threads guys know
::what they're having problems with.  It has been stated that
::jdk is not guaranteed to work with anything but libc_r, so
::contact us over at threads@.  We want to see a fast and stable
::jdk as much as anyone else does.

Hi Sheldon and jdk13 users,

Thanks for the info.
I now think it's best time to release a patch for jdk13+HostSpot
to make it work with libthr/libkse.

This patch is mostly based on work done by Antony T Curtis, back
in March, with minor clean-up by me.  The original message can be
found with:
http://docs.freebsd.org/cgi/getmsg.cgi?fetch=472328+0+archive/2003/freebsd-java/20030316.freebsd-java

The patch has only been lightly tested with:
  OS : 5-CURRENT/-BETA
  Lib: libthr and libkse (mostly with libthr)
  App: $JAVA_HOME/demo/jfc/Java2D/Java2Demo.html, etc...

Somehow '-native' (Native thread) does not seem to work...

Thanks,
 Haro
=------------------------------------------------------------------------------
           _ _    Munehiro (haro) Matsuda
 -|- /_\  |_|_|   Network & Security Dept., Kubota Graphics Technologies Inc.
 /|\ |_|  |_|_|   2-8-8 Shinjuku Shinjuku-ku Tokyo 160-0022, Japan
                  Tel: +81-3-3225-0373  Fax: +81-3-3225-0740
                  Email: haro@kgt.co.jp

----Next_Part(Tue_Jun__3_00:01:43_2003_142)--
Content-Type: Text/Plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="jdk13.hotspot.libthr.patch"

diff -ruN --exclude CVS jdk13.org/files/patch-hotspot-gcc.make jdk13/files/patch-hotspot-gcc.make
--- jdk13.org/files/patch-hotspot-gcc.make	Thu Jan  1 09:00:00 1970
+++ jdk13/files/patch-hotspot-gcc.make	Fri Apr  4 18:17:02 2003
@@ -0,0 +1,11 @@
+--- ../../hotspot1.3.1/build/linux/makefiles/gcc.make.org	Wed Apr  2 11:24:03 2003
++++ ../../hotspot1.3.1/build/linux/makefiles/gcc.make	Wed Apr  2 11:29:01 2003
+@@ -17,7 +17,7 @@
+ CFLAGS += -fwritable-strings
+ CFLAGS += -fno-rtti
+ CFLAGS += -fhandle-exceptions
+-CFLAGS += -D__STDC__=1 -D_LARGEFILE64_SOURCE -DTEMPLATE_TABLE_BUG
++CFLAGS += -D__STDC__=1 -D_LARGEFILE64_SOURCE
+ CFLAGS += -D__GNU__ -D_REENTRANT
+ CFLAGS += -fcheck-new
+ 
diff -ruN --exclude CVS jdk13.org/files/patch-hotspot-os.hpp jdk13/files/patch-hotspot-os.hpp
--- jdk13.org/files/patch-hotspot-os.hpp	Thu Jan  1 09:00:00 1970
+++ jdk13/files/patch-hotspot-os.hpp	Fri Mar 14 12:08:26 2003
@@ -0,0 +1,12 @@
+diff -ur ../../hotspot1.3.1/src/share/vm/runtime/os.hpp ../../hotspot1.3.1/src/share/vm/runtime/os.hpp
+--- ../../hotspot1.3.1/src/share/vm/runtime/os.hpp	Fri Mar 14 01:32:07 2003
++++ ../../hotspot1.3.1/src/share/vm/runtime/os.hpp	Fri Mar 14 00:05:31 2003
+@@ -156,7 +156,7 @@
+   static address current_stack_pointer();
+   static address current_stack_base();
+   static address current_stack_limit();
+-  static int current_stack_size();
++  static size_t current_stack_size();
+ 
+   static int message_box(const char* title, const char* message);
+ 
diff -ruN --exclude CVS jdk13.org/files/patch-hotspot-os_linux.cpp jdk13/files/patch-hotspot-os_linux.cpp
--- jdk13.org/files/patch-hotspot-os_linux.cpp	Thu Jan  1 09:00:00 1970
+++ jdk13/files/patch-hotspot-os_linux.cpp	Fri Mar 14 12:08:52 2003
@@ -0,0 +1,146 @@
+diff -ur ../../hotspot1.3.1/src/os/linux/vm/os_linux.cpp ../../hotspot1.3.1/src/os/linux/vm/os_linux.cpp
+--- ../../hotspot1.3.1/src/os/linux/vm/os_linux.cpp	Fri Mar 14 01:32:06 2003
++++ ../../hotspot1.3.1/src/os/linux/vm/os_linux.cpp	Thu Mar 13 23:53:43 2003
+@@ -39,12 +39,7 @@
+ 
+ #include <pthread.h>
+ #include <pthread_np.h>
+-
+-#undef pthread_attr_default
+-#undef pthread_mutexattr_default
+-#undef pthread_condattr_default
+-
+-#include <uthread/pthread_private.h>
++#include <setjmp.h>
+ 
+ #include <vm/vm.h>
+ #include <vm/pmap.h>
+@@ -124,82 +119,46 @@
+ 	}
+ }
+ 
+-address os::current_stack_base()
+-{
+-    uintptr_t	addr,
+-		guard_page_size = getpagesize();
+-    int 	result;
+-    pthread_t	self = pthread_self();
+-
+-    result = pthread_main_np();
+-//    result = pthread_equal(self, _thread_initial);
+-#if 1
++address os::current_stack_base() {
+ 
+-    if (result > 0) {
+-	    addr  = (uintptr_t) USRSTACK;
+-    }
+-    else if (result == 0 ) {
+-	    //if (self != NULL)
++  uintptr_t addr = NULL;
++  pthread_attr_t attr;
++  void *mystack = NULL;
++  size_t mysize = 0;
++
++  if (pthread_attr_init(&attr) == 0) {
++    if (pthread_attr_get_np(pthread_self(), &attr) != 0)
++        goto err;
++    if (pthread_attr_getstackaddr(&attr, &mystack) != 0)
++        goto err;
++    if (pthread_attr_getstacksize(&attr, &mysize) != 0)
++        goto err;
+ 
+-	    self = pthread_self();
+-	    if (!(self > 0)) {
+-		fprintf(stderr, "pthread_main_np self == 0x%08x", (uintptr_t) self);
+-	    }
+-	    else {
+-		addr = (uintptr_t) self->stack;
+-	    }
+-    }
+-    else {
+-	warning("pthread_main_np reported that _thread_initial == NULL");
+-    }
+-    return (address) addr;
+-
+-#else
++    addr = (uintptr_t) mystack + mysize;
++    pthread_attr_destroy(&attr);
+ 
+-    if (self > 0) {
+-	addr = (uintptr_t) self->stack;
+-	fprintf(stderr, "attr  == 0x%08x\n", addr);
+-    }
+-    else {
+-	fprintf(stderr, "pthread_self failed == 0x%08x\n", (uintptr_t) self);
+-    }
+     return (address) addr;
++  }
++
++err:
++  fatal("Unable to get current thread stack base pointer");
+ 
+-#endif
+ }
+ 
+-// Same for this function too
+-//
+-// --billh
+-int os::current_stack_size()
+-{
+-    uintptr_t sizep = 0;
+-    pthread_t self  = pthread_self();
++size_t os::current_stack_size() {
+ 
+-#if 0
+-  if (pthread_equal(self, _thread_initial)) {
+-//    if (pthread_main_np()){
+-	/* in main()'s thread */
+-	struct rlimit r;
+-	assert(getrlimit(RLIMIT_STACK, &r) == 0, "os::current_stack_size: getrlimit failed");
+-	sizep = (long)r.rlim_cur;
+-
+-#define PTHREAD_STACK_DEFAULT                   65536
+-    } else {
+-	sizep = (long) PTHREAD_STACK_DEFAULT;
+-    }
+-    return sizep;
+-#else
+-    if (self > 0) {
+-	sizep = (uintptr_t) self->attr.stacksize_attr;
++  pthread_attr_t attr;
++  size_t sizep = 0;
+ 
++  if (pthread_attr_init(&attr) == 0) {
++    if (pthread_attr_get_np(pthread_self(), &attr) == 0) {
++      pthread_attr_getstacksize(&attr, &sizep);
+     }
+-    else {
+-	fprintf(stderr, "pthread_self failed == 0x%08x\n", self);
+-    }
+-
++    pthread_attr_destroy(&attr);
+     return sizep;
+-#endif
++  }
++
++  fatal("Unable to get current thread stack base size");
+ }
+ 
+ // Part 2
+@@ -358,6 +317,7 @@
+ #define RT_JAR         "/lib/rt.jar"
+ #define I18N_JAR       "/lib/i18n.jar"
+ #define SUNRSASIGN_JAR "/lib/sunrsasign.jar"
++#define EXTENSIONS_DIR "/lib/ext"
+ #define CLASSES_DIR    "/classes"
+ #define DEFAULT_LD_LIBRARY_PATH "/usr/lib" /* See ld.so.1(1) */
+ 
+@@ -431,7 +391,7 @@
+ 	char * buf;
+ //	buf = malloc(strlen(sprops.java_home) + sizeof(MAXNAMLEN));
+ 	buf = malloc(MAXNAMLEN);
+-	snprintf(buf, MAXNAMLEN, "%s", sprops.java_home);
++	snprintf(buf, MAXNAMLEN, "%s" EXTENSIONS_DIR, sprops.java_home);
+ 	sprops.ext_dirs = buf;
+     }
+   }
diff -ruN --exclude CVS jdk13.org/files/patch-hotspot-os_linux_i486.cpp jdk13/files/patch-hotspot-os_linux_i486.cpp
--- jdk13.org/files/patch-hotspot-os_linux_i486.cpp	Thu Jan  1 09:00:00 1970
+++ jdk13/files/patch-hotspot-os_linux_i486.cpp	Fri Mar 14 12:09:28 2003
@@ -0,0 +1,16 @@
+diff -ur ../../hotspot1.3.1/src/os_cpu/linux_i486/vm/os_linux_i486.cpp ../../hotspot1.3.1/src/os_cpu/linux_i486/vm/os_linux_i486.cpp
+--- ../../hotspot1.3.1/src/os_cpu/linux_i486/vm/os_linux_i486.cpp	Fri Mar 14 01:32:06 2003
++++ ../../hotspot1.3.1/src/os_cpu/linux_i486/vm/os_linux_i486.cpp	Fri Mar 14 00:15:28 2003
+@@ -35,12 +35,6 @@
+ 
+ #include <setjmp.h>
+ 
+-#undef pthread_attr_default
+-#undef pthread_mutexattr_default
+-#undef pthread_condattr_default
+-
+-#include <uthread/pthread_private.h>
+-
+ #define MAX_PATH (2 * K)
+ #define INTERRUPT_SIGNAL SIGUSR1
+ 
diff -ruN --exclude CVS jdk13.org/files/patch-plugin-java_vm.c jdk13/files/patch-plugin-java_vm.c
--- jdk13.org/files/patch-plugin-java_vm.c	Thu Jan  1 09:00:00 1970
+++ jdk13/files/patch-plugin-java_vm.c	Tue Mar 18 16:54:52 2003
@@ -0,0 +1,29 @@
+--- ../ext/plugin/oji-plugin/src/motif/jvm_exec/java_vm.c.org	Sun Mar 16 23:54:01 2003
++++ ../ext/plugin/oji-plugin/src/motif/jvm_exec/java_vm.c	Tue Mar 18 16:53:56 2003
+@@ -119,12 +119,24 @@
+     void *libjvm;
+     char jvmpath[MAXPATHLEN];
+     const char *debug = "";
++    char *thread_type;
+ 
+     if (getenv("JAVA_PLUGIN_DEBUG"))
+ 	debug = "_g";
+ 
+-    snprintf(jvmpath, sizeof jvmpath, "%s/lib/"ARCH"/client/libjvm%s.so", java_home, debug);
+-    libjvm = dlopen(jvmpath, RTLD_NOW + RTLD_GLOBAL);
++    /*
++     * Check for HotSpot VM.
++     * With the current status of *BSD JDK, HotSpot VM needs to have
++     * THREADS_FLAG envrionment varible set to "native" at startup time,
++     * which in turn defined within THREADS_TYPE along the way here.
++     * So check for THREADS_TYPE, before loading HotSpot VM.
++     */ 
++    libjvm = NULL;
++    thread_type = getenv("THREADS_TYPE");
++    if (thread_type != NULL && strcmp(thread_type, "native_threads") == 0) {
++        snprintf(jvmpath, sizeof jvmpath, "%s/lib/"ARCH"/client/libjvm%s.so", java_home, debug);
++        libjvm = dlopen(jvmpath, RTLD_NOW + RTLD_GLOBAL);
++    }
+ 
+     if (libjvm == NULL) {
+       /* If we don't find the HotSpot JVM, look in classic.
diff -ruN --exclude CVS jdk13.org/files/patch-threads_bsd.c jdk13/files/patch-threads_bsd.c
--- jdk13.org/files/patch-threads_bsd.c	Sat Mar  1 07:47:00 2003
+++ jdk13/files/patch-threads_bsd.c	Tue May 20 00:49:47 2003
@@ -1,8 +1,8 @@
 $FreeBSD: ports/java/jdk13/files/patch-threads_bsd.c,v 1.1 2003/02/28 17:47:38 glewis Exp $
 
 --- ../src/solaris/hpi/native_threads/src/threads_bsd.c	7 Feb 2002 05:19:54 -0000	1.12
-+++ ../src/solaris/hpi/native_threads/src/threads_bsd.c	25 Feb 2003 16:31:54 -0000
-@@ -22,32 +22,23 @@
++++ ../src/solaris/hpi/native_threads/src/threads_bsd.c	Tue May 20 00:44:07 2003
+@@ -22,32 +22,25 @@
  #include "np.h"
  
  #include <pthread.h>
@@ -16,11 +16,12 @@
 -/* Remove defines from pthread.h so pthread_private.h can be included */
 -#undef pthread_condattr_default
 -#undef pthread_mutexattr_default
++#ifdef DEBUG_BSD_NATIVE_THREADS
  #undef pthread_attr_default
 +#undef pthread_mutexattr_default
 +#undef pthread_condattr_default
  #include "pthread_private.h"
- 
+-
 -#include <assert.h>
 -#include <ucontext.h>
 -#include <machine/ucontext.h>
@@ -30,7 +31,8 @@
 -#include <vm/pmap.h>
 -#include <machine/pmap.h>
 -#include <machine/vmparam.h>
--
++#endif
+ 
  #endif
  
  #include <string.h>
@@ -40,7 +42,7 @@
  #include <sys/resource.h>
  #include <stdlib.h>
  #include <string.h>
-@@ -63,14 +54,9 @@
+@@ -63,14 +56,9 @@
  /* Private functions used to implement native threading. --billh */
  
  #ifdef DEBUG_BSD_NATIVE_THREADS
@@ -57,9 +59,17 @@
  
  /*
   * Suspend a thread.  Used to implement java.lang.Thread.suspend(),
-@@ -108,28 +94,24 @@
- int
- np_stackinfo(void **addr, long *sizep)
+@@ -103,33 +91,45 @@
+ 
+ 
+ /*
+- * Get the stack start address, and max stack size for the current thread.
++ * Internal helper function to get stack information about specified thread.
+  */
+-int
+-np_stackinfo(void **addr, long *sizep)
++static int
++get_stackinfo(pthread_t tid, pthread_attr_t attr, void **addr, long *sizep)
  {
 -    thread_t self = pthread_self();
 -    int base;
@@ -68,41 +78,53 @@
 -    if (!pthread_equal(self, _thread_initial)) {
 -        *addr = self->stack;
 -	*sizep = (long) PTHREAD_STACK_DEFAULT;
--
++    size_t s;
++    void  *p;
++    int    ret = SYS_ERR;
++
++    if (pthread_attr_get_np(tid, &attr) != 0)
++        goto err;
++    if (pthread_attr_getstackaddr(&attr, &p) != 0)
++        goto err;
++    if (pthread_attr_getstacksize(&attr, &s) != 0)
++        goto err;
++    *addr = p;
++    *sizep = s;
++    ret = SYS_OK;
++err:
+ 
 -    } else {
 -	/* in main()'s thread */
 -	struct rlimit r;
--
++    return (ret);
++}
+ 
 -	if (getrlimit(RLIMIT_STACK, &r) == -1)
 -	    return SYS_ERR;
--
+ 
 -	/* PS_STRINGS is also from sys/exec.h in FreeBSD, but as macro. --billh */
--
++/*
++ * Get the stack start address, and max stack size for the current thread.
++ */
++int
++np_stackinfo(void **addr, long *sizep)
++{
++    pthread_attr_t attr;
++    int    ret = SYS_ERR;
+ 
 -	*addr  = (void *) (PS_STRINGS +1);
 -	*sizep = (long)r.rlim_cur;
--    }
-+    pthread_attr_t attr;
-+    size_t size;
++    if (pthread_attr_init(&attr) == 0) {
++        ret = get_stackinfo(pthread_self(), attr, addr, sizep);
++        pthread_attr_destroy(&attr);
+     }
  
-+    if ((errno = pthread_attr_init(&attr)))
-+	return SYS_ERR;
-+    if ((errno = pthread_attr_get_np(pthread_self(), &attr)))
-+	goto err;
-+    if ((errno = pthread_attr_getstackaddr(&attr, addr)))
-+	goto err;
-+    if ((errno = pthread_attr_getstacksize(&attr, &size)))
-+	goto err;
-+    *sizep = size;
-+    pthread_attr_destroy(&attr);
-     return SYS_OK;
-+
-+err:
-+    pthread_attr_destroy(&attr);
-+    return SYS_ERR;
+-    return SYS_OK;
++    return (ret);
  }
  
  /*
-@@ -177,7 +159,7 @@
+@@ -177,7 +177,7 @@
  	Do this for the FreeBSD implementation too, since this is a silly
  	function anyways.  --billh
  */
@@ -111,13 +133,20 @@
  }
  
  
-@@ -190,38 +172,54 @@
+@@ -187,43 +187,69 @@
+     return SYS_OK;
+ }
+ 
++
  static void
  record_thread_regs()
  {
 -    sys_thread_t *tid;
 +    struct pthread *self = pthread_self();
 +    sys_thread_t *tid = ThreadQueue;
++    pthread_attr_t attr = NULL;
++    void *addr;
++    long sz;
      int i;
 -    int sp;
  
@@ -138,6 +167,9 @@
 -//#endif	//__FreeBSD__
 -/*	Potential race here if the stack isn't setup before GC. --billh */
 -	} else {
++    if (pthread_attr_init(&attr) != 0)
++	attr = NULL;
++
 +    for (i = 0; i < ActiveThreadCount && tid != NULL; i++, tid = tid->next) {
 +	struct pthread *thread = tid->sys_thread;
 +
@@ -152,10 +184,12 @@
  	}
  
 -	record_gc_registers_of(tid);
-+        tid->sp = thread->stack;
-+/*	Potential race here if the stack isn't setup before GC. --billh */
- 
--	tid = tid->next;
++	if (get_stackinfo(thread, attr, &addr, &sz) == SYS_OK)
++	    tid->sp = addr;
++	else
++	    tid->sp = 0;
++
++#ifdef DEBUG_BSD_NATIVE_THREADS
 +	/*
 +	 * The thread that calls this function will alway be the JVM GC thread,
 +	 * so skip over it in the list of threads.
@@ -163,13 +197,11 @@
 +	if (thread != self && (thread->flags & PTHREAD_FLAGS_PRIVATE) == 0) {
 +	    register_t *regbase;
 +
-+#ifdef DEBUG_BSD_NATIVE_THREADS
 +	    /*
 +	     * Got search candidate..
 +	     */
 +	    if (thread->state != PS_SUSPENDED)
 +		dumpThreadLogStates(thread);
-+#endif
 +
 +	    regbase = (register_t*) &thread->ctx.jb[0];
 +	    tid->regs[0] = regbase[6];	/* eax */
@@ -179,15 +211,20 @@
 +	    tid->regs[4] = regbase[3];	/* ebp */
 +	    tid->regs[5] = regbase[4];	/* esi */
 +	    tid->regs[6] = regbase[5];	/* edi */
-+
-+#ifdef DEBUG_BSD_NATIVE_THREADS
+ 
+-	tid = tid->next;
 +	    dumpThreadStates();
-+#endif
 +	}
++#endif
      }
  
++    if (attr != NULL)
++	pthread_attr_destroy(&attr);
++
  #ifdef DEBUG_BSD_NATIVE_THREADS
-@@ -239,14 +237,7 @@
+     fprintf(stderr, "\n\n\nCalling GC thread\n\n\n"); fflush(stderr);
+ #endif
+@@ -239,14 +265,7 @@
  {
      sysAssert(SYS_QUEUE_LOCKED(sysThreadSelf()));
  
@@ -203,7 +240,7 @@
      record_thread_regs();
      return SYS_OK;
  }
-@@ -259,42 +250,13 @@
+@@ -259,42 +278,13 @@
  np_multi(void)
  {
      sysAssert(SYS_QUEUE_LOCKED(sysThreadSelf()));
@@ -249,7 +286,7 @@
  =
  {
  	"PS_RUNNING",
-@@ -316,18 +278,17 @@
+@@ -316,18 +306,17 @@
  	"PS_JOIN",
  	"PS_SUSPENDED",
  	"PS_DEAD",
@@ -272,7 +309,7 @@
  }
  
  void dumpThreadStates()
-@@ -336,114 +297,29 @@
+@@ -336,114 +325,29 @@
  	struct pthread	*thread;
  	struct pthread	*self = pthread_self();
  
@@ -337,8 +374,8 @@
 -	 */
 -	_thread_kern_sig_undefer();
 -fprintf(stderr, "pthread_suspend_all_np END\n");
--}
--
+ }
+ 
 -/* Resume a thread: */
 -void
 -_pthread_resume_all_np(void)
@@ -373,9 +410,9 @@
 -	 */
 -	_thread_kern_sig_undefer();
 -fprintf(stderr, "pthread_resume_all_np END\n");
- }
+-}
 -#endif
- 
+-
  /*
  	[A snippet from Dan Eichen's email on the subject]
  
@@ -392,7 +429,7 @@
  	You can also look at src/gnu/usr.bin/binutils/gdb/freebsd-uthread.c.
  	It knows how to iterate through all the threads and pull out
  	(and even set) thread contexts.
-@@ -462,19 +338,8 @@
+@@ -462,19 +366,8 @@
  	--billh
  */
  
@@ -412,12 +449,12 @@
  int i;
  	for(i=0; i < STATE_LOG_SIZE; ++i)
  	{
-@@ -494,311 +359,5 @@
+@@ -494,311 +387,5 @@
  		}
  	}
  	printf("\t\t***XXX\n");
 -#endif
--}
+ }
 -
 -void record_gc_registers_of(sys_thread_t *javaThread)
 -{
@@ -482,7 +519,7 @@
 -Terminate:
 -	dumpThreadStates();
 -#endif
- }
+-}
 -
 -void record_uc(sys_thread_t *t, ucontext_t *uc)
 -{

----Next_Part(Tue_Jun__3_00:01:43_2003_142)----



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20030603.000143.74755686.haro>