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, ¤t_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, ¤t_ts); +- +- _subtract_timespec3(remaining_spec, &thread->wakeup_time, ¤t_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>