This is the mail archive of the java-patches@gcc.gnu.org mailing list for the Java project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [RFC] Implementing JVMTI's GetThreadState


>>>>> "Keith" == Keith Seitz <keiths@redhat.com> writes:

I'm sorry I let this go so long.

Keith> Right now, I have been playing with an implementation which does
Keith> everything except figure out WHY a thread is waiting. My question of
Keith> course: Does anyone see anything more elegant than adding a bunch of
Keith> booleans in LockSupport.park, Object.wait, and Thread.sleep in order
Keith> to divine said information?

We need something similar to implement Thread.getState.  I was working
on a patch for this once, I've appended what I had.  I doubt it works
or compiles.

Keith> 	  else if (false /*in Object.wait HOW TO DO THIS?*/)
Keith> 	    state |= JVMTI_THREAD_STATE_IN_OBJECT_WAIT;

Isn't this Thread.State.WAITING?

Anyway we can have more states internally than are exposed by
Thread.State.  The patch below directly uses the State enum, but it
could just as well use JVMTI values and then do translation in
getState.

What do you think of this?

Note that this patch doesn't address all the places we might block on
I/O.  What a pain that will be.

Tom

Index: ChangeLog
from  Tom Tromey  <tromey@redhat.com>

	* include/posix-threads.h (_Jv_MutexLock): Set thread's state.
	* posix-threads.cc (_Jv_CondWait): Set thread's state.
	* include/jvm.h (class JvSetThreadState): New class.
	* java/lang/Thread.java (state): New field.
	(getState): Wrote.
	* java/lang/natThread.cc (_Jv_ThreadRun): Use
	getUncaughtExceptionHandler.
	(start): Set state.
	(_Jv_AttachCurrentThread): Likewise.
	(finish_): Likewise.
	(getState): Removed.

Index: include/posix-threads.h
===================================================================
--- include/posix-threads.h	(revision 115453)
+++ include/posix-threads.h	(working copy)
@@ -1,7 +1,7 @@
 // -*- c++ -*-
 // posix-threads.h - Defines for using POSIX threads.
 
-/* Copyright (C) 1998, 1999, 2001, 2003  Free Software Foundation
+/* Copyright (C) 1998, 1999, 2001, 2003, 2006  Free Software Foundation
 
    This file is part of libgcj.
 
@@ -123,31 +123,7 @@
   mu->owner = 0;
 }
 
-inline int
-_Jv_MutexLock (_Jv_Mutex_t *mu)
-{
-  pthread_t self = pthread_self ();
-  if (mu->owner == self)
-    {
-      mu->count++;
-    }
-  else
-    {
-#     ifdef LOCK_DEBUG
-	int result = pthread_mutex_lock (&mu->mutex);
-	if (0 != result)
-	  {
-	    fprintf(stderr, "Pthread_mutex_lock returned %d\n", result);
-	    for (;;) {}
-	  }
-#     else
-        pthread_mutex_lock (&mu->mutex);
-#     endif
-      mu->count = 1;
-      mu->owner = self;
-    }
-  return 0;
-}
+extern int _Jv_MutexLock (_Jv_Mutex_t *);
 
 inline int
 _Jv_MutexUnlock (_Jv_Mutex_t *mu)
Index: include/jvm.h
===================================================================
--- include/jvm.h	(revision 116131)
+++ include/jvm.h	(working copy)
@@ -30,6 +30,9 @@
 #include <gcj/cni.h>
 #include <gcj/field.h>
 
+#include <java/lang/Thread.h>
+#include <java/lang/Thread$State.h>
+
 /* Macro for possible unused arguments.  */
 #define MAYBE_UNUSED __attribute__((__unused__))
 
@@ -673,4 +676,27 @@
 // A helper function defined in prims.cc.
 char* _Jv_PrependVersionedLibdir (char* libpath);
 
+// Temporarily set the thread's state.
+class JvSetThreadState
+{
+private:
+  ::java::lang::Thread *thread;
+  ::java::lang::Thread$State *saved;
+
+public:
+
+  JvSetThreadState(::java::lang::Thread *cthread,
+		   ::java::lang::Thread$State *nstate)
+    : thread (cthread),
+      saved (cthread->state)
+  {
+    thread->state = nstate;
+  }
+
+  ~JvSetThreadState()
+  {
+    thread->state = saved;
+  }
+};
+
 #endif /* __JAVA_JVM_H__ */
Index: posix-threads.cc
===================================================================
--- posix-threads.cc	(revision 115453)
+++ posix-threads.cc	(working copy)
@@ -1,6 +1,6 @@
 // posix-threads.cc - interface between libjava and POSIX threads.
 
