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/JDWP] suspend counting for JDWP


Hi,

Now that the last bits of missing JVMTI functionality are in, I can submit this patch, which implements the JDWP methods VMVirtualMachine.suspendThread, VMVirtualMachine.resumeThread and VMVirtualMachine.getSuspendCount using JVMTI.

Keith

ChangeLog
2006-09-21  Keith Seitz  <keiths@redhat.com>

        * gnu/classpath/jdwp/natVMVirtualMachine.cc
        (_jdwp_suspend_counts): New variable.
        (initialize): Initialize _jdwp_suspend_counts.
        (suspendThread): Implement.
        (resumeThread): Implement.
        (getSuspendCount): Implement.
Index: gnu/classpath/jdwp/natVMVirtualMachine.cc
===================================================================
--- gnu/classpath/jdwp/natVMVirtualMachine.cc	(revision 117093)
+++ gnu/classpath/jdwp/natVMVirtualMachine.cc	(working copy)
@@ -15,27 +15,36 @@
 
 #include <java/lang/Class.h>
 #include <java/lang/ClassLoader.h>
+#include <java/lang/Integer.h>
+#include <java/lang/String.h>
+#include <java/lang/StringBuffer.h>
 #include <java/lang/Thread.h>
 #include <java/nio/ByteBuffer.h>
 #include <java/util/ArrayList.h>
+#include <java/util/Hashtable.h>
 #include <java/util/Iterator.h>
 
 #include <gnu/classpath/jdwp/VMFrame.h>
 #include <gnu/classpath/jdwp/VMMethod.h>
 #include <gnu/classpath/jdwp/VMVirtualMachine.h>
 #include <gnu/classpath/jdwp/event/EventRequest.h>
+#include <gnu/classpath/jdwp/exception/JdwpInternalErrorException.h>
 #include <gnu/classpath/jdwp/util/MethodResult.h>
 
 using namespace java::lang;
 using namespace gnu::classpath::jdwp::event;
 using namespace gnu::classpath::jdwp::util;
 
+// Thread suspension table. Maps Thread to suspend count
+static ::java::util::Hashtable *_jdwp_suspend_counts;
+
 // JVMTI environment
 static jvmtiEnv *_jdwp_jvmtiEnv;
 
 void
 gnu::classpath::jdwp::VMVirtualMachine::initialize ()
 {
+  _jdwp_suspend_counts = new ::java::util::Hashtable ();
   JavaVM *vm = _Jv_GetJavaVM ();
   vm->GetEnv (reinterpret_cast<void **> (&_jdwp_jvmtiEnv), JVMTI_VERSION_1_0);
 }
@@ -43,17 +52,80 @@
 void
 gnu::classpath::jdwp::VMVirtualMachine ::suspendThread (Thread *thread)
 {
+  _Jv_MonitorEnter (_jdwp_suspend_counts);
+  Integer *count
+    = reinterpret_cast<Integer *> (_jdwp_suspend_counts->get (thread));
+  if (count == NULL)
+    {
+      // New -- suspend thread
+      count = new Integer (1);
+      _jdwp_suspend_counts->put (thread, count);
+      _Jv_MonitorExit (_jdwp_suspend_counts);
+      jvmtiError err = _jdwp_jvmtiEnv->SuspendThread (thread);
+      if (err != JVMTI_ERROR_NONE)
+	{
+	  using namespace gnu::classpath::jdwp::exception;
+	  char *reason;
+	  _jdwp_jvmtiEnv->GetErrorName (err, &reason);
+	  ::java::lang::String *txt
+	      = JvNewStringLatin1 ("could not suspend thread: ");
+	  ::java::lang::StringBuffer *msg
+	      = new ::java::lang::StringBuffer (txt);
+	  msg->append (JvNewStringUTF (reason));
+	  _jdwp_jvmtiEnv->Deallocate ((unsigned char *) (reason));
+	  throw new JdwpInternalErrorException (msg->toString ());
+	}
+
+      return;
+    }
+
+  // Increment suspend count
+  jint value = count->intValue ();
+  count = new Integer (++value);
+  _jdwp_suspend_counts->put (thread, count);
+  _Jv_MonitorExit (_jdwp_suspend_counts);
 }
 
 void
 gnu::classpath::jdwp::VMVirtualMachine::resumeThread (Thread *thread)
 {
+  _Jv_MonitorEnter (_jdwp_suspend_counts);
+  Integer *count
+    = reinterpret_cast<Integer *> (_jdwp_suspend_counts->get (thread));
+  if (count == NULL)
+    {
+      // thread not suspended: ThreadReference.Resume says to ignore it.
+    }
+  else
+    {
+      // Decrement suspend count
+      jint value = count->intValue ();
+      if (--value == 0)
+	{
+	  // Resume thread and remove entry
+	  _jdwp_suspend_counts->remove (thread);
+	  _Jv_MonitorExit (_jdwp_suspend_counts);
+	  _jdwp_jvmtiEnv->ResumeThread (thread);
+	  return;
+	}
+
+      // Record new suspned count
+      count = new Integer (value);
+      _jdwp_suspend_counts->put (thread, count);
+    }
+
+  _Jv_MonitorExit (_jdwp_suspend_counts);
 }
 
 jint
 gnu::classpath::jdwp::VMVirtualMachine::getSuspendCount (Thread *thread)
 {
-  return 0;
+  jint suspensions = 0;
+  Integer *count
+    = reinterpret_cast<Integer *> (_jdwp_suspend_counts->get (thread));
+  if (count != NULL)
+    suspensions = count->intValue ();
+  return suspensions;
 }
 
 void

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