[kaffe] CVS kaffe (guilhem): Lock speedup + DestroyJavaVM fix.

Kaffe CVS cvs-commits at kaffe.org
Sat Mar 12 13:26:49 PST 2005


PatchSet 5528 
Date: 2005/03/12 21:22:38
Author: guilhem
Branch: HEAD
Tag: (none) 
Log:
Lock speedup + DestroyJavaVM fix.

	* kaffe/kaffevm/locks.c
	(getHeavyLock): Changed order of heavy locking.
	(putHeavyLock): Only call KSEM(put) if it is useful.

	* kaffe/kaffevm/systems/unix-pthreads/thread-impl.c
	(jthread_exit): If it is called from the main thread it will wait
	for all other non-daemon threads to exit before returning.

	* kaffe/kaffevm/jni/jni-base.c
	(KaffeJNI_DestroyJavaVM): New function.
	(JNI_CreateJavaVM): Remember the thread which has built the VM object.
	(startingThread): New variable.

	* kaffe/kaffevm/jni/jni_funcs.h
	(KaffeJNI_DestroyJavaVM): New function.

	* kaffe/kaffevm/jni/jni.c
	(Kaffe_DestroyJavaVM): Removed.

Members: 
	ChangeLog:1.3702->1.3703 
	kaffe/kaffevm/locks.c:1.57->1.58 
	kaffe/kaffevm/jni/jni-base.c:1.14->1.15 
	kaffe/kaffevm/jni/jni.c:1.18->1.19 
	kaffe/kaffevm/jni/jni_funcs.h:1.5->1.6 
	kaffe/kaffevm/systems/unix-pthreads/thread-impl.c:1.73->1.74 

Index: kaffe/ChangeLog
diff -u kaffe/ChangeLog:1.3702 kaffe/ChangeLog:1.3703
--- kaffe/ChangeLog:1.3702	Sat Mar 12 19:25:49 2005
+++ kaffe/ChangeLog	Sat Mar 12 21:22:38 2005
@@ -1,5 +1,26 @@
 2005-03-12  Guilhem Lavaux  <guilhem at kaffe.org>
 
+	* kaffe/kaffevm/locks.c
+	(getHeavyLock): Changed order of heavy locking.
+	(putHeavyLock): Only call KSEM(put) if it is useful.
+
+	* kaffe/kaffevm/systems/unix-pthreads/thread-impl.c
+	(jthread_exit): If it is called from the main thread it will wait
+	for all other non-daemon threads to exit before returning.
+
+	* kaffe/kaffevm/jni/jni-base.c
+	(KaffeJNI_DestroyJavaVM): New function.
+	(JNI_CreateJavaVM): Remember the thread which has built the VM object.
+	(startingThread): New variable.
+
+	* kaffe/kaffevm/jni/jni_funcs.h
+	(KaffeJNI_DestroyJavaVM): New function.
+
+	* kaffe/kaffevm/jni/jni.c
+	(Kaffe_DestroyJavaVM): Removed.
+	
+2005-03-12  Guilhem Lavaux  <guilhem at kaffe.org>
+
 	* kaffe/kaffevm/systems/unix-jthreads/config-jthreads.h: Define
 	SIGALTSTACK_NEEDS_END if the system is IRIX.
 
Index: kaffe/kaffe/kaffevm/locks.c
diff -u kaffe/kaffe/kaffevm/locks.c:1.57 kaffe/kaffe/kaffevm/locks.c:1.58
--- kaffe/kaffe/kaffevm/locks.c:1.57	Fri Mar 11 16:41:52 2005
+++ kaffe/kaffe/kaffevm/locks.c	Sat Mar 12 21:22:40 2005
@@ -156,13 +156,14 @@
   /* The lock is allocated and ready to use. */
   for (;;) {
     /* Try to acquire the lock. */
+    lk->num_wait++;
     if (!COMPARE_AND_EXCHANGE(&(lk->in_progress), 0, 1))
       {
-	lk->num_wait++;
 	KSEM(get)(&lk->sem, (jlong)0);
-	lk->num_wait--;
+        lk->num_wait--;
 	continue;
       }
+    lk->num_wait--;
     lk->lkp = lkp;
     return lk;
   }
