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]

[RFA] Mostly implement JVMTI's GetThreadState


Hi,

I posted last week about what a pain it is turning out to implement this function fully. I hate to do this, but I'm going to have to ask maintainers to consider a patch which does not fully implement this function. This is a real blocker for continued JDWP testing with Eclipse.

Keith

boehm-gc/ChangeLog:
2007-04-18  Keith Seitz  <keiths@redhat.com>

        * include/gc.h (GC_is_thread_suspended): Declare.
        * pthread_stop_world.c (GC_is_thread_suspended): New function.

ChangeLog:
2007-04-18  Keith Seitz  <keiths@redhat.com>

        * include/no-gc.h (_Jv_IsThreadSuspended): Declare.
        * include/boehm-gc.h (_Jv_IsThreadSuspended): Likewise.
        * boehm.cc (_Jv_IsThreadSuspended): New function.
        * nogc.cc (_Jv_IsThreadSuspended): Likewise.
        * jvmti.cc (_Jv_JVMTI_GetThreadState): New function.
        (_Jv_JVMTI_Interface): Define GetThreadState.
Index: boehm-gc/include/gc.h
===================================================================
--- boehm-gc/include/gc.h	(revision 123923)
+++ boehm-gc/include/gc.h	(working copy)
@@ -1085,5 +1085,6 @@
   && !defined(GC_WIN32_THREADS) && !defined(GC_DARWIN_THREADS)
 GC_API void GC_suspend_thread GC_PROTO((pthread_t));
 GC_API void GC_resume_thread GC_PROTO((pthread_t));
+GC_API int GC_is_thread_suspended GC_PROTO((pthread_t));
 #endif
 #endif /* _GC_H */
Index: boehm-gc/pthread_stop_world.c
===================================================================
--- boehm-gc/pthread_stop_world.c	(revision 123923)
+++ boehm-gc/pthread_stop_world.c	(working copy)
@@ -483,6 +483,14 @@
   t -> flags &= ~SUSPENDED;
 }
 
+int GC_is_thread_suspended(pthread_t thread) {
+  GC_thread t = GC_lookup_thread(thread);
+  if (t == NULL)
+    ABORT("querying suspension state of unknown thread");
+
+  return (t -> flags & SUSPENDED);
+}
+
 /* Caller holds allocation lock, and has held it continuously since	*/
 /* the world stopped.							*/
 void GC_start_world()
Index: include/no-gc.h
===================================================================
--- include/no-gc.h	(revision 123960)
+++ include/no-gc.h	(working copy)
@@ -1,7 +1,7 @@
 // -*- c++ -*-
 // no-gc.h - Defines for no garbage collector.
 
-/* Copyright (C) 1998, 1999, 2006  Free Software Foundation
+/* Copyright (C) 1998, 1999, 2006, 2007  Free Software Foundation
 
    This file is part of libgcj.
 
@@ -18,4 +18,6 @@
 // Resume a suspended thread.
 extern "C" void _Jv_ResumeThread (_Jv_Thread_t *);
 
+// Is the given thread suspended?
+extern "C" int _Jv_IsThreadSuspended (_Jv_Thread_t *);
 #endif /* __JV_NO_GC__ */
Index: include/boehm-gc.h
===================================================================
--- include/boehm-gc.h	(revision 123960)
+++ include/boehm-gc.h	(working copy)
@@ -1,7 +1,7 @@
 // -*- c++ -*-
 // boehm-gc.h - Defines for Boehm collector.
 
-/* Copyright (C) 1998, 1999, 2002, 2004, 2006  Free Software Foundation
+/* Copyright (C) 1998, 1999, 2002, 2004, 2006, 2007  Free Software Foundation
 
    This file is part of libgcj.
 
@@ -93,4 +93,6 @@
 // Resume a suspended thread.
 extern "C" void _Jv_ResumeThread (_Jv_Thread_t *);
 
+// Is the given thread suspended?
+extern "C" int _Jv_IsThreadSuspended (_Jv_Thread_t *);
 #endif /* __JV_BOEHM_GC__ */
Index: boehm.cc
===================================================================
--- boehm.cc	(revision 123960)
+++ boehm.cc	(working copy)
@@ -722,6 +722,17 @@
 #endif
 }
 
