[kaffe] CVS kaffe (hkraemer): cleanup of thread handling

Kaffe CVS Kaffe Mailing List <kaffe@kaffe.org>
Sun Feb 1 14:17:03 2004


PatchSet 4381 
Date: 2004/02/01 22:14:46
Author: hkraemer
Branch: HEAD
Tag: (none) 
Log:
cleanup of thread handling

This patch moves the vm specific part of java.lang.Thread into threadData.
This makes the core a little bit more readable and type safe.

Also included is a partial implementation of the AttachCurrentThread jni
function for the unix-pthreads system.

Members: 
	ChangeLog:1.1965->1.1966 
	kaffe/kaffevm/exception.c:1.76->1.77 
	kaffe/kaffevm/gcRefs.c:1.11->1.12 
	kaffe/kaffevm/jar.h:1.7->1.8 
	kaffe/kaffevm/jni.c:1.100->1.101 
	kaffe/kaffevm/jnirefs.h:1.1->1.2 
	kaffe/kaffevm/locks.c:1.46->1.47 
	kaffe/kaffevm/locks.h:1.22->1.23 
	kaffe/kaffevm/support.c:1.61->1.62 
	kaffe/kaffevm/thread.c:1.56->1.57 
	kaffe/kaffevm/thread.h:1.16->1.17 
	kaffe/kaffevm/threadData.h:1.2->1.3 
	kaffe/kaffevm/intrp/icode.h:1.19->1.20 
	kaffe/kaffevm/intrp/machine.c:1.36->1.37 
	kaffe/kaffevm/intrp/machine.h:1.9->1.10 
	kaffe/kaffevm/intrp/stackTrace-impl.h:1.3->1.4 
	kaffe/kaffevm/jit/machine.c:1.59->1.60 
	kaffe/kaffevm/systems/unix-jthreads/jthread.c:1.106->1.107 
	kaffe/kaffevm/systems/unix-jthreads/jthread.h:1.50->1.51 
	kaffe/kaffevm/systems/unix-pthreads/lock-impl.c:1.5->1.6 
	kaffe/kaffevm/systems/unix-pthreads/lock-impl.h:1.4->1.5 
	kaffe/kaffevm/systems/unix-pthreads/thread-impl.c:1.17->1.18 
	kaffe/kaffevm/systems/unix-pthreads/thread-internal.h:1.10->1.11 
	libraries/javalib/Klasses.jar.bootstrap:1.46->1.47 
	libraries/javalib/java/lang/Thread.java:1.43->1.44 

Index: kaffe/ChangeLog
diff -u kaffe/ChangeLog:1.1965 kaffe/ChangeLog:1.1966
--- kaffe/ChangeLog:1.1965	Sun Feb  1 16:28:33 2004
+++ kaffe/ChangeLog	Sun Feb  1 22:14:46 2004
@@ -1,3 +1,60 @@
+2004-02-01  Helmer Kramer <hkraemer@freenet.de>
+
+	* libraries/javalib/java/lang/Thread.java
+	(threadQ), (sFunc), (sArg), (exceptPtr), (exceptObj),
+	(jnireferences), (stackOverflowError), (outOfMemoryError),
+	(sem), (nextlk), (needOnStack): removed
+
+	* kaffe/kaffevm/threadData.h
+	(jnireferences), (sem), (nextlk), (exceptPtr), (exceptObj),
+	(needOnStack): new fields replacing those in java.lang.Thread.
+
+	* kaffe/kaffevm/exception.c, kaffe/kaffevm/jni.c,
+	kaffe/kaffevm/locks.c, kaffe/kaffevm/locks.h,
+	kaffe/kaffevm/support.c, kaffe/kaffevm/intrp/icode.h,
+	kaffe/kaffevm/intrp/machine.c, kaffe/kaffevm/intrp/machine.h,
+	kaffe/kaffevm/intrp/stackTrace-impl.h, kaffe/kaffevm/jit/machine.c:
+	adapted to java.lang.Thread -> threadData change.
+
+	* kaffe/kaffevm/jni.c (Kaffe_AttachCurrentThread): implemented
+	
+	* kaffe/kaffevm/gcRefs.c
+	(TwalkThread), (liveThreadWalker): pass jthread_t, not
+	Hjava_lang_Thread* as parameter
+
+	* kaffe/kaffevm/jar.h: don't include locks.h for KAFFEH
+
+	* kaffe/kaffevm/thread.c (linkNativeAndJavaThread),
+	(unlinkNativeAndJavaThread): new methods
+	(initThreadLock): removed
+	(createInitialThread): renamed to attachFakedThreadInstance
+	(initNativeThreads): create initial thread here
+
+	adapted to java.lang.Thread -> threadData change
+
+	* kaffe/kaffevm/systems/unix-jthreads/jthread.c
+	(jthread_walkLiveThreads): pass jthread_t as parameter
+	(jthread_createfirst): tweak guestimation of stack
+
+	* kaffe/kaffevm/systems/unix-jthreads/jthread.h
+	(jthread_attach_current_thread): new method
+
+	* kaffe/kaffevm/systems/unix-pthreads/lock-impl.h,
+	kaffe/kaffevm/systems/unix-pthreads/lock-impl.c
+	(jmutex_lock): deinlined
+
+	* kaffe/kaffevm/systems/unix-pthreads/thread-internal.h
+	(struct _nativeThread): renamed to struct _jthread
+
+	* kaffe/kaffevm/systems/unix-pthreads/thread-impl.c
+	(jthread_attach_current_thread): partially implemented
+	(jthread_createfirst): tweak guestimation of stack
+	(jthread_walkLiveThreads): pass jthread_t as parameter
+
+	adapted to struct _nativeThread renaming
+	
+	* libraries/javalib/Klasses.jar.bootstrap: regenerated
+
 2004-02-01  Dalibor Topic <robilad@kaffe.org>
 
         developers/autogen.sh:
