Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 25 Feb 2003 15:41:41 +1030
From:      Greg Lewis <glewis@eyesbeyond.com>
To:        Munehiro Matsuda <haro@h4.dion.ne.jp>
Subject:   Re: [REPOST] java/47397: [PATCH] java/jdk13 to enable HotSpot
Message-ID:  <20030225154141.A48569@misty.eyesbeyond.com>
In-Reply-To: <20030225.014627.41626713.haro@h4.dion.ne.jp>; from haro@h4.dion.ne.jp on Tue, Feb 25, 2003 at 01:46:27AM %2B0900
References:  <15961.28772.873323.999940@ool-18bacefa.dyn.optonline.net> <20030224.103157.108739495.haro@kgt.co.jp> <15962.16668.753657.116140@ool-18bacefa.dyn.optonline.net> <20030225.014627.41626713.haro@h4.dion.ne.jp>

next in thread | previous in thread | raw e-mail | index | archive | help

--bp/iNruPH9dso1Pn
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

Hi all,

Can people please look over the attached patch in terms of enabling HotSpot
for the jdk13 port.  This is based on Munehiro Matsuda-san's excellent
patch with some small modifications.  The main changes I've made are:

. Simplify the HotSpot VM selection.  We just build them all and install
  them appropriately (the result is as per the linux-sun-jdk13 port).
. Use ${REINPLACE_COMMAND} rather than extra patches to change the gcc
  usage for the port.

This is how I'd prefer to do things at least initially.

Two notes:
. As per Matsuda-san's patches this patch uses Max Khon's updated native
  threads.  This will mean you need a really recent version of FreeBSD
  to build native threads.  However on the up side it greatly reduces
  (but not quite eliminates) reliance on the internals of libc_r.
. These patches don't address the gethostby{addr,name}_r problem for
  FreeBSD 5.x.  I'll do them separately.

I'd really appreciate it if a few people (other than me :) would test
these.  My main concern is if Matsuda-san's patches worked for you and
these fail then I definitely want to know.

-- 
Greg Lewis                          Email   : glewis@eyesbeyond.com
Eyes Beyond                         Web     : http://www.eyesbeyond.com
Information Technology              FreeBSD : glewis@FreeBSD.org


--bp/iNruPH9dso1Pn
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="hotspot.diff"

Index: Makefile
===================================================================
RCS file: /var/fcvs/ports/java/jdk13/Makefile,v
retrieving revision 1.47
diff -u -r1.47 Makefile
--- Makefile	12 Feb 2003 19:00:41 -0000	1.47
+++ Makefile	25 Feb 2003 05:05:28 -0000
@@ -89,7 +89,7 @@
 PLIST_SUB+=	DEBUG:=""
 .endif
 
-.if defined(WITH_NATIVE_THREADS)
+.if defined(WITH_NATIVE_THREADS) || defined(WITH_HOTSPOT)
 PLIST_SUB+=    NATIVE:=""
 MAKE_ARGS+=    HPIS="green native"
 .else
@@ -102,8 +102,25 @@
 PLIST_SUB+=    PLUGIN:=""
 .endif
 
+.if defined(WITH_HOTSPOT)
+PLIST_SUB+=    HOTSPOT:=""
+USE_REINPLACE= yes
+.else
+PLIST_SUB+=    HOTSPOT:="@comment "
+.endif
+
 .include <bsd.port.pre.mk>
 
+.if defined(WITH_HOTSPOT) && ${OSVERSION} < 500039
+USE_GCC=	3.2
+BUILD_DEPENDS+=	gcc32:${PORTSDIR}/lang/gcc32
+MAKE_ENV+=	ALT_COMPILER_PATH=${LOCALBASE}/bin
+HOTSPOT_BUILD=	../ext/plugin/build/solaris/GNUmakefile \
+	../../hotspot1.3.1/build/linux/makefiles/adlc.make \
+	../../hotspot1.3.1/build/linux/platform_i486
+HOTSPOT_TARGETS=compiler1 compiler2
+.endif
+
 .if ${OSVERSION} < 460101 || ( ${OSVERSION} >= 500000 && ${OSVERSION} < 500038 )
 BUILD_DEPENDS+=	gtar:${PORTSDIR}/archivers/gtar
 TAR=		gtar	# Necessary for proper extraction of sources
@@ -134,6 +151,24 @@
 Please place the patchset in ${DISTDIR}.\n
 .endif
 
+# HotSpot and/or native threads require a recent version of FreeBSD
+.if ( defined(WITH_NATIVE_THREADS) || defined(WITH_HOTSPOT) ) && ( ${OSVERSION} < 470101 || ( ${OSVERSION} >= 500000 && ${OSVERSION} < 500043 ) )
+ECHO_MSG=/usr/bin/printf
+IGNORE= :\n\
+You must have a version of FreeBSD later than 4.7-STABLE February 2003\n\
+or 5-CURRENT February 2003 to use either native threads or HotSpot.\n
+.endif
+
+# Warn user about HotSpot build
+.if defined(WITH_HOTSPOT)
+pre-everything:
+	@${ECHO_MSG} ""
+	@${ECHO_MSG} "You have set WITH_HOTSPOT to enable the build of the HotSpot VM."
+	@${ECHO_MSG} "Please note that HotSpot development is still experimental and is"
+	@${ECHO_MSG} "not suitable for use in a production environment."
+	@${ECHO_MSG} ""
+.endif
+
 pre-patch:
 	@cd ${WRKDIR} &&  \
 		${CHMOD} -R u+w * && \