@@ -205,7 +206,8 @@
   
   lk->in_progress = 0;
   lk->lkp = NULL;
-  KSEM(put)(&(lk->sem));
+  if (lk->num_wait != 0)
+    KSEM(put)(&(lk->sem));
 }
 
 /*
@@ -223,6 +225,7 @@
     dprintf("slowLockMutex(lk=%p, th=%p)\n",
 	    *lkp, KTHREAD(current)());
     );
+
  KTHREAD(disable_stop)(); /* protect the heavy lock, and its queues */
 
  tdata = KTHREAD(get_data)(cur);
Index: kaffe/kaffe/kaffevm/jni/jni-base.c
diff -u kaffe/kaffe/kaffevm/jni/jni-base.c:1.14 kaffe/kaffe/kaffevm/jni/jni-base.c:1.15
--- kaffe/kaffe/kaffevm/jni/jni-base.c:1.14	Sun Feb  6 14:57:50 2005
+++ kaffe/kaffe/kaffevm/jni/jni-base.c	Sat Mar 12 21:22:40 2005
@@ -32,6 +32,7 @@
  * we only support one at a time.
  */
 static int Kaffe_NumVM = 0;
+static jthread_t startingThread;
 
 extern struct JNINativeInterface Kaffe_JNINativeInterface;
 extern KaffeVM_Arguments Kaffe_JavaVMInitArgs;
@@ -303,6 +304,7 @@
   /* Return the VM and JNI we're using */
   *vm = &Kaffe_JavaVM;
   *env = THREAD_JNIENV();
+  startingThread = KTHREAD(current)();
   Kaffe_NumVM++;
 
 #if defined(ENABLE_JVMPI)
@@ -314,7 +316,20 @@
       jvmpiPostEvent(&ev);
     }
 #endif
-	
+
+  return 0;
+}
+
+jint
+KaffeJNI_DestroyJavaVM(JavaVM* vm UNUSED)
+{
+  /* The destroy function must be called by the same thread that has
+   * built the VM object
+   */
+  if (KTHREAD(current)() != startingThread)
+    return -1;
+
+  exitThread();
   return 0;
 }
 
Index: kaffe/kaffe/kaffevm/jni/jni.c
diff -u kaffe/kaffe/kaffevm/jni/jni.c:1.18 kaffe/kaffe/kaffevm/jni/jni.c:1.19
--- kaffe/kaffe/kaffevm/jni/jni.c:1.18	Sat Feb  5 17:12:07 2005
+++ kaffe/kaffe/kaffevm/jni/jni.c	Sat Mar 12 21:22:40 2005
@@ -736,14 +736,6 @@
 }
 
 static jint