Index: kaffe/kaffe/kaffevm/exception.c
diff -u kaffe/kaffe/kaffevm/exception.c:1.76 kaffe/kaffe/kaffevm/exception.c:1.77
--- kaffe/kaffe/kaffevm/exception.c:1.76	Sun Jan 25 19:08:55 2004
+++ kaffe/kaffe/kaffevm/exception.c	Sun Feb  1 22:14:52 2004
@@ -61,7 +61,7 @@
                                     vmExcept_jumpToHandler((VmExceptHandler *)(F)); /* Does not return */
 #else
 
-#define DISPATCH_EXCEPTION(F,H,E) unhand(ct)->exceptObj = 0;\
+#define DISPATCH_EXCEPTION(F,H,E) thread_data->exceptObj = 0;\
                                   CALL_KAFFE_EXCEPTION((F),(H),(E));
 
 #endif	/* TRANSLATOR */
@@ -302,7 +302,7 @@
 static void
 dispatchException(Hjava_lang_Throwable* eobj, stackTraceInfo* baseFrame)
 {
-	Hjava_lang_Thread*	ct;
+	threadData*		thread_data;
 	VmExceptHandler*	lastJniFrame;
 	stackTraceInfo*		frame;
 
@@ -314,10 +314,10 @@
 	 */
 	assert(!INTS_DISABLED());
 #endif
-	ct = getCurrentThread();
+	thread_data = THREAD_DATA(); 
 
 	/* Save exception object */
-	unhand(ct)->exceptObj = eobj;
+	thread_data->exceptObj = eobj;
 
 #if defined (HAVE_GCJ_SUPPORT)
 	/* XXX */
@@ -333,7 +333,7 @@
 	 * (there is _always_ a jni frame somewhere on the stack,
 	 *  except during initialiseKaffe() )
 	 */
-	for (lastJniFrame = (VmExceptHandler *)unhand(ct)->exceptPtr;
+	for (lastJniFrame = thread_data->exceptPtr;
 	     lastJniFrame && !vmExcept_isJNIFrame(lastJniFrame);
 	     lastJniFrame = lastJniFrame->prev);
 
@@ -349,7 +349,7 @@
 		 * if we reach the last jni frame, we're done
 		 */
 		if (lastJniFrame && vmExcept_JNIContains(lastJniFrame, frame->fp)) {
-			unhand(ct)->exceptPtr = (struct Hkaffe_util_Ptr *)lastJniFrame;
+			thread_data->exceptPtr = lastJniFrame;
 			vmExcept_jumpToHandler(lastJniFrame); /* doesn't return */
 		}
 
@@ -380,7 +380,7 @@
 
 		/* If handler found, call it */
 		if (foundHandler) {
-			unhand(ct)->needOnStack = STACK_HIGH;
+			thread_data->needOnStack = STACK_HIGH;
 			DISPATCH_EXCEPTION(frame->fp, handler, eobj); /* doesn't return */
 		}
 
@@ -414,12 +414,9 @@
 {
 	const char* cname;
 	Hjava_lang_Class* class;
-	Hjava_lang_Thread* ct;
-
-	ct = getCurrentThread();
 
 	/* Clear held exception object */
-	unhand(ct)->exceptObj = 0;
+	THREAD_DATA()->exceptObj = 0;
 
 	class = OBJECT_CLASS(&eobj->base);
 	cname = CLASS_CNAME(class);
Index: kaffe/kaffe/kaffevm/gcRefs.c
diff -u kaffe/kaffe/kaffevm/gcRefs.c:1.11 kaffe/kaffe/kaffevm/gcRefs.c:1.12
--- kaffe/kaffe/kaffevm/gcRefs.c:1.11	Sat Jul 26 16:50:49 2003
+++ kaffe/kaffe/kaffevm/gcRefs.c	Sun Feb  1 22:14:53 2004
@@ -102,17 +102,16 @@
  */     
 static  
 void    
-TwalkThread(Collector* collector, Hjava_lang_Thread* tid)
+TwalkThread(Collector* collector, jthread_t jtid)
 {       
         void *from;
         unsigned len;  
-        jthread_t jtid = (jthread_t)unhand(tid)->PrivateInfo;
         
         /* Don't walk the gc thread's stack.  It was not stopped and
          * we hence don't have valid sp information.  In addition, there's
          * absolutely no reason why we should walk it at all.
          */
-        if (jtid == 0 || tid == jthread_get_data((void*)jthread_current())->jlThread) {
+        if (jtid == jthread_current()) {
 DBG(JTHREAD,
                 dprintf("%p NOT walking jtid %p\n", jthread_current(), jtid);
     )   
@@ -125,7 +124,7 @@
          */
         if (jthread_extract_stack(jtid, &from, &len)) {
 DBG(JTHREAD|DBG_GCWALK,
-                dprintf("walking stack of `%s' thread\n", nameThread(tid));
+                dprintf("walking stack of `%s' thread\n", nameThread(jthread_get_data(jtid)->jlThread));
     )
                 /* and walk it if needed */
                 GC_walkConservative(collector, from, len);
@@ -142,12 +141,19 @@
  * soft_instanceof in walkObject, which is a big source of overhead.
  */
 static void
-liveThreadWalker(void *tid)
+liveThreadWalker(jthread_t tid)
 {
   Collector *c = running_collector;
+  threadData *thread_data = jthread_get_data(tid);
 
-  GC_markObject(c, tid);
-  TwalkThread(c, (Hjava_lang_Thread *)tid);
+  GC_markObject(c, thread_data->jlThread);
+  
+  if (thread_data->exceptObj != NULL)
+  {
+    GC_markObject(c, thread_data->exceptObj);
+  }
+
+  TwalkThread(c, tid);
 }
 
 /*
Index: kaffe/kaffe/kaffevm/jar.h
diff -u kaffe/kaffe/kaffevm/jar.h:1.7 kaffe/kaffe/kaffevm/jar.h:1.8
--- kaffe/kaffe/kaffevm/jar.h:1.7	Mon Jan  6 17:14:20 2003
+++ kaffe/kaffe/kaffevm/jar.h	Sun Feb  1 22:14:53 2004
@@ -14,7 +14,9 @@
 #define __jar_h
 
 #include <sys/types.h>
+#if !defined(KAFFEH)
 #include "locks.h"
+#endif
 
 /*
  * JAR files are like ZIP files, they're basically a series of records
Index: kaffe/kaffe/kaffevm/jni.c
diff -u kaffe/kaffe/kaffevm/jni.c:1.100 kaffe/kaffe/kaffevm/jni.c:1.101
--- kaffe/kaffe/kaffevm/jni.c:1.100	Thu Jan 22 22:35:15 2004
+++ kaffe/kaffe/kaffevm/jni.c	Sun Feb  1 22:14:53 2004
@@ -9,10 +9,6 @@
  * of this file. 
  */
 
-#if 0
-#define	NEED_JNIREFS	/* Define to mange local JNI refs */
-#endif
-
 #include "config.h"
 #include "config-std.h"
 #include "config-mem.h"
@@ -130,28 +126,28 @@
  */
 #define	BEGIN_EXCEPTION_HANDLING(X)			\
 	VmExceptHandler ebuf;				\
+	threadData *thread_data = THREAD_DATA();	\
 	KAFFE_JNI_SETEXCEPTFP(&ebuf); 			\
-	ebuf.prev = (VmExceptHandler*)(unhand(getCurrentThread())->exceptPtr);\
+	ebuf.prev = thread_data->exceptPtr;\
 	if (JTHREAD_SETJMP(ebuf.jbuf) != 0) {		\
-		unhand(getCurrentThread())->exceptPtr = \
-		  (struct Hkaffe_util_Ptr*)ebuf.prev;	\
+		thread_data->exceptPtr = ebuf.prev;	\
 		return X;				\
 	}						\
-	unhand(getCurrentThread())->exceptPtr = (void *) &ebuf
+	thread_data->exceptPtr = &ebuf
 
 #define	BEGIN_EXCEPTION_HANDLING_VOID()			\
 	VmExceptHandler ebuf; 				\
+	threadData *thread_data = THREAD_DATA();	\
 	KAFFE_JNI_SETEXCEPTFP(&ebuf); 			\
-	ebuf.prev = (VmExceptHandler*)(unhand(getCurrentThread())->exceptPtr);\
+	ebuf.prev = thread_data->exceptPtr;	\
 	if (JTHREAD_SETJMP(ebuf.jbuf) != 0) {		\
-		unhand(getCurrentThread())->exceptPtr = \
-		  (struct Hkaffe_util_Ptr*)ebuf.prev;	\
+		thread_data->exceptPtr = ebuf.prev; \
 		return;					\
 	}						\
-	unhand(getCurrentThread())->exceptPtr = (void *) &ebuf
+	thread_data->exceptPtr = &ebuf
 
 #define	END_EXCEPTION_HANDLING()			\
-	unhand(getCurrentThread())->exceptPtr = (void *) ebuf.prev
+	thread_data->exceptPtr = ebuf.prev
 
 /*
  * Get and set fields.
@@ -206,7 +202,7 @@
 
 	/* Setup JNI for main thread */
 #if defined(NEED_JNIREFS)
-	unhand(getCurrentThread())->jnireferences = gc_malloc(sizeof(jnirefs), &gcNormal);
+	THREAD_DATA()->jnireferences = (jnirefs *)gc_malloc(sizeof(jnirefs), &gcNormal);
 #endif
 
 	/* Return the VM and JNI we're using */
@@ -423,15 +419,9 @@
 	{
 		assert(((Hjava_lang_Object *)obj)->dtable);
 		
-		unhand(getCurrentThread())->exceptObj =
-			(struct Hjava_lang_Throwable*)obj;
-	}
-	else
-	{
-		unhand(getCurrentThread())->exceptObj =
-			unhand(getCurrentThread())->outOfMemoryError;
+		thread_data->exceptObj = (struct Hjava_lang_Throwable*)obj;
 	}
-	
+
 	END_EXCEPTION_HANDLING();
 	return (0);
 }
@@ -447,7 +437,7 @@
 					"(Ljava/lang/String;)V",
 					checkPtr(stringC2Java((char*)mess)));
 
-	unhand(getCurrentThread())->exceptObj = (struct Hjava_lang_Throwable*)eobj;
+	thread_data->exceptObj = (struct Hjava_lang_Throwable*)eobj;
 
 	END_EXCEPTION_HANDLING();
 	return (0);
@@ -460,7 +450,7 @@
 
 	BEGIN_EXCEPTION_HANDLING(0);
 
-	obj = unhand(getCurrentThread())->exceptObj;
+	obj = thread_data->exceptObj;
 
 	ADD_REF(obj);
 	END_EXCEPTION_HANDLING();
@@ -475,7 +465,7 @@
 
 	BEGIN_EXCEPTION_HANDLING(0);
 
-	obj = unhand(getCurrentThread())->exceptObj;
+	obj = thread_data->exceptObj;
 	result = (obj == NULL) ? JNI_FALSE : JNI_TRUE;
 
 	END_EXCEPTION_HANDLING();
@@ -487,8 +477,9 @@
 {
 	BEGIN_EXCEPTION_HANDLING_VOID();
 
-	if (unhand(getCurrentThread())->exceptObj != 0) {
-		do_execute_java_method(unhand(getCurrentThread())->exceptObj, "printStackTrace", "()V", 0, 0, unhand(getCurrentThread())->exceptObj); 
+	if (thread_data->exceptObj != 0) {
+		do_execute_java_method(thread_data->exceptObj, "printStackTrace", "()V",
+				       0, 0, thread_data->exceptObj); 
 	}
 	END_EXCEPTION_HANDLING();
 }
@@ -498,7 +489,7 @@
 {
 	BEGIN_EXCEPTION_HANDLING_VOID();
 
-	unhand(getCurrentThread())->exceptObj = 0;
+	thread_data->exceptObj = 0;
 
 	END_EXCEPTION_HANDLING();
 }
@@ -3593,8 +3584,11 @@
 static jint
 Kaffe_AttachCurrentThread(JavaVM* vm, void** penv, ThreadAttachArgs* args)
 {
-	*penv = NULL;
-	return (0);
+	if (jthread_attach_current_thread (false)) {
+		attachFakedThreadInstance ("test attach");
+		return 0;
+	}
+	return -1;
 }
 
 static jint
@@ -4091,37 +4085,37 @@
 static void*
 startJNIcall(void)
 {
+	threadData 	*thread_data = THREAD_DATA();
 #if defined(NEED_JNIREFS)
 	jnirefs* table;
 
 	table = gc_malloc(sizeof(jnirefs), &gcNormal);
-	table->prev = unhand(getCurrentThread())->jnireferences;
-	unhand(getCurrentThread())->jnireferences = table;
+	table->prev = thread_data->jnireferences;
+	thread_data->jnireferences = table;
 #endif
 	/* No pending exception when we enter JNI routine */
-	unhand(getCurrentThread())->exceptObj = 0;
-	return( THREAD_JNIENV() );
+	thread_data->exceptObj = 0;
+	return( &thread_data->jniEnv ); 
 }
 
 static void
 finishJNIcall(void)
 {
 	jref eobj;
-	Hjava_lang_Thread* ct;
+	threadData	*thread_data = THREAD_DATA();
 
-	ct = getCurrentThread();
 #if defined(NEED_JNIREFS)
 	{
 		jnirefs* table;
 
-		table = (jnirefs*)unhand(ct)->jnireferences;
-		unhand(ct)->jnireferences = table->prev;
+		table = thread_data->jnireferences;
+		thread_data->jnireferences = table->prev;
 	}
 #endif
 	/* If we have a pending exception, throw it */
-	eobj = unhand(ct)->exceptObj;
+	eobj = thread_data->exceptObj;
 	if (eobj != 0) {
-		unhand(ct)->exceptObj = 0;
+		thread_data->exceptObj = 0;
 		throwExternalException(eobj);
 	}
 }
@@ -4134,7 +4128,7 @@
 	jnirefs* table;
 	int idx;
 
-	table = (jnirefs*)unhand(getCurrentThread())->jnireferences;
+	table = THREAD_DATA()->jnireferences;
 
 	if (table->used == JNIREFS) {
 		abort();	/* FIX ME */
@@ -4158,7 +4152,7 @@
 	int idx;
 	jnirefs* table;
 
-	table = (jnirefs*)unhand(getCurrentThread())->jnireferences;
+	table = THREAD_DATA()->jnireferences;
 
 	for (idx = 0; idx < JNIREFS; idx++) {
 		if (table->objects[idx] == obj) {
Index: kaffe/kaffe/kaffevm/jnirefs.h
diff -u kaffe/kaffe/kaffevm/jnirefs.h:1.1 kaffe/kaffe/kaffevm/jnirefs.h:1.2
--- kaffe/kaffe/kaffevm/jnirefs.h:1.1	Thu May 28 18:37:01 1998
+++ kaffe/kaffe/kaffevm/jnirefs.h	Sun Feb  1 22:14:53 2004
@@ -12,6 +12,12 @@
 #ifndef __jnirefs_h
 #define	__jnirefs_h
 
+#if 0
+#define NEED_JNIREFS		/* define to manage local jni refs */
+#endif
+
+#ifdef NEED_JNIREFS
+
 #define	JNIREFS				61
 
 typedef struct _jnirefs {
@@ -20,5 +26,7 @@
 	struct _jnirefs*		prev;
 	jref				objects[JNIREFS];
 } jnirefs;
+
+#endif /* NEED_JNIREFS */
 
 #endif
Index: kaffe/kaffe/kaffevm/locks.c
diff -u kaffe/kaffe/kaffevm/locks.c:1.46 kaffe/kaffe/kaffevm/locks.c:1.47
--- kaffe/kaffe/kaffevm/locks.c:1.46	Mon Sep 22 15:31:24 2003
+++ kaffe/kaffe/kaffevm/locks.c	Sun Feb  1 22:14:53 2004
@@ -78,7 +78,6 @@
 {
 	iLock* old;
 	iLock* lk;
-	Hjava_lang_Thread* tid;
 	jlong timeout;
 
 DBG(SLOWLOCKS,
@@ -95,9 +94,8 @@
 		old = *lkp;
 		if (old == LOCKINPROGRESS || !COMPARE_AND_EXCHANGE(lkp, old, LOCKINPROGRESS)) {
 			/* Someone else put the lock in LOCKINPROGRESS state */
-			tid = getCurrentThread();
 			backoffcount++;
-			ksemGet((Ksem*)(unhand(tid)->sem), timeout);
+			ksemGet(&THREAD_DATA()->sem, timeout);
 			/* Back off */
 			timeout = (timeout << 1)|timeout;
 			continue;
@@ -169,7 +167,7 @@
 slowLockMutex(iLock** lkp, void* where, iLock *heavyLock)
 {
 	iLock* lk;
-	Hjava_lang_Thread* tid;
+	jthread_t cur = jthread_current ();
 
 DBG(SLOWLOCKS,
     	dprintf("slowLockMutex(**lkp=%p, where=%p, th=%p)\n",
@@ -196,11 +194,10 @@
 		}
 
 		/* Otherwise wait for holder to release it */
-		tid = getCurrentThread();
-		unhand(tid)->nextlk = lk->mux;
-		lk->mux = tid;
+		jthread_get_data(cur)->nextlk = lk->mux;
+		lk->mux = cur;
 		putHeavyLock(lkp, lk);
-		ksemGet((Ksem*)(unhand(tid)->sem), 0);
+		ksemGet(&jthread_get_data(cur)->sem, 0);
 	}
 }
 
@@ -213,7 +210,7 @@
 slowUnlockMutex(iLock** lkp, void* where, iLock *heavyLock)
 {
 	iLock* lk;
-	Hjava_lang_Thread* tid;
+	jthread_t tid;
 
 DBG(SLOWLOCKS,
     	dprintf("slowUnlockMutex(**lkp=%p, where=%p, th=%p)\n",
@@ -245,11 +242,11 @@
 	 */
 	if (lk->mux != 0) {
 		tid = lk->mux;
-		lk->mux = unhand(tid)->nextlk;
-		unhand(tid)->nextlk = 0;
+		lk->mux = jthread_get_data(tid)->nextlk;
+		jthread_get_data(tid)->nextlk = 0;
 		lk->holder = 0;
 		putHeavyLock(lkp, lk);
-		ksemPut((Ksem*)(unhand(tid)->sem));
+		ksemPut(&jthread_get_data(tid)->sem);
 	}
 	/* If someone's waiting to be signaled keep the heavy in place */
 	else if (lk->cv != 0) {
@@ -305,8 +302,8 @@
 {
 	iLock* lk;
 	void* holder;
-	Hjava_lang_Thread* tid;
-	Hjava_lang_Thread** ptr;
+	jthread_t cur = jthread_current();
+	jthread_t *ptr;
 	jboolean r;
 
 DBG(SLOWLOCKS,
@@ -323,12 +320,11 @@
 		throwException(IllegalMonitorStateException);
 	}
 
-	tid = getCurrentThread();
-	unhand(tid)->nextlk = lk->cv;
-	lk->cv = tid;
+	jthread_get_data(cur)->nextlk = lk->cv;
+	lk->cv = cur;
 	putHeavyLock(lkp, lk);
 	slowUnlockMutex(lkp, holder, heavyLock);
-	r = ksemGet((Ksem*)unhand(tid)->sem, timeout);
+	r = ksemGet(&jthread_get_data(cur)->sem, timeout);
 
 	/* Timeout */
 	if (r == false) {
@@ -336,22 +332,22 @@
 		/* Remove myself from CV or MUX queue - if I'm * not on either
 		 * then I should wait on myself to remove any pending signal.
 		 */
-		for (ptr = &lk->cv; *ptr != 0; ptr = &unhand(*ptr)->nextlk) {
-			if ((*ptr) == tid) {
-				*ptr = unhand(tid)->nextlk;
+		for (ptr = &lk->cv; *ptr != 0; ptr = &jthread_get_data(*ptr)->nextlk) {
+			if ((*ptr) == cur) {
+				*ptr = jthread_get_data(cur)->nextlk;
 				goto found;
 			}
 		}
-		for (ptr = &lk->mux; *ptr != 0; ptr = &unhand(*ptr)->nextlk) {
-			if ((*ptr) == tid) {
-				*ptr = unhand(tid)->nextlk;
+		for (ptr = &lk->mux; *ptr != 0; ptr = &jthread_get_data(*ptr)->nextlk) {
+			if ((*ptr) == cur) {
+				*ptr = jthread_get_data(cur)->nextlk;
 				goto found;
 			}
 		}
 		/* Not on list - so must have been signalled after all -
 		 * decrease the semaphore to avoid problems.
 		 */
-		ksemGet((Ksem*)(unhand(tid)->sem), 0);
+		ksemGet(&jthread_get_data(cur)->sem, 0);
 
 		found:;
 		putHeavyLock(lkp, lk);
@@ -366,7 +362,7 @@
 locks_internal_signalCond(iLock** lkp, iLock *heavyLock)
 {
 	iLock* lk;
-	Hjava_lang_Thread* tid;
+	jthread_t tid;
 
 DBG(SLOWLOCKS,
     	dprintf("_signalCond(**lkp=%p, th=%p)\n",
@@ -383,8 +379,8 @@
 	/* Move one CV's onto the MUX */
 	tid = lk->cv;
 	if (tid != 0) {
-		lk->cv = unhand(tid)->nextlk;
-		unhand(tid)->nextlk = lk->mux;
+		lk->cv = jthread_get_data(tid)->nextlk;
+		jthread_get_data(tid)->nextlk = lk->mux;
 		lk->mux = tid;
 	}
 
@@ -395,7 +391,7 @@
 locks_internal_broadcastCond(iLock** lkp, iLock *heavyLock)
 {
 	iLock* lk;
-	Hjava_lang_Thread* tid;
+	jthread_t tid;
 
 DBG(SLOWLOCKS,
     	dprintf("_broadcastCond(**lkp=%p, th=%p)\n",
@@ -412,8 +408,8 @@
 	/* Move all the CV's onto the MUX */
 	while (lk->cv != 0) {
 		tid = lk->cv;
-		lk->cv = unhand(tid)->nextlk;
-		unhand(tid)->nextlk = lk->mux;
+		lk->cv = jthread_get_data(tid)->nextlk;
+		jthread_get_data(tid)->nextlk = lk->mux;
 		lk->mux = tid;
 	}
 
Index: kaffe/kaffe/kaffevm/locks.h
diff -u kaffe/kaffe/kaffevm/locks.h:1.22 kaffe/kaffe/kaffevm/locks.h:1.23
--- kaffe/kaffe/kaffevm/locks.h:1.22	Tue Jul  8 07:33:49 2003
+++ kaffe/kaffe/kaffevm/locks.h	Sun Feb  1 22:14:53 2004
@@ -13,9 +13,7 @@
 #ifndef __locks_h
 #define __locks_h
 
-#ifndef KAFFEH
 #include "thread-impl.h"
-#endif
 
 #include "md.h"
 
@@ -34,7 +32,6 @@
 #define	signalStaticCond(THING)		locks_internal_signalCond(&(THING)->lock, &(THING)->heavyLock)
 #define	broadcastStaticCond(THING)	locks_internal_broadcastCond(&(THING)->lock, &(THING)->heavyLock)
 
-struct Hjava_lang_Thread;
 struct Hjava_lang_Object;
 
 /*
@@ -46,9 +43,9 @@
  * unlock and for distinguishing recursive invocations).
  */
 typedef struct _iLock {
-	void*				holder;
-	struct Hjava_lang_Thread*	mux;
-	struct Hjava_lang_Thread*	cv;
+	void*		holder;
+	jthread_t	mux;
+	jthread_t	cv;
 } iLock;
 
 typedef struct _iStaticLock {
Index: kaffe/kaffe/kaffevm/support.c
diff -u kaffe/kaffe/kaffevm/support.c:1.61 kaffe/kaffe/kaffevm/support.c:1.62
--- kaffe/kaffe/kaffevm/support.c:1.61	Sun Sep 28 22:30:19 2003
+++ kaffe/kaffe/kaffevm/support.c	Sun Feb  1 22:14:53 2004
@@ -606,12 +606,12 @@
 #endif
 #if defined(INTERPRETER)
 	if ((meth->accflags & ACC_NATIVE) == 0) {
-		virtualMachine(meth, (slots*)call.args, (slots*)call.ret, getCurrentThread());
+		virtualMachine(meth, (slots*)call.args, (slots*)call.ret, THREAD_DATA()); 
 	}
 	else {
 		Hjava_lang_Object* syncobj = 0;
 		VmExceptHandler mjbuf;
-		Hjava_lang_Thread* tid = getCurrentThread();
+		threadData* thread_data = THREAD_DATA(); 
 
 		if (meth->accflags & ACC_SYNCHRONISED) {
 			if (meth->accflags & ACC_STATIC) {
@@ -623,7 +623,7 @@
 			lockObject(syncobj);
 		}
 
-		setupExceptionHandling(&mjbuf, meth, syncobj, tid);
+		setupExceptionHandling(&mjbuf, meth, syncobj, thread_data);
 
 		/* Make the call - system dependent */
 		sysdepCallMethod(&call);
@@ -632,7 +632,7 @@
 			unlockObject(syncobj);
 		}
 
-		cleanupExceptionHandling(&mjbuf, tid);
+		cleanupExceptionHandling(&mjbuf, thread_data);
 	}
 #endif
 	if (!promoted && call.retsize == 1) {
@@ -820,12 +820,12 @@
 #endif
 #if defined(INTERPRETER)
 	if ((meth->accflags & ACC_NATIVE) == 0) {
-		virtualMachine(meth, (slots*)call.args, (slots*)call.ret, getCurrentThread());
+		virtualMachine(meth, (slots*)call.args, (slots*)call.ret, THREAD_DATA()); 
 	}
 	else {
 		Hjava_lang_Object* syncobj = 0;
 		VmExceptHandler mjbuf;
-		Hjava_lang_Thread* tid = getCurrentThread();
+		threadData* thread_data = THREAD_DATA(); 
 
 		if (meth->accflags & ACC_SYNCHRONISED) {
 			if (meth->accflags & ACC_STATIC) {
@@ -837,7 +837,7 @@
 			lockObject(syncobj);
 		}
 
-		setupExceptionHandling(&mjbuf, meth, syncobj, tid);
+		setupExceptionHandling(&mjbuf, meth, syncobj, thread_data);
 
 		/* Make the call - system dependent */
 		sysdepCallMethod(&call);
@@ -846,7 +846,7 @@
 			unlockObject(syncobj);
 		}
 
-		cleanupExceptionHandling(&mjbuf, tid);
+		cleanupExceptionHandling(&mjbuf, thread_data);
 	}
 #endif
 }
Index: kaffe/kaffe/kaffevm/thread.c
diff -u kaffe/kaffe/kaffevm/thread.c:1.56 kaffe/kaffe/kaffevm/thread.c:1.57
--- kaffe/kaffe/kaffevm/thread.c:1.56	Sat Oct 11 20:45:49 2003
+++ kaffe/kaffe/kaffevm/thread.c	Sun Feb  1 22:14:53 2004
@@ -44,11 +44,6 @@
 		
 extern struct JNINativeInterface Kaffe_JNINativeInterface;
 
-/* 
- * store the native thread for the main thread here 
- * between init and createFirst 
- */
-static jthread_t	mainthread;
 static int threadStackSize;	/* native stack size */
 
 /* referenced by native/Runtime.c */
@@ -61,7 +56,6 @@
 Hjava_lang_ThreadGroup* standardGroup;
 
 static void firstStartThread(void*);
-static void createInitialThread(const char*);
 static void runfinalizer(void);
 
 static iStaticLock	thread_start_lock;
@@ -90,6 +84,34 @@
 	return gc_realloc(p, s, GC_ALLOC_THREADCTX);
 }
 
+static void
+linkNativeAndJavaThread(jthread_t thread, Hjava_lang_Thread *jlThread)
+{
+	threadData *thread_data = jthread_get_data(thread);
+
+	thread_data->jlThread = jlThread;
+	unhand (jlThread)->PrivateInfo = (struct Hkaffe_util_Ptr *)thread;
+
+	thread_data->jniEnv = &Kaffe_JNINativeInterface;
+
+	thread_data->needOnStack = STACK_HIGH; 
+}
+
+static void
+unlinkNativeAndJavaThread(jthread_t thread)
+{
+	threadData *thread_data = jthread_get_data(thread);
+
+	/*
+	unhand((Hjava_lang_Thread *)thread_data->jlThread)->PrivateInfo = 0;
+	*/
+
+	thread_data->jlThread = 0;
+	thread_data->jniEnv = 0;
+
+	ksemDestroy (&thread_data->sem);
+}
+
 /*
  * Initialise threads.
  */
@@ -123,51 +145,30 @@
 
 
 	/* Allocate a thread to be the main thread */
-	createInitialThread("main");
+	attachFakedThreadInstance("main");
 
 	DBG(INIT, dprintf("initThreads() done\n"); )
 }
 
 
-static int
+static jthread_t
 createThread(Hjava_lang_Thread* tid, void* func, size_t stacksize,
 	     struct _errorInfo *einfo)
 {
-	struct Hkaffe_util_Ptr* nativethread;
+	jthread_t nativeThread;
 
-	nativethread = (struct Hkaffe_util_Ptr*)jthread_create(
-		unhand(tid)->priority,
-		func,
-		unhand(tid)->daemon,
-		tid,
-		stacksize);
+	nativeThread = jthread_create(unhand(tid)->priority,
+			       func,
+			       unhand(tid)->daemon,
+			       tid,
+			       stacksize);
 
-	if (!nativethread) {
+	if (nativeThread == NULL) {
 		postOutOfMemory(einfo);
 		return 0;
 	}
 
-	jthread_get_data((jthread_t)nativethread)->jniEnv = &Kaffe_JNINativeInterface;
-	unhand(tid)->PrivateInfo = nativethread;
-	/* preallocate a stack overflow error for this thread in case it 
-	 * runs out 
-	 */
-	unhand(tid)->stackOverflowError = 
-		(Hjava_lang_Throwable*)StackOverflowError;
-	unhand(tid)->needOnStack = STACK_HIGH;
-	return 1;
-}
-
-static
-void
-initThreadLock(Hjava_lang_Thread* tid)
-{
-	Ksem *sem;
-	sem = thread_malloc(sizeof(Ksem));
-	assert(sem != NULL);
-	ksemInit(sem);
-
-	unhand(tid)->sem = (struct Hkaffe_util_Ptr*)sem;
+	return nativeThread;
 }
 
 /*
@@ -176,12 +177,10 @@
 void
 startThread(Hjava_lang_Thread* tid)
 {
-	int success;
+	jthread_t nativeTid;
 	struct _errorInfo info;
 	int iLockRoot;
 
-	initThreadLock(tid);
-	
 #if 0
 	if (aliveThread(tid) == true) {
 		throwException(IllegalThreadStateException);
@@ -195,11 +194,14 @@
 	 */
 	lockStaticMutex(&thread_start_lock);
 
-	success = createThread(tid, &firstStartThread,
-			       threadStackSize, &info);
+	nativeTid = createThread(tid, &firstStartThread,
+				 threadStackSize, &info);
 
+	linkNativeAndJavaThread (nativeTid, tid);
+	
 	unlockStaticMutex(&thread_start_lock);
-	if (!success) {
+
+	if (nativeTid == NULL) {
 		throwError(&info);
 	}
 }
@@ -239,39 +241,29 @@
  * Create the initial thread with a given name.
  *  We should only ever call this once.
  */
-static
 void
-createInitialThread(const char* nm)
+attachFakedThreadInstance(const char* nm)
 {
 	Hjava_lang_Thread* tid;
 
-	DBG(INIT, dprintf("createInitialThread(%s)\n", nm); )
+	DBG(VMTHREAD, dprintf("attachFakedThreadInstance(%s)\n", nm); )
 
 	/* Allocate a thread to be the main thread */
 	tid = (Hjava_lang_Thread*)newObject(ThreadClass);
 	assert(tid != 0);
 
-	unhand(tid)->name = stringC2CharArray(nm);
+	unhand(tid)->name = stringC2Java(nm);
 	assert(unhand(tid)->name != NULL);
 	unhand(tid)->priority = java_lang_Thread_NORM_PRIORITY;
-	unhand(tid)->threadQ = 0;
 	unhand(tid)->daemon = 0;
 	unhand(tid)->interrupting = 0;
 	unhand(tid)->target = 0;
 	unhand(tid)->group = standardGroup;
 	unhand(tid)->started = 1;
 
-	initThreadLock(tid);
-
-	jthread_atexit(runfinalizer);
 	/* set Java thread associated with main thread */
-	mainthread = jthread_createfirst(MAINSTACKSIZE, java_lang_Thread_NORM_PRIORITY, tid);
-	jthread_get_data(mainthread)->jniEnv = &Kaffe_JNINativeInterface;
-	unhand(tid)->PrivateInfo = (struct Hkaffe_util_Ptr*)mainthread;
-	unhand(tid)->stackOverflowError = 
-		(Hjava_lang_Throwable*)StackOverflowError;
-	unhand(tid)->needOnStack = STACK_HIGH;
-        
+	linkNativeAndJavaThread (jthread_current(), tid);
+
         /*
 	 * set context class loader of primordial thread to app classloader
 	 * must not be done earlier, since getCurrentThread() won't work
@@ -285,7 +277,7 @@
 	/* Attach thread to threadGroup */
 	do_execute_java_method(unhand(tid)->group, "add", "(Ljava/lang/Thread;)V", 0, 0, tid);
 
-	DBG(INIT, dprintf("createInitialThread(%s) done\n", nm); )
+	DBG(VMTHREAD, dprintf("attachFakedThreadInstance(%s)=%p done\n", nm, tid); )
 }
 
 /*
@@ -293,17 +285,23 @@
  */
 static
 void
-startSpecialThread(void* arg)
+startSpecialThread(void *arg)
 {
-	Hjava_lang_Thread* tid;
 	void (*func)(void *);
 	void *argument;
+	int iLockRoot;
+
+	ksemInit(&THREAD_DATA()->sem);
+
+	lockStaticMutex(&thread_start_lock);
+	unlockStaticMutex(&thread_start_lock);
+
+	func = (void *)THREAD_DATA()->exceptPtr;
+	THREAD_DATA()->exceptPtr = NULL;
+
+	argument = (void *)THREAD_DATA()->exceptObj;
+	THREAD_DATA()->exceptObj = NULL;
 
-	tid  = getCurrentThread();
-	func = (void*)tid->sFunc;
-	argument = (void*)tid->sArg;
-	tid->target = 0;
-	tid->group = 0;
 	func(argument);
 }
 
@@ -321,6 +319,8 @@
 	     size_t stacksize, struct _errorInfo *einfo)
 {
 	Hjava_lang_Thread* tid;

*** Patch too long, truncated ***