This is the mail archive of the
java-patches@gcc.gnu.org
mailing list for the Java project.
[ecj] Patch: FYI: implement Thread.getState
- From: Tom Tromey <tromey at redhat dot com>
- To: Java Patch List <java-patches at gcc dot gnu dot org>
- Date: 16 Aug 2006 09:46:29 -0600
- Subject: [ecj] Patch: FYI: implement Thread.getState
- Reply-to: tromey at redhat dot com
I'm checking this in on the gcj-eclipse branch.
This implements Thread.getState.
Tom
Index: ChangeLog
from Tom Tromey <tromey@redhat.com>
* include/posix-threads.h (_Jv_MutexLock): No longer inline.
* posix-threads.cc (_Jv_CondWait): Set thread's state.
* include/jvm.h (class JvSetThreadState): New class.
(JvThreadState): New enum.
* java/lang/Thread.java (state): New field.
* java/lang/natThread.cc (_Jv_ThreadRun): Use
getUncaughtExceptionHandler.
(start): Set state.
(_Jv_AttachCurrentThread): Likewise.
(finish_): Likewise.
(getState): Wrote.
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 int state;
+
// 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;
}
Index: java/lang/natThread.cc
===================================================================
--- java/lang/natThread.cc (revision 116132)
+++ java/lang/natThread.cc (working copy)
@@ -18,6 +18,8 @@
#include <gnu/gcj/RawDataManaged.h>
#include <java/lang/Thread.h>
+#include <java/lang/Thread$State.h>
+#include <java/lang/Thread$UncaughtExceptionHandler.h>
#include <java/lang/ThreadGroup.h>
#include <java/lang/IllegalArgumentException.h>
#include <java/lang/IllegalThreadStateException.h>
@@ -59,6 +61,8 @@
{
natThread *nt = (natThread *) _Jv_AllocBytes (sizeof (natThread));
+ state = JV_NEW;
+
data = (gnu::gcj::RawDataManaged *) nt;
// Register a finalizer to clean up the native thread resources.
@@ -227,6 +231,7 @@
{
JvSynchronize sync (this);
alive_flag = false;
+ state = JV_TERMINATED;
}
_Jv_CondNotifyAll (&nt->join_cond, &nt->join_mutex);
@@ -307,7 +312,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 +334,7 @@
alive_flag = true;
startable_flag = false;
+ state = JV_RUNNABLE;
natThread *nt = (natThread *) data;
_Jv_ThreadStart (this, nt->thread, (_Jv_ThreadStartFunc *) &_Jv_ThreadRun);
}
@@ -388,8 +394,28 @@
::java::lang::Thread$State *
java::lang::Thread::getState()
{
- // FIXME
- return NULL;
+ _Jv_InitClass(&::java::lang::Thread$State::class$);
+
+ switch (state)
+ {
+ case JV_BLOCKED:
+ return ::java::lang::Thread$State::BLOCKED;
+ case JV_NEW:
+ return ::java::lang::Thread$State::NEW;
+
+ case JV_RUNNABLE:
+ return ::java::lang::Thread$State::RUNNABLE;
+ case JV_TERMINATED:
+ return ::java::lang::Thread$State::TERMINATED;
+ case JV_TIMED_WAITING:
+ return ::java::lang::Thread$State::TIMED_WAITING;
+ case JV_WAITING:
+ return ::java::lang::Thread$State::WAITING;
+ }
+
+ // We don't really need a default, but this makes the compiler
+ // happy.
+ return ::java::lang::Thread$State::RUNNABLE;
}
JNIEnv *
@@ -419,6 +445,7 @@
return -1;
thread->startable_flag = false;
thread->alive_flag = true;
+ thread->state = JV_RUNNABLE;
natThread *nt = (natThread *) thread->data;
_Jv_ThreadRegister (nt->thread);
return 0;
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,8 @@
#include <gcj/cni.h>
#include <gcj/field.h>
+#include <java/lang/Thread.h>
+
/* Macro for possible unused arguments. */
#define MAYBE_UNUSED __attribute__((__unused__))
@@ -673,4 +675,44 @@
// A helper function defined in prims.cc.
char* _Jv_PrependVersionedLibdir (char* libpath);
+
+// An enum for use with JvSetThreadState. We use a C++ enum rather
+// than the Java enum to avoid problems with class initialization
+// during VM bootstrap.
+typedef enum
+{
+ JV_BLOCKED,
+ JV_NEW,
+ JV_RUNNABLE,
+ JV_TERMINATED,
+ JV_TIMED_WAITING,
+ JV_WAITING
+} JvThreadState;
+
+// Temporarily set the thread's state.
+class JvSetThreadState
+{
+private:
+ ::java::lang::Thread *thread;
+ jint saved;
+
+public:
+
+ // Note that 'cthread' could be NULL -- during VM startup there may
+ // not be a Thread available.
+ JvSetThreadState(::java::lang::Thread *cthread, JvThreadState nstate)
+ : thread (cthread),
+ saved (cthread ? cthread->state : JV_NEW)
+ {
+ if (thread)
+ thread->state = nstate;
+ }
+
+ ~JvSetThreadState()
+ {
+ if (thread)
+ 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,34 @@
+int
+_Jv_MutexLock (_Jv_Mutex_t *mu)
+{
+ pthread_t self = pthread_self ();
+ if (mu->owner == self)
+ {
+ mu->count++;
+ }
+ else
+ {
+ JvSetThreadState holder (_Jv_ThreadCurrent(), JV_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 +121,7 @@
struct timespec ts;
+ JvThreadState new_state = JV_WAITING;
if (millis > 0 || nanos > 0)
{
// Calculate the abstime corresponding to the timeout.
@@ -118,6 +147,7 @@
{
m %= 1000;
ts.tv_nsec = m * 1000000 + (unsigned long long)nanos;
+ new_state = JV_TIMED_WAITING;
}
}
@@ -134,6 +164,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;