This patch puts a bit more into thread state handling. It adds a variable to hold the state inside the thread (in much the same way as the name is handled). It also updates some of the methods so that they also update the state. A full implementation will mean that VMs also have to update the state when it changes in native code. Note that we only look at the state from a VM perspective, not from an OS one. So, state changes in native code will be monitor lock acquisition, wait, notify and the expiration of sleep and join.
(And yes, using a String is ugly... roll on the merge!) Changelog: 2006-06-28 Andrew John Hughes <[EMAIL PROTECTED]> * java/lang/Thread.java: (Thread(ThreadGroup,Runnable,String,long)): Update state. (Thread(VMThread,String,int,boolean)): Likewise. (join(long,int)): Likewise. (resume()): Likewise. (sleep(long,int)): Likewise. (start()): Likewise. (stop()): Likewise. (suspend()): Likewise. (die()): Likewise. (getState()): Return either state or use VMThread. * java/lang/VMThread.java: (getState()): Added default implementation to return thread.state -- Andrew :-) Please avoid sending me Microsoft Office (e.g. Word, PowerPoint) attachments. See http://www.fsf.org/philosophy/no-word-attachments.html If you use Microsoft Office, support movement towards the end of vendor lock-in: http://opendocumentfellowship.org/petition/ "Value your freedom, or you will lose it, teaches history. `Don't bother us with politics' respond those who don't want to learn." -- Richard Stallman Escape the Java Trap with GNU Classpath! http://www.gnu.org/philosophy/java-trap.html public class gcj extends Freedom implements Java { ... }
Index: java/lang/Thread.java =================================================================== RCS file: /cvsroot/classpath/classpath/java/lang/Thread.java,v retrieving revision 1.26 diff -u -3 -p -u -r1.26 Thread.java --- java/lang/Thread.java 27 Jun 2006 21:57:29 -0000 1.26 +++ java/lang/Thread.java 28 Jun 2006 19:56:17 -0000 @@ -131,6 +131,9 @@ public class Thread implements Runnable /** The thread priority, 1 to 10. */ volatile int priority; + /** The current thread state. */ + volatile String state; + /** Native thread stack size. 0 = use default */ private long stacksize; @@ -372,6 +375,7 @@ public class Thread implements Runnable priority = current.priority; daemon = current.daemon; + state = "NEW"; contextClassLoader = current.contextClassLoader; contextClassLoaderIsSystemClassLoader = current.contextClassLoaderIsSystemClassLoader; @@ -402,6 +406,7 @@ public class Thread implements Runnable this.name = name; this.priority = priority; this.daemon = daemon; + state = "NEW"; // By default the context class loader is the system class loader, // we set a flag to signal this because we don't want to call // ClassLoader.getSystemClassLoader() at this point, because on @@ -706,7 +711,13 @@ public class Thread implements Runnable VMThread t = vmThread; if(t != null) - t.join(ms, ns); + { + if(ms == 0 && ns == 0) + state = "WAITING"; + else + state = "TIMED_WAITING"; + t.join(ms, ns); + } } /** @@ -724,7 +735,10 @@ public class Thread implements Runnable checkAccess(); VMThread t = vmThread; if (t != null) + { + state = "RUNNABLE"; t.resume(); + } } /** @@ -850,7 +864,7 @@ public class Thread implements Runnable * are no guarantees which thread will be next to run, but most VMs will * choose the highest priority thread that has been waiting longest. * - * @param ms the number of milliseconds to sleep. + * @param ms the number of milliseconds to sleep5~. * @throws InterruptedException if the Thread is (or was) interrupted; * it's <i>interrupted status</i> will be cleared * @throws IllegalArgumentException if ms is negative @@ -892,6 +906,11 @@ public class Thread implements Runnable if (ns < 0 || ns > 999999) throw new IllegalArgumentException("Nanoseconds ouf of range: " + ns); + if (ms == 0 && ns == 0) + currentThread().state = "WAITING"; + else + currentThread().state = "TIMED_WAITING"; + // Really sleep VMThread.sleep(ms, ns); } @@ -911,6 +930,7 @@ public class Thread implements Runnable if (vmThread != null || group == null) throw new IllegalThreadStateException(); + state = "RUNNABLE"; VMThread.create(this, stacksize); } @@ -984,7 +1004,10 @@ public class Thread implements Runnable } VMThread vt = vmThread; if (vt != null) + { + state = "TERMINATED"; vt.stop(t); + } else stillborn = t; } @@ -1006,7 +1029,10 @@ public class Thread implements Runnable checkAccess(); VMThread t = vmThread; if (t != null) + { + state = "WAITING"; t.suspend(); + } } /** @@ -1058,6 +1084,7 @@ public class Thread implements Runnable group.removeThread(this); vmThread = null; locals = null; + state = "TERMINATED"; } /** @@ -1239,7 +1266,7 @@ public class Thread implements Runnable public String getState() { VMThread t = vmThread; - return t == null ? null : t.getState(); + return t == null ? state : t.getState(); } /** @@ -1338,5 +1365,5 @@ public class Thread implements Runnable ThreadInfo info = bean.getThreadInfo(threadId, Integer.MAX_VALUE); return info.getStackTrace(); } - + } Index: vm/reference/java/lang/VMThread.java =================================================================== RCS file: /cvsroot/classpath/classpath/vm/reference/java/lang/VMThread.java,v retrieving revision 1.12 diff -u -3 -p -u -r1.12 VMThread.java --- vm/reference/java/lang/VMThread.java 26 Jun 2006 20:56:58 -0000 1.12 +++ vm/reference/java/lang/VMThread.java 28 Jun 2006 19:56:18 -0000 @@ -456,6 +456,9 @@ final class VMThread * @return a string corresponding to one of the * thread enumeration states specified above. */ - native String getState(); + String getState() + { + return thread.state; + } }
signature.asc
Description: Digital signature