@@ -148,6 +183,16 @@
 		${MKDIR} hotspot1.3.1/src/os_cpu/bsd_i486/vm && \
 			${PATCH} < ${WRKDIR}/jdk131.patches
 
+post-patch:
+.if defined(WITH_HOTSPOT)
+.if defined(USE_GCC) && ${USE_GCC} == 3.2
+	@for file in ${HOTSPOT_BUILD}; do \
+        	${REINPLACE_CMD} -e "s:gcc:gcc32:g ; s:g\+\+:g\+\+32:g" ${WRKSRC}/$${file}; \
+	done
+	@${REINPLACE_CMD} -e "s:PATH[)]gcc:PATH)gcc32:g ; s:PATH[)]g\+\+:PATH)g\+\+32:g" ${WRKSRC}/common/Defs-bsd.gmk 
+.endif
+.endif
+
 .if !defined(NATIVE_BOOTSTRAP)
 pre-build:
 	@if [ "$${WRKDIRPREFIX}" -a \
@@ -170,7 +215,33 @@
 	fi
 .endif
 
+do-build:
+	# Start of jdk build
+	@(cd ${BUILD_WRKSRC}; ${SETENV} ${MAKE_ENV} ${GMAKE} ${MAKE_FLAGS} ${MAKEFILE} ${MAKE_ARGS} ${ALL_TARGET})
+.if defined(WITH_HOTSPOT)
+	# Start of HotSpot build
+	@(cd ${WRKDIR}/hotspot1.3.1/build/linux ;  \
+		${SETENV} ${MAKE_ENV} ${GMAKE} ${MAKE_FLAGS} ${MAKEFILE} ${HOTSPOT_TARGETS})
+.endif
+
 post-build:
+.if defined(WITH_HOTSPOT)
+	# Copy HotSpot VM to image dir
+	${MKDIR} ${JDKIMAGEDIR}/jre/lib/i386/client
+	${INSTALL_PROGRAM} ${WRKDIR}/hotspot1.3.1/build/linux/linux_i486_compiler1/product/libjvm.so ${JDKIMAGEDIR}/jre/lib/i386/client/
+	${INSTALL_DATA} ${WRKDIR}/hotspot1.3.1/src/share/vm/Xusage.txt ${JDKIMAGEDIR}/jre/lib/i386/client/
+	${MKDIR} ${JDKIMAGEDIR}/jre/lib/i386/server
+	${INSTALL_PROGRAM} ${WRKDIR}/hotspot1.3.1/build/linux/linux_i486_compiler2/product/libjvm.so ${JDKIMAGEDIR}/jre/lib/i386/server/
+	${INSTALL_DATA} ${WRKDIR}/hotspot1.3.1/src/share/vm/Xusage.txt ${JDKIMAGEDIR}/jre/lib/i386/server/
+	@(cd ${JDKIMAGEDIR}/jre/lib/i386; ${LN} -sf client hotspot)
+.if !defined(NODEBUG)
+	# Copy debug version of HotSpot VM to image dir
+	${MKDIR} ${JDKIMAGEDIR_G}/jre/lib/i386/client
+	${INSTALL_PROGRAM} ${WRKDIR}/hotspot1.3.1/build/linux/linux_i486_compiler1/jvmg/libjvm_g.so ${JDKIMAGEDIR_G}/jre/lib/i386/client/
+	${MKDIR} ${JDKIMAGEDIR_G}/jre/lib/i386/server
+	${INSTALL_PROGRAM} ${WRKDIR}/hotspot1.3.1/build/linux/linux_i486_compiler2/jvmg/libjvm_g.so ${JDKIMAGEDIR_G}/jre/lib/i386/server/
+.endif
+.endif
 	# Prune empty dirs
 	${FIND} ${JDKIMAGEDIR} -type d | ${SORT} -r | \
 		${XARGS} ${RMDIR} 2> /dev/null || ${TRUE}
Index: pkg-plist
===================================================================
RCS file: /var/fcvs/ports/java/jdk13/pkg-plist,v
retrieving revision 1.12
diff -u -r1.12 pkg-plist
--- pkg-plist	10 Nov 2002 22:44:00 -0000	1.12
+++ pkg-plist	24 Feb 2003 22:39:03 -0000
@@ -813,8 +813,12 @@
 jdk%%JDK_VERSION%%/jre/lib/i386/classic/Xusage.txt
 jdk%%JDK_VERSION%%/jre/lib/i386/classic/libjvm.so
 %%DEBUG:%%jdk%%JDK_VERSION%%/jre/lib/i386/classic/libjvm_g.so
+%%HOTSPOT:%%jdk%%JDK_VERSION%%/jre/lib/i386/client/Xusage.txt
+%%HOTSPOT:%%jdk%%JDK_VERSION%%/jre/lib/i386/client/libjvm.so
+%%HOTSPOT:%%%%DEBUG:%%jdk%%JDK_VERSION%%/jre/lib/i386/client/libjvm_g.so
 jdk%%JDK_VERSION%%/jre/lib/i386/green_threads/libhpi.so
 %%DEBUG:%%jdk%%JDK_VERSION%%/jre/lib/i386/green_threads/libhpi_g.so
+%%HOTSPOT:%%jdk%%JDK_VERSION%%/jre/lib/i386/hotspot
 jdk%%JDK_VERSION%%/jre/lib/i386/libJdbcOdbc.so
 %%DEBUG:%%jdk%%JDK_VERSION%%/jre/lib/i386/libJdbcOdbc_g.so
 jdk%%JDK_VERSION%%/jre/lib/i386/libagent.so
@@ -855,6 +859,9 @@
 %%DEBUG:%%jdk%%JDK_VERSION%%/jre/lib/i386/libzip_g.so
 %%NATIVE:%%jdk%%JDK_VERSION%%/jre/lib/i386/native_threads/libhpi.so
 %%NATIVE:%%%%DEBUG:%%jdk%%JDK_VERSION%%/jre/lib/i386/native_threads/libhpi_g.so
+%%HOTSPOT:%%jdk%%JDK_VERSION%%/jre/lib/i386/server/Xusage.txt
+%%HOTSPOT:%%jdk%%JDK_VERSION%%/jre/lib/i386/server/libjvm.so
+%%HOTSPOT:%%%%DEBUG:%%jdk%%JDK_VERSION%%/jre/lib/i386/server/libjvm_g.so
 jdk%%JDK_VERSION%%/jre/lib/images/cursors/cursors.properties
 jdk%%JDK_VERSION%%/jre/lib/images/cursors/invalid32x32.gif
 jdk%%JDK_VERSION%%/jre/lib/images/cursors/motif_CopyDrop32x32.gif
@@ -956,8 +963,10 @@
 @dirrm jdk%%JDK_VERSION%%/jre/lib/locale
 @dirrm jdk%%JDK_VERSION%%/jre/lib/images/cursors
 @dirrm jdk%%JDK_VERSION%%/jre/lib/images
+%%HOTSPOT:%%@dirrm jdk%%JDK_VERSION%%/jre/lib/i386/server
 %%NATIVE:%%@dirrm jdk%%JDK_VERSION%%/jre/lib/i386/native_threads
 @dirrm jdk%%JDK_VERSION%%/jre/lib/i386/green_threads
+%%HOTSPOT:%%@dirrm jdk%%JDK_VERSION%%/jre/lib/i386/client
 @dirrm jdk%%JDK_VERSION%%/jre/lib/i386/classic
 @dirrm jdk%%JDK_VERSION%%/jre/lib/i386
 @dirrm jdk%%JDK_VERSION%%/jre/lib/fonts
Index: files/patch-jvm.cfg
===================================================================
RCS file: files/patch-jvm.cfg
diff -N files/patch-jvm.cfg
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ files/patch-jvm.cfg	24 Feb 2003 22:42:20 -0000
@@ -0,0 +1,13 @@
+$FreeBSD$
+
+--- ../src/solaris/bin/jvm.cfg.orig	Mon Feb 24 15:41:30 2003
++++ ../src/solaris/bin/jvm.cfg	Mon Feb 24 15:41:42 2003
+@@ -8,7 +8,7 @@
+ # List of JVMs that can be used as the first option to java, javac, etc.
+ # Order is important -- first in this list is the default JVM.
+ #
++-classic
+ -client
+ -hotspot
+ -server
+--classic
Index: files/patch-platform_i486
===================================================================
RCS file: files/patch-platform_i486
diff -N files/patch-platform_i486
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ files/patch-platform_i486	24 Feb 2003 03:28:00 -0000
@@ -0,0 +1,13 @@
+$FreeBSD$
+
+--- ../../hotspot1.3.1/build/linux/platform_i486	Thu Jan 23 00:28:52 2003
++++ ../../hotspot1.3.1/build/linux/platform_i486	Thu Jan 23 01:14:01 2003
+@@ -6,7 +6,7 @@
+ 
+ lib_arch = i386
+ 
+-compiler = gcc32
++compiler = gcc
+ 
+ gnu_dis_arch = i386
+ 
Index: files/patch-threads_bsd.c
===================================================================
RCS file: files/patch-threads_bsd.c
diff -N files/patch-threads_bsd.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ files/patch-threads_bsd.c	24 Feb 2003 03:34:20 -0000
@@ -0,0 +1,720 @@
+$FreeBSD$
+
+--- ../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	24 Feb 2003 02:22:44 -0000
+@@ -22,27 +22,17 @@
+ #include "np.h"
+ 
+ #include <pthread.h>
++#include <pthread_np.h>
+ 
+ #if defined(__FreeBSD__)
+ 
+-#include <pthread_np.h>
++#include <assert.h>
+ 
+-/* Remove defines from pthread.h so pthread_private.h can be included */
+-#undef pthread_condattr_default
+-#undef pthread_mutexattr_default
+ #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>
+-
+-#include <sys/exec.h>
+-#include <vm/vm.h>
+-#include <vm/pmap.h>
+-#include <machine/pmap.h>
+-#include <machine/vmparam.h>
+-
+ #endif
+ 
+ #include <string.h>
+@@ -63,14 +53,9 @@
+ /* Private functions used to implement native threading. --billh */
+ 
+ #ifdef DEBUG_BSD_NATIVE_THREADS
+-void _pthread_suspend_all_np(void);
+-void _pthread_resume_all_np(void);
+-#endif
+-void record_uc(sys_thread_t *, ucontext_t *);
+-void record_gc_registers_of(sys_thread_t *);
+-
+-void dumpThreadStates();
+ void dumpThreadLogStates(pthread_t);
++void dumpThreadStates();
++#endif
+ 
+ /*
+  * Suspend a thread.  Used to implement java.lang.Thread.suspend(),
+@@ -108,28 +93,24 @@
+ int
+ np_stackinfo(void **addr, long *sizep)
+ {
+-    thread_t self = pthread_self();
+-    int base;
+-    int size;
+-
+-    if (!pthread_equal(self, _thread_initial)) {
+-        *addr = self->stack;
+-	*sizep = (long) PTHREAD_STACK_DEFAULT;
+-
+-    } else {
+-	/* in main()'s thread */
+-	struct rlimit r;
+-
+-	if (getrlimit(RLIMIT_STACK, &r) == -1)
+-	    return SYS_ERR;
+-
+-	/* PS_STRINGS is also from sys/exec.h in FreeBSD, but as macro. --billh */
+-
+-	*addr  = (void *) (PS_STRINGS +1);
+-	*sizep = (long)r.rlim_cur;
+-    }
++    pthread_attr_t attr;
++    size_t size;
+ 
++    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;
+ }
+ 
+ /*
+@@ -177,7 +158,7 @@
+ 	Do this for the FreeBSD implementation too, since this is a silly
+ 	function anyways.  --billh
+ */
+-	return TRUE;
++    return TRUE;
+ }
+ 
+ 
+@@ -190,38 +171,54 @@
+ static void
+ record_thread_regs()
+ {
+-    sys_thread_t *tid;
++    struct pthread *self = pthread_self();
++    sys_thread_t *tid = ThreadQueue;
+     int i;
+-    int sp;
+ 
+-    tid = ThreadQueue;
+-    for (i = 0; i < ActiveThreadCount && tid != 0; i++) {
+-	int i;
+-
+-	if (tid->sys_thread != 0) {
+-#ifdef __bsdi__
+-	    /* if thread has already been initialized */
+-	    if (pthread_getstackpointer_np(tid->sys_thread, &sp) == 0)
+-		tid->sp = sp;
+-	    else
+-		tid->sp = 0;
+-#elif __FreeBSD__
+-#endif
+-            tid->sp = tid->sys_thread->stack;
+-//#endif	//__FreeBSD__
+-/*	Potential race here if the stack isn't setup before GC. --billh */
+-	} else {
++    for (i = 0; i < ActiveThreadCount && tid != NULL; i++, tid = tid->next) {
++	struct pthread *thread = tid->sys_thread;
++
++	if (thread == 0) {
+ 	    /*
+ 	     * thread is still in the process of being initalized.
+ 	     * So GC should not care about this thread. Just
+ 	     * set its sp to 0, and this will force GC to ignore it.
+ 	     */
+ 	    tid->sp = 0;
++	    continue;
+ 	}
+ 
+-	record_gc_registers_of(tid);
++        tid->sp = thread->stack;
++/*	Potential race here if the stack isn't setup before GC. --billh */
+ 
+-	tid = tid->next;
++	/*
++	 * The thread that calls this function will alway be the JVM GC thread,
++	 * so skip over it in the list of threads.
++	 */
++	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 */
++	    tid->regs[1] = 0;		/* ecx (missing) */
++	    tid->regs[2] = 0;		/* edx (missing) */
++	    tid->regs[3] = regbase[1];	/* ebx */
++	    tid->regs[4] = regbase[3];	/* ebp */
++	    tid->regs[5] = regbase[4];	/* esi */
++	    tid->regs[6] = regbase[5];	/* edi */
++
++#ifdef DEBUG_BSD_NATIVE_THREADS
++	    dumpThreadStates();
++#endif
++	}
+     }
+ 
+ #ifdef DEBUG_BSD_NATIVE_THREADS
+@@ -239,14 +236,7 @@
+ {
+     sysAssert(SYS_QUEUE_LOCKED(sysThreadSelf()));
+ 
+-#ifdef DEBUG_BSD_NATIVE_THREADS
+-    _pthread_suspend_all_np();
+-#else
+-    pthread_single_np();
+-#endif
+-
+-//usleep(100000 *3);
+-
++    pthread_suspend_all_np();
+     record_thread_regs();
+     return SYS_OK;
+ }
+@@ -259,42 +249,13 @@
+ np_multi(void)
+ {
+     sysAssert(SYS_QUEUE_LOCKED(sysThreadSelf()));
+-#ifdef DEBUG_BSD_NATIVE_THREADS
+-    _pthread_resume_all_np();
+-#else
+-    pthread_multi_np();
+-#endif
++    pthread_resume_all_np();
+ }
+ 
+-
+-
+-
++#ifdef DEBUG_BSD_NATIVE_THREADS
+ /* pthreads hackery begins --billh */
+ 
+-#define ANALRETENTIVE (6 + 1)
+-
+-char SuspendList[ANALRETENTIVE][16] = 
+-{
+-	"SUSP_NO",		/* Not suspended. */
+-	"SUSP_YES",		/* Suspended. */
+-	"SUSP_JOIN",		/* Suspended, joining. */  
+-	"SUSP_NOWAIT",		/* Suspended, was in a mutex or condition queue. */
+-	"SUSP_MUTEX_WAIT",	/* Suspended, still in a mutex queue. */
+-	"SUSP_COND_WAIT",	/* Suspended, still in a condition queue. */
+-	"susp boundless"
+-};
+-
+-char *getSuspendStateString(enum pthread_susp suspendState)
+-{
+-	if (suspendState < ANALRETENTIVE)
+-		return &SuspendList[suspendState][0];
+-	else 
+-		return &SuspendList[ANALRETENTIVE-1][0];
+-}
+-
+-#define SATAN (21 + 1) /* for the error string at the end of the list */
+-
+-char SignalList [SATAN][16]
++char SignalList [][16]
+ =
+ {
+ 	"PS_RUNNING",
+@@ -316,18 +277,17 @@
+ 	"PS_JOIN",
+ 	"PS_SUSPENDED",
+ 	"PS_DEAD",
+-	"PS_DEADLCK",
++	"PS_DEADLOCK",
+ 	"PS_STATE_MAX",
+-	"PS_REQUEST_WAITING_SUSPENDED",
+ 	"boundless"
+ };
+ 
+ char *getThreadStateString(enum pthread_state threadState)
+ {
+ 	if (threadState < SATAN)
+-		return &SignalList[threadState][0];
+-	else 
+-		return &SignalList[SATAN-1][0];
++		return SignalList[threadState];
++	else
++		return SignalList[SATAN-1];
+ }
+ 
+ void dumpThreadStates()
+@@ -336,114 +296,29 @@
+ 	struct pthread	*thread;
+ 	struct pthread	*self = pthread_self();
+ 
+-#ifdef DEBUG_BSD_NATIVE_THREADS
+ 	_thread_kern_sig_defer();
+ 	TAILQ_FOREACH(thread, &_thread_list, tle) {
+ 		if (thread != self) { /* special case this --billh */
+-			printf("\tthread %d\t%s\t%s\n",
++			printf("\tthread %d\t%s\n",
+ 				threadCount,
+-				getThreadStateString(thread->state),
+-				getSuspendStateString(thread->suspended));
++				getThreadStateString(thread->state));
+ 
+ 			if (thread->state != PS_SUSPENDED)
+ 				dumpThreadLogStates(thread);
+-		}
+-		else
+-		{
+-			printf("\tgc thread %d\t%s\t%s\n",
++		} else {
++			printf("\tgc thread %d\t%s\n",
+ 				threadCount,
+-				getThreadStateString(thread->state),
+-				getSuspendStateString(thread->suspended));
++				getThreadStateString(thread->state))
+ 		}
+ 		++threadCount;
+ 	}
+ 	_thread_kern_sig_undefer();
+ 	printf("\n");
+-#endif
+-}
+-
+-
+-#ifdef DEBUG_BSD_NATIVE_THREADS
+-extern void _pthread_suspend_np_by_pthread_common(pthread_t);
+-extern void _pthread_resume_by_pthread_common(pthread_t, enum pthread_susp);
+-
+-void
+-_pthread_suspend_all_np(void)
+-{
+-	struct pthread	*thread;
+-	struct pthread	*self = pthread_self();
+-
+-fprintf(stderr, "pthread_suspend_all_np\n");
+-	/*
+-	 * Defer signals to protect the scheduling queues from
+-	 * access by the signal handler:
+-	 */
+-	_thread_kern_sig_defer();
+-
+-	/* Suspend all threads other than the current thread: */
+-	TAILQ_FOREACH(thread, &_thread_list, tle) {
+-		if (thread != self) {
+-			_pthread_suspend_np_by_pthread_common(thread);
+-		}
+-	}
+-
+-	/*
+-	 * Undefer and handle pending signals, yielding if necessary:
+-	 */
+-	_thread_kern_sig_undefer();
+-fprintf(stderr, "pthread_suspend_all_np END\n");
+-}
+-
+-/* Resume a thread: */
+-void
+-_pthread_resume_all_np(void)
+-{
+-	enum		pthread_susp old_suspended;
+-	struct pthread	*thread;
+-	struct pthread	*self = pthread_self();
+-
+-fprintf(stderr, "pthread_resume_all_np\n");
+-	_thread_kern_sig_defer();
+-
+-	/*
+-		Iterate through the thread list and resume suspended threads.
+-		this is copied from pthread_resume_np(). --billh
+-	*/
+-
+-	TAILQ_FOREACH(thread, &_thread_list, tle) {
+-		if (thread != self) {
+-			/* Cancel any pending suspensions: */
+-
+-			old_suspended = thread->suspended;
+-			thread->suspended = SUSP_NO;
+-
+-			_pthread_resume_by_pthread_common(thread, old_suspended);
+-
+-		} // if !thread_self
+-	} // TAILQ_FOREACH
+-
+-	/*
+-	 * Undefer and handle pending signals, yielding if
+-	 * necessary:
+-	 */
+-	_thread_kern_sig_undefer();
+-fprintf(stderr, "pthread_resume_all_np END\n");
+ }
+-#endif
+ 
+ /*
+ 	[A snippet from Dan Eichen's email on the subject]
+ 
+-	It uses _longjmp (non-signal-saving/restoring) for the most part.
+-	The only exception is when the process (currently running thread) is 
+-	interrupted by a signal.  So your context types are a jmp_buf and
+-	a ucontext_t (if interrupted by a signal).  If thread->ctxtype is
+-	CTX_UC, the context is stored as a ucontext in thread->ctx.uc.
+-	Otherwise, the context is stored as a jmp_buf in thread->ctx.jb.
+-	We don't currently use CTX_JB and CTX_SJB, so don't even bother
+-	with those cases.  Those should go away actually; all we need
+-	to know is if it is a ucontext_t or a jmp_buf.
+-
+ 	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 +337,8 @@
+ 	--billh
+ */
+ 
+-void clear_gc_registers(sys_thread_t * jthread)
+-{
+-/* clear out x86 registers for the thread's "self" --billh */
+-
+-	jthread->regs[0] = 0; jthread->regs[1] = 0;
+-	jthread->regs[2] = 0; jthread->regs[3] = 0;
+-	jthread->regs[4] = 0; jthread->regs[5] = 0;
+-	jthread->regs[6] = 0;
+-}
+-
+ void dumpThreadLogStates(pthread_t thread)
+ {
+-#ifdef DEBUG_BSD_NATIVE_THREADS
+ int i;
+ 	for(i=0; i < STATE_LOG_SIZE; ++i)
+ 	{
+@@ -494,311 +358,5 @@
+ 		}
+ 	}
+ 	printf("\t\t***XXX\n");
+-#endif
+-}
+-
+-void record_gc_registers_of(sys_thread_t *javaThread)
+-{
+-struct pthread	*self	= pthread_self();
+-struct pthread	*thread	= NULL;
+-
+-	assert( javaThread != NULL );
+-	assert( javaThread->sys_thread != NULL );
+-
+-	thread = javaThread->sys_thread;
+-
+-	/*
+-	 * The thread that calls this function will alway be the JVM GC thread,
+-	 * so skip over it in the list of threads.
+-	 */
+-	if (	(thread == self)
+-		|| ((thread->flags & PTHREAD_FLAGS_PRIVATE) != 1)
+-	   )
+-	{
+-		record_uc(javaThread, &thread->ctx.uc);
+-#ifdef DEBUG_BSD_NATIVE_THREADS
+-		goto Terminate; // And do nothing with this pthread entry. 
+-#endif
+-	}
+-
+-	/*
+-	 * Got search candiate..
+-	 */
+-	if (thread->state != PS_SUSPENDED)
+-		dumpThreadLogStates(thread);
+-
+-	switch ((int)thread->ctxtype)
+-	{
+-		case CTX_JB_NOSIG:	/* 0) jmp_buf context without signal mask for blocking IO, etc... */
+-		case CTX_JB:		/* 1) should never be CTX_JB */
+-		case CTX_SJB:		/* 2) should never be CTX_SJB */
+-			clear_gc_registers(javaThread);
+-#ifdef DEBUG_BSD_NATIVE_THREADS
+-			goto Terminate;
+-#endif
+-			break;
+-		case CTX_UC:		/* 3) */
+-			/* context is a ucontext_t */
+-			record_uc(javaThread, &thread->ctx.uc);
+-#ifdef DEBUG_BSD_NATIVE_THREADS
+-			goto Terminate;
+-#endif
+-			break;
+-		default:
+-#ifdef DEBUG_BSD_NATIVE_THREADS
+-			fprintf(stderr, "ctxtype failed %d.\n", thread->ctxtype);
+-			goto TermFailed;
+-#endif
+-			break;
+-	}
+-
+-#ifdef DEBUG_BSD_NATIVE_THREADS
+-TermFailed:
+-	fprintf(stderr, "Failed to find pthread struct.\n"); fflush(stderr);
+-	assert(0);
+-
+-Terminate:
+-	dumpThreadStates();
+-#endif
+ }
+-
+-void record_uc(sys_thread_t *t, ucontext_t *uc)
+-{
+-	mcontext_t *mc = &(uc->uc_mcontext);
+-
+-	t->regs[0] = mc->mc_eax;
+-	t->regs[1] = mc->mc_ecx;
+-	t->regs[2] = mc->mc_edx;
+-	t->regs[3] = mc->mc_ebx;
+-	t->regs[4] = mc->mc_ebp;
+-	t->regs[5] = mc->mc_esi;
+-	t->regs[6] = mc->mc_edi;
+-}
+-
+-/*
+-From /usr/src/lib/libc/i386/gen/_setjmp.S:
+-ENTRY(_setjmp)
+-	movl	4(%esp),%eax
+-	movl	0(%esp),%edx
+-	movl	%edx, 0(%eax)	/ * rta * /
+-	movl	%ebx, 4(%eax)
+-	movl	%esp, 8(%eax)
+-	movl	%ebp,12(%eax)
+-	movl	%esi,16(%eax)
+-	movl	%edi,20(%eax)
+-	fnstcw	24(%eax)
+-	xorl	%eax,%eax
+-	ret
+-
+-typedef JmpBufStruct
+-{
+-	int	edx, // Accumulator for operands and results data.
+-		ebx, // Pointer to data in the DS segment.
+-		esp, // Stack pointer (in the SS segment).
+-		ebp, // Pointer to data on the stack (in the SS segment).
+-		esi, // Pointer to data in the segment pointer to by the DS register; source pointer for string operations.
+-		edi; // Pointer to data (or destination) in the segment pointer to by the ES register; destination pointer for string operations.
+-
+-} JmpBufStruct;
+-
+-
+-void record_jb(sys_thread_t *t, JmpBufStruct *jb)
+-{
+-	t->regs[0] = jb->eax; // What about these two register ? they seem missing in jmp_buf.
+-	t->regs[1] = / *jb->ecx;* / 0;
+-	t->regs[2] = jb->edx; // The rest of these registers are defined...
+-	t->regs[3] = jb->ebx;
+-	t->regs[4] = jb->ebp;
+-	t->regs[5] = jb->esi;
+-	t->regs[6] = jb->edi;
+-}
+-*/
+-
+-#if 0
+-static void
+-finish_suspension(void *arg)
+-{
+-	if (_thread_run->suspended != SUSP_NO)
+-		_thread_kern_sched_state(PS_SUSPENDED, __FILE__, __LINE__);
+-}
+-
+-void _pthread_suspend_np_by_pthread_common(pthread_t thread)
+-{
+-struct timeval  tv;
+-struct timespec current_ts;
+-
+-	switch (thread->state) {
+-	case PS_RUNNING:
+-		/*
+-		 * Remove the thread from the priority queue and
+-		 * set the state to suspended:
+-		 */
+-		PTHREAD_PRIOQ_REMOVE(thread);
+-		PTHREAD_SET_STATE(thread, PS_SUSPENDED);
+-		break;
+-
+-	case PS_SPINBLOCK:
+-	case PS_FDR_WAIT:
+-	case PS_FDW_WAIT:
+-	case PS_POLL_WAIT:
+-	case PS_SELECT_WAIT:
+-		/*
+-		 * Remove these threads from the work queue
+-		 * and mark the operation as interrupted:
+-		 */
+-		if ((thread->flags & PTHREAD_FLAGS_IN_WORKQ) != 0)
+-			PTHREAD_WORKQ_REMOVE(thread);
+-		_thread_seterrno(thread,EINTR);
+-
+-		/* FALLTHROUGH */
+-	case PS_SLEEP_WAIT:
+-		thread->interrupted = 1;
+-
+-		/* FALLTHROUGH */
+-	case PS_SIGTHREAD:
+-	case PS_WAIT_WAIT:
+-	case PS_SIGSUSPEND:
+-	case PS_SIGWAIT:
+-		/*
+-		 * Remove these threads from the waiting queue and
+-		 * set their state to suspended:
+-		 */
+-		PTHREAD_WAITQ_REMOVE(thread);
+-		PTHREAD_SET_STATE(thread, PS_SUSPENDED);
+-		break;
+-
+-	case PS_MUTEX_WAIT:
+-		/* Mark the thread as suspended and still in a queue. */
+-		thread->suspended = SUSP_MUTEX_WAIT;
+-
+-		PTHREAD_SET_STATE(thread, PS_SUSPENDED);
+-		break;
+-	case PS_COND_WAIT:
+-#if 0
+-		/* This is for a pthreads_cond_timedwait() --billh */
+-		if (thread->wakeup_time.tv_sec != -1) {
+-			/* (1) Use to restore the waiting-queue time that's left when the
+-			 * thread is resumed. --billh
+-			 */
+-			_subtract_timespec3(thread, &current_ts, &thread->remaining_wakeup_time);
+-
+-			/* (2) So that it's inserted at the end of the waiting queue and
+-			 * not scanned by the uthreads_kern.c waiting queue logic. It also
+-			 * means to make it wait forever.
+-			 */
+-			thread->wakeup_time.tv_sec  = -1;
+-			thread->wakeup_time.tv_nsec = -1;
+-
+-			/* (3) Remove and reinsert it at the end of waiting-queue
+-			 * (automatic on the insertion attempt when (2)).
+-			 */
+-			PTHREAD_WORKQ_REMOVE(thread);
+-			PTHREAD_WORKQ_INSERT(thread);
+-		}
+-#endif
+-
+-		/* Mark the thread as suspended and still in a queue. */
+-		thread->suspended = SUSP_COND_WAIT;
+-
+-		PTHREAD_SET_STATE(thread, PS_SUSPENDED);
+-		break;
+-	case PS_JOIN:
+-		/* Mark the thread as suspended and joining: */
+-		thread->suspended = SUSP_JOIN;
+-
+-		PTHREAD_NEW_STATE(thread, PS_SUSPENDED);
+-		break;
+-	case PS_FDLR_WAIT:
+-	case PS_FDLW_WAIT:
+-	case PS_FILE_WAIT:
+-		/* Mark the thread as suspended: */
+-		thread->suspended = SUSP_YES;
+-
+-		/*
+-		 * Threads in these states may be in queues.
+-		 * In order to preserve queue integrity, the
+-		 * cancelled thread must remove itself from the
+-		 * queue.  Mark the thread as interrupted and
+-		 * set the state to running.  When the thread
+-		 * resumes, it will remove itself from the queue
+-		 * and call the suspension completion routine.
+-		 */
+-		thread->interrupted = 1;
+-		_thread_seterrno(thread, EINTR);
+-		PTHREAD_NEW_STATE(thread, PS_RUNNING);
+-		thread->continuation = finish_suspension;
+-		break;
+-
+-	case PS_DEAD:
+-	case PS_DEADLOCK:
+-	case PS_STATE_MAX:
+-	case PS_SUSPENDED:
+-		/* Nothing needs to be done: */
+-		break;
+-	}
+-}
+-
+-void _pthread_resume_by_pthread_common(pthread_t thread, enum pthread_susp old_suspended)
+-{
+-struct timeval  tv;
+-struct timespec current_ts,
+-		remaining_spec;
+-
+-	/* Is it currently suspended? */
+-	if (thread->state == PS_SUSPENDED) {
+-		/*
+-		 * Defer signals to protect the scheduling queues
+-		 * from access by the signal handler:
+-		 */
+-		_thread_kern_sig_defer();
+-
+-		switch (old_suspended) {
+-		case SUSP_MUTEX_WAIT:
+-			/* Set the thread's state back. */
+-			PTHREAD_SET_STATE(thread,PS_MUTEX_WAIT);
+-			break;
+-		case SUSP_COND_WAIT:
+-			/* For cases where it was doing a pthread_cond_timedwait()
+-			 * Mark the remaining suspend time.
+-			 * --billh
+-			 */
+-#if 0
+-			if (thread->remaining_wakeup_time.tv_sec != -1) {
+-				GET_CURRENT_TOD(tv);
+-				TIMEVAL_TO_TIMESPEC(&tv, &current_ts);
+-
+-				_subtract_timespec3(remaining_spec, &thread->wakeup_time, &current_ts);
+-				_thread_kern_set_timeout_by_pthread_timespec(thread, &remaining_spec);
+-			}
+-#endif
+-
+-			/* Set the thread's state back. */
+-			PTHREAD_SET_STATE(thread,PS_COND_WAIT);
+-			break;
+-		case SUSP_JOIN:
+-			/* Set the thread's state back. */
+-			PTHREAD_SET_STATE(thread,PS_JOIN);
+-			break;
+-		case SUSP_NOWAIT:
+-			/* Allow the thread to run. */
+-			PTHREAD_SET_STATE(thread,PS_RUNNING);
+-			PTHREAD_WAITQ_REMOVE(thread);
+-			PTHREAD_PRIOQ_INSERT_TAIL(thread);
+-			break;
+-		case SUSP_NO:
+-		case SUSP_YES:
+-			/* Allow the thread to run. */
+-			PTHREAD_SET_STATE(thread,PS_RUNNING);
+-			PTHREAD_PRIOQ_INSERT_TAIL(thread);
+-			break;
+-		}
+-
+-		/*
+-		 * Undefer and handle pending signals, yielding if
+-		 * necessary:
+-		 */
+-		_thread_kern_sig_undefer();
+-	}
+-}
+-
+ #endif
Index: files/patch-threads_md.c
===================================================================
RCS file: files/patch-threads_md.c
diff -N files/patch-threads_md.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ files/patch-threads_md.c	24 Feb 2003 03:34:13 -0000
@@ -0,0 +1,12 @@
+$FreeBSD$
+
+--- ../src/solaris/hpi/native_threads/src/threads_md.c	21 Nov 2001 04:02:04 -0000	1.4
++++ ../src/solaris/hpi/native_threads/src/threads_md.c	24 Feb 2003 03:17:30 -0000
+@@ -23,6 +23,7 @@
+ #include <setjmp.h>
+ #include <signal.h>
+ #include <sys/types.h>
++#include <sys/time.h>
+ #include <sys/signal.h>
+ #include <sys/resource.h>
+ #ifdef __FreeBSD__

--bp/iNruPH9dso1Pn--

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-java" in the body of the message




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