-Kaffe_DestroyJavaVM(JavaVM* vm UNUSED)
-{
-	/* Right now, calling this from main2 is what prevents us from 
-	   exiting there */
-	exitThread();
-}
-
-static jint
 Kaffe_AttachCurrentThread(JavaVM* vm UNUSED, void** penv, void* args UNUSED)
 {
 	if (KTHREAD(attach_current_thread) (false)) {
@@ -1068,7 +1060,7 @@
 	NULL,
 	NULL,
 	NULL,
-	Kaffe_DestroyJavaVM,
+	KaffeJNI_DestroyJavaVM,
 	Kaffe_AttachCurrentThread,
 	Kaffe_DetachCurrentThread,
 	Kaffe_GetEnv,
Index: kaffe/kaffe/kaffevm/jni/jni_funcs.h
diff -u kaffe/kaffe/kaffevm/jni/jni_funcs.h:1.5 kaffe/kaffe/kaffevm/jni/jni_funcs.h:1.6
--- kaffe/kaffe/kaffevm/jni/jni_funcs.h:1.5	Tue Dec 21 08:06:38 2004
+++ kaffe/kaffe/kaffevm/jni/jni_funcs.h	Sat Mar 12 21:22:40 2005
@@ -12,6 +12,10 @@
 #ifndef KAFFE_JNI_FUNCTIONS_H
 #define KAFFE_JNI_FUNCTIONS_H
 
+/* ====== Invokation API ============================================================= */
+
+jint KaffeJNI_DestroyJavaVM(JavaVM* vm);
+
 /* ====== Helpers =================================================================== */
 
 jmethodID KaffeJNI_FromReflectedMethod (JNIEnv *, jobject);
Index: kaffe/kaffe/kaffevm/systems/unix-pthreads/thread-impl.c
diff -u kaffe/kaffe/kaffevm/systems/unix-pthreads/thread-impl.c:1.73 kaffe/kaffe/kaffevm/systems/unix-pthreads/thread-impl.c:1.74
--- kaffe/kaffe/kaffevm/systems/unix-pthreads/thread-impl.c:1.73	Sun Feb 20 00:55:48 2005
+++ kaffe/kaffe/kaffevm/systems/unix-pthreads/thread-impl.c	Sat Mar 12 21:22:41 2005
@@ -1004,9 +1004,10 @@
    */
 }
 
-/*
+/**
  * Function to be called (by threads.c firstStartThread) when the thread leaves
- * the user thread function
+ * the user thread function. If the calling thread is the main thread then it
+ * suspend the thread until all other threads has exited.
  */
 void
 jthread_exit ( void )
@@ -1044,7 +1045,9 @@
 	  }
 
 	  for ( t=activeThreads; t != NULL; t = t->next ){
-		if ( t != cur ) {
+		/* We must not kill the current thread and the main thread
+		 */
+		if ( t != cur && t != firstThread) {
 		  /* Mark the thread as to be killed. */
 		  t->status = THREAD_KILL;
 		  /* Send an interrupt event to the remote thread.
@@ -1066,27 +1069,32 @@
 #endif
 
 	  if ( (cur != firstThread) && (firstThread->active == 0) ) {
-		/* if the firstThread has already been frozen, it's not in the cache list */
-		pthread_cancel( firstThread->tid);
+		/* if the firstThread has already been frozen,
+		 * it's not in the cache list. We must wake it up because
+		 * this thread is the last one alive and it is exiting. */
 		repsem_post (&firstThread->sem);
 	  }
 
-	  unprotectThreadList(cur);
-	  pthread_exit( NULL);
+	  /* This is not the main thread so we may kill it. */
+	  if (cur != firstThread)
+	  {
+	    unprotectThreadList(cur);
+	    pthread_exit( NULL);
 
-	  /* we shouldn't get here, this is a last safeguard */
-	  EXIT(0);
+	    /* we shouldn't get here, this is a last safeguard */
+	    EXIT(0);
+	  }
 	}
 	unprotectThreadList(cur);
   }
 
-  if ( cur == firstThread ) {
-	/*
-	 * We don't cache this one, but we have to remove it from the active list. Note
-	 * that the firstThread always has to be the last entry in the activeThreads list
-	 * (we just add new entries at the head)
-	 */
-	protectThreadList(cur);
+  /*
+   * We don't cache this one, but we have to remove it from the active list. Note
+   * that the firstThread always has to be the last entry in the activeThreads list
+   * (we just add new entries at the head)
+   */
+  protectThreadList(cur);
+  if ( cur == firstThread && nonDaemons != 0) {
 
 	/* if we would be the head, we would have been the last, too (and already exited) */
 	assert( cur != activeThreads);
@@ -1097,22 +1105,15 @@
 
 	unprotectThreadList(cur);
 
-	/*
-	 * Put us into a permanent freeze to avoid shut down of the whole process (it's
-	 * not clear if this is common pthread behavior or just a implementation
-	 * linux-threads "feature")
+	/* Put the main thread in a frozen state waiting for the other
+	 * real threads to terminate. The main thread gets the control back
+	 * after that.
 	 */
 	repsem_wait( &cur->sem);
-
-	/* We put here a safe-guard in case the pthread_cancel has not managed
-	 * to do its job and that repsem_wait awakes.
-	 */
-	pthread_exit(NULL);
   }
-  else {
+  else if (cur != firstThread) {
 	/* flag that we soon will get a new cache entry (would be annoying to
 	 * create a new thread in the meantime) */
-	protectThreadList(cur);
 	pendingExits++;
 	unprotectThreadList(cur);
   }




More information about the kaffe mailing list