This is the mail archive of the
java-patches@gcc.gnu.org
mailing list for the Java project.
[RFA/JDWP] suspend counting for JDWP
- From: Keith Seitz <keiths at redhat dot com>
- To: Java Patch List <java-patches at gcc dot gnu dot org>
- Date: Thu, 21 Sep 2006 11:17:27 -0700
- Subject: [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