+int
+_Jv_IsThreadSuspended (_Jv_Thread_t *thread)
+{
+#if defined(GC_PTHREADS) && !defined(GC_SOLARIS_THREADS) \
+     && !defined(GC_WIN32_THREADS) && !defined(GC_DARWIN_THREADS)
+  return GC_is_thread_suspended (_Jv_GetPlatformThreadID (thread));
+#else
+  return 0;
+#endif
+}
+
 void
 _Jv_GCAttachThread ()
 {
Index: nogc.cc
===================================================================
--- nogc.cc	(revision 123960)
+++ nogc.cc	(working copy)
@@ -184,3 +184,9 @@
 _Jv_ResumeThread (_Jv_Thread_t *thread)
 {
 }
+
+int
+_Jv_IsThreadSuspended (_Jv_Thread_t *thread)
+{
+  return 0;
+}
Index: jvmti.cc
===================================================================
--- jvmti.cc	(revision 123960)
+++ jvmti.cc	(working copy)
@@ -30,6 +30,7 @@
 #include <java/lang/OutOfMemoryError.h>
 #include <java/lang/Thread.h>
 #include <java/lang/ThreadGroup.h>
+#include <java/lang/Thread$State.h>
 #include <java/lang/Throwable.h>
 #include <java/lang/VMClassLoader.h>
 #include <java/lang/reflect/Field.h>
@@ -521,6 +522,66 @@
 }
 
 static jvmtiError JNICALL
+_Jv_JVMTI_GetThreadState (MAYBE_UNUSED jvmtiEnv *env, jthread thread,
+			  jint *thread_state_ptr)
+{
+  REQUIRE_PHASE (env, JVMTI_PHASE_LIVE);
+
+  THREAD_DEFAULT_TO_CURRENT (thread);
+  THREAD_CHECK_VALID (thread);
+  NULL_CHECK (thread_state_ptr);
+
+  jint state = 0;
+  if (thread->isAlive ())
+    {
+      state |= JVMTI_THREAD_STATE_ALIVE;
+
+      _Jv_Thread_t *data = _Jv_ThreadGetData (thread);
+      if (_Jv_IsThreadSuspended (data))
+	state |= JVMTI_THREAD_STATE_SUSPENDED;
+
+      if (thread->isInterrupted ())
+	state |= JVMTI_THREAD_STATE_INTERRUPTED;
+
+      _Jv_Frame *frame = reinterpret_cast<_Jv_Frame *> (thread->frame);
+      if (frame != NULL && frame->frame_type == frame_native)
+	state |= JVMTI_THREAD_STATE_IN_NATIVE;
+
+      using namespace java::lang;
+      Thread$State *ts = thread->getState ();
+      if (ts == Thread$State::RUNNABLE)
+	state |= JVMTI_THREAD_STATE_RUNNABLE;
+      else if (ts == Thread$State::BLOCKED)
+	state |= JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER;
+      else if (ts == Thread$State::TIMED_WAITING
+	       || ts == Thread$State::WAITING)
+	{
+	  state |= JVMTI_THREAD_STATE_WAITING;
+	  state |= ((ts == Thread$State::WAITING)
+		    ? JVMTI_THREAD_STATE_WAITING_INDEFINITELY
+		    : JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT);
+
+	  /* FIXME: We don't have a way to tell
+	     the caller why the thread is suspended,
+	     i.e., JVMTI_THREAD_STATE_SLEEPING,
+	     JVMTI_THREAD_STATE_PARKED, and
+	     JVMTI_THREAD_STATE_IN_OBJECT_WAIT
+	     are never set. */
+	}
+    }
+  else
+    {
+      using namespace java::lang;
+      Thread$State *ts = thread->getState ();
+      if (ts == Thread$State::TERMINATED)
+	state |= JVMTI_THREAD_STATE_TERMINATED;
+    }
+
+  *thread_state_ptr = state;
+  return JVMTI_ERROR_NONE;
+}
+
+static jvmtiError JNICALL
 _Jv_JVMTI_CreateRawMonitor (MAYBE_UNUSED jvmtiEnv *env, const char *name,
 			    jrawMonitorID *result)
 {
@@ -2004,7 +2065,7 @@
   UNIMPLEMENTED,		// GetThreadGroupInfo
   UNIMPLEMENTED,		// GetThreadGroupChildren
   _Jv_JVMTI_GetFrameCount,		// GetFrameCount
-  UNIMPLEMENTED,		// GetThreadState
+  _Jv_JVMTI_GetThreadState,	// GetThreadState
   RESERVED,			// reserved18
   UNIMPLEMENTED,		// GetFrameLocation
   UNIMPLEMENTED,		// NotifyPopFrame

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