-/* Copyright (C) 1998, 1999, 2000, 2001, 2004  Free Software Foundation
+/* Copyright (C) 1998, 1999, 2000, 2001, 2004, 2006  Free Software Foundation
 
    This file is part of libgcj.
 
@@ -78,6 +78,35 @@
 
 
 
+int
+_Jv_MutexLock (_Jv_Mutex_t *mu)
+{
+  pthread_t self = pthread_self ();
+  if (mu->owner == self)
+    {
+      mu->count++;
+    }
+  else
+    {
+      JvSetThreadState holder (_Jv_ThreadCurrent(),
+			       ::java::lang::Thread$State::BLOCKED);
+	
+#     ifdef LOCK_DEBUG
+	int result = pthread_mutex_lock (&mu->mutex);
+	if (0 != result)
+	  {
+	    fprintf(stderr, "Pthread_mutex_lock returned %d\n", result);
+	    for (;;) {}
+	  }
+#     else
+        pthread_mutex_lock (&mu->mutex);
+#     endif
+      mu->count = 1;
+      mu->owner = self;
+    }
+  return 0;
+}
+
 // Wait for the condition variable "CV" to be notified. 
 // Return values:
 // 0: the condition was notified, or the timeout expired.
@@ -93,6 +122,7 @@
 
   struct timespec ts;
 
+  ::java::lang::Thread$State *new_state = ::java::lang::Thread$State::WAITING;
   if (millis > 0 || nanos > 0)
     {
       // Calculate the abstime corresponding to the timeout.
@@ -118,6 +148,7 @@
         {
           m %= 1000;
           ts.tv_nsec = m * 1000000 + (unsigned long long)nanos;
+	  new_state = ::java::lang::Thread$State::TIMED_WAITING;
         }
     }
 
@@ -134,6 +165,9 @@
       return _JV_INTERRUPTED;
     }
 
+  // Set the thread's state.
+  JvSetThreadState holder (current_obj, new_state);
+
   // Add this thread to the cv's wait set.
   current->next = NULL;
 
Index: java/lang/Thread.java
===================================================================
--- java/lang/Thread.java	(revision 116132)
+++ java/lang/Thread.java	(working copy)
@@ -153,6 +153,9 @@
   // This describes the top-most interpreter frame for this thread.
   RawData interp_frame;
 
+  // Current state.
+  volatile State state = State.NEW;
+
   // Our native data - points to an instance of struct natThread.
   private RawDataManaged data;
 
@@ -997,6 +1000,7 @@
    */
   public UncaughtExceptionHandler getUncaughtExceptionHandler()
   {
+    // FIXME: if thread is dead, should return null...
     return exceptionHandler != null ? exceptionHandler : group;
   }
 
@@ -1147,7 +1151,10 @@
    *
    * @return the current thread state.
    */
-  public native State getState();
+  public State getState()
+  {
+    return state;
+  }
 
   /**
    * <p>
Index: java/lang/natThread.cc
===================================================================
--- java/lang/natThread.cc	(revision 116132)
+++ java/lang/natThread.cc	(working copy)
@@ -18,6 +18,7 @@
 
 #include <gnu/gcj/RawDataManaged.h>
 #include <java/lang/Thread.h>
+#include <java/lang/Thread$UncaughtExceptionHandler.h>
 #include <java/lang/ThreadGroup.h>
 #include <java/lang/IllegalArgumentException.h>
 #include <java/lang/IllegalThreadStateException.h>
@@ -227,6 +228,7 @@
   {
     JvSynchronize sync (this);
     alive_flag = false;
+    state = Thread$State::TERMINATED;
   }
 
   _Jv_CondNotifyAll (&nt->join_cond, &nt->join_mutex);
@@ -307,7 +309,7 @@
       // this results in an uncaught exception, that is ignored.
       try
 	{
-	  thread->group->uncaughtException (thread, t);
+	  thread->getUncaughtExceptionHandler()->uncaughtException (thread, t);
 	}
       catch (java::lang::Throwable *f)
 	{
@@ -329,6 +331,7 @@
 
   alive_flag = true;
   startable_flag = false;
+  state = Thread$State::RUNNABLE;
   natThread *nt = (natThread *) data;
   _Jv_ThreadStart (this, nt->thread, (_Jv_ThreadStartFunc *) &_Jv_ThreadRun);
 }
@@ -385,13 +388,6 @@
   _Jv_ThreadYield ();
 }
 
-::java::lang::Thread$State *
-java::lang::Thread::getState()
-{
-  // FIXME
-  return NULL;
-}
-
 JNIEnv *
 _Jv_GetCurrentJNIEnv ()
 {
@@ -419,6 +415,7 @@
     return -1;
   thread->startable_flag = false;
   thread->alive_flag = true;
+  thread->state = ::java::lang::Thread$State::RUNNABLE;
   natThread *nt = (natThread *) thread->data;
   _Jv_ThreadRegister (nt->thread);
   return 0;


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]