+++ /dev/null
-/* VMThread -- VM interface for Thread of executable code
- Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation
-
-This file is part of GNU Classpath.
-
-GNU Classpath is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
-
-GNU Classpath is distributed in the hope that it will be useful, but
-WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GNU Classpath; see the file COPYING. If not, write to the
-Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-02110-1301 USA.
-
-Linking this library statically or dynamically with other modules is
-making a combined work based on this library. Thus, the terms and
-conditions of the GNU General Public License cover the whole
-combination.
-
-As a special exception, the copyright holders of this library give you
-permission to link this library with independent modules to produce an
-executable, regardless of the license terms of these independent
-modules, and to copy and distribute the resulting executable under
-terms of your choice, provided that you also meet, for each linked
-independent module, the terms and conditions of the license of that
-module. An independent module is a module which is not derived from
-or based on this library. If you modify this library, you may extend
-this exception to your version of the library, but you are not
-obligated to do so. If you do not wish to do so, delete this
-exception statement from your version. */
-
-package java.lang;
-
-/**
- * VM interface for Thread of executable code. Holds VM dependent state.
- * It is deliberately package local and final and should only be accessed
- * by the Thread class.
- * <p>
- * This is the GNU Classpath reference implementation, it should be adapted
- * for a specific VM.
- * <p>
- * The following methods must be implemented:
- * <ul>
- * <li>native void start(long stacksize);
- * <li>native void interrupt();
- * <li>native boolean isInterrupted();
- * <li>native void suspend();
- * <li>native void resume();
- * <li>native void nativeSetPriority(int priority);
- * <li>native void nativeStop(Throwable t);
- * <li>native static Thread currentThread();
- * <li>static native void yield();
- * <li>static native boolean interrupted();
- * </ul>
- * All other methods may be implemented to make Thread handling more efficient
- * or to implement some optional (and sometimes deprecated) behaviour. Default
- * implementations are provided but it is highly recommended to optimize them
- * for a specific VM.
- *
- * @author Jeroen Frijters (jeroen@frijters.net)
- * @author Dalibor Topic (robilad@kaffe.org)
- */
-final class VMThread
-{
- /**
- * The Thread object that this VM state belongs to.
- * Used in currentThread() and start().
- * Note: when this thread dies, this reference is *not* cleared
- */
- volatile Thread thread;
-
- /**
- * Flag that is set when the thread runs, used by stop() to protect against
- * stop's getting lost.
- */
- private volatile boolean running;
-
- /**
- * VM private data.
- */
- private transient Object vmdata;
-
- /**
- * Private constructor, create VMThreads with the static create method.
- *
- * @param thread The Thread object that was just created.
- */
- private VMThread(Thread thread)
- {
- this.thread = thread;
- }
-
- /**
- * This method is the initial Java code that gets executed when a native
- * thread starts. It's job is to coordinate with the rest of the VMThread
- * logic and to start executing user code and afterwards handle clean up.
- */
- private void run()
- {
- try
- {
- try
- {
- running = true;
- synchronized(thread)
- {
- Throwable t = thread.stillborn;
- if(t != null)
- {
- thread.stillborn = null;
- throw t;
- }
- }
- thread.run();
- }
- catch(Throwable t)
- {
- try
- {
- Thread.UncaughtExceptionHandler handler;
- handler = thread.getUncaughtExceptionHandler();
- handler.uncaughtException(thread, t);
- }
- catch(Throwable ignore)
- {
- }
- }
- }
- finally
- {
- // Setting runnable to false is partial protection against stop
- // being called while we're cleaning up. To be safe all code in
- // VMThread be unstoppable.
- running = false;
- thread.die();
- synchronized(this)
- {
- // release the threads waiting to join us
- notifyAll();
- }
- }
- }
-
- /**
- * Creates a native Thread. This is called from the start method of Thread.
- * The Thread is started.
- *
- * @param thread The newly created Thread object
- * @param stacksize Indicates the requested stacksize. Normally zero,
- * non-zero values indicate requested stack size in bytes but it is up
- * to the specific VM implementation to interpret them and may be ignored.
- */
- static void create(Thread thread, long stacksize)
- {
- VMThread vmThread = new VMThread(thread);
- thread.vmThread = vmThread;
- vmThread.start(stacksize);
- }
-
- /**
- * Gets the name of the thread. Usually this is the name field of the
- * associated Thread object, but some implementation might choose to
- * return the name of the underlying platform thread.
- */
- String getName()
- {
- return thread.name;
- }
-
- /**
- * Set the name of the thread. Usually this sets the name field of the
- * associated Thread object, but some implementations might choose to
- * set the name of the underlying platform thread.
- * @param name The new name
- */
- void setName(String name)
- {
- thread.name = name;
- }
-
- /**
- * Set the thread priority field in the associated Thread object and
- * calls the native method to set the priority of the underlying
- * platform thread.
- * @param priority The new priority
- */
- void setPriority(int priority)
- {
- thread.priority = priority;
- nativeSetPriority(priority);
- }
-
- /**
- * Returns the priority. Usually this is the priority field from the
- * associated Thread object, but some implementation might choose to
- * return the priority of the underlying platform thread.
- * @return this Thread's priority
- */
- int getPriority()
- {
- return thread.priority;
- }
-
- /**
- * Returns true if the thread is a daemon thread. Usually this is the
- * daemon field from the associated Thread object, but some
- * implementation might choose to return the daemon state of the underlying
- * platform thread.
- * @return whether this is a daemon Thread or not
- */
- boolean isDaemon()
- {
- return thread.daemon;
- }
-
- /**
- * Returns the number of stack frames in this Thread.
- * Will only be called when when a previous call to suspend() returned true.
- *
- * @deprecated unsafe operation
- */
- native int countStackFrames();
-
- /**
- * Wait the specified amount of time for the Thread in question to die.
- *
- * <p>Note that 1,000,000 nanoseconds == 1 millisecond, but most VMs do
- * not offer that fine a grain of timing resolution. Besides, there is
- * no guarantee that this thread can start up immediately when time expires,
- * because some other thread may be active. So don't expect real-time
- * performance.
- *
- * @param ms the number of milliseconds to wait, or 0 for forever
- * @param ns the number of extra nanoseconds to sleep (0-999999)
- * @throws InterruptedException if the Thread is interrupted; it's
- * <i>interrupted status</i> will be cleared
- */
- synchronized void join(long ms, int ns) throws InterruptedException
- {
- // Round up
- ms += (ns != 0) ? 1 : 0;
-
- // Compute end time, but don't overflow
- long now = System.currentTimeMillis();
- long end = now + ms;
- if (end < now)
- end = Long.MAX_VALUE;
-
- // A VM is allowed to return from wait() without notify() having been
- // called, so we loop to handle possible spurious wakeups.
- while(thread.vmThread != null)
- {
- // We use the VMThread object to wait on, because this is a private
- // object, so client code cannot call notify on us.
- wait(ms);
- if(ms != 0)
- {
- now = System.currentTimeMillis();
- ms = end - now;
- if(ms <= 0)
- {
- break;
- }
- }
- }
- }
-
- /**
- * Cause this Thread to stop abnormally and throw the specified exception.
- * If you stop a Thread that has not yet started, the stop is ignored
- * (contrary to what the JDK documentation says).
- * <b>WARNING</b>This bypasses Java security, and can throw a checked
- * exception which the call stack is unprepared to handle. Do not abuse
- * this power.
- *
- * <p>This is inherently unsafe, as it can interrupt synchronized blocks and
- * leave data in bad states.
- *
- * <p><b>NOTE</b> stop() should take care not to stop a thread if it is
- * executing code in this class.
- *
- * @param t the Throwable to throw when the Thread dies
- * @deprecated unsafe operation, try not to use
- */
- void stop(Throwable t)
- {
- // Note: we assume that we own the lock on thread
- // (i.e. that Thread.stop() is synchronized)
- if(running)
- nativeStop(t);
- else
- thread.stillborn = t;
- }
-
- /**
- * Create a native thread on the underlying platform and start it executing
- * on the run method of this object.
- * @param stacksize the requested size of the native thread stack
- */
- native void start(long stacksize);
-
- /**
- * Interrupt this thread.
- */
- native void interrupt();
-
- /**
- * Determine whether this Thread has been interrupted, but leave
- * the <i>interrupted status</i> alone in the process.
- *
- * @return whether the Thread has been interrupted
- */
- native boolean isInterrupted();
-
- /**
- * Suspend this Thread. It will not come back, ever, unless it is resumed.
- */
- native void suspend();
-
- /**
- * Resume this Thread. If the thread is not suspended, this method does
- * nothing.
- */
- native void resume();
-
- /**
- * Set the priority of the underlying platform thread.
- *
- * @param priority the new priority
- */
- native void nativeSetPriority(int priority);
-
- /**
- * Asynchronously throw the specified throwable in this Thread.
- *
- * @param t the exception to throw
- */
- native void nativeStop(Throwable t);
-
- /**
- * Return the Thread object associated with the currently executing
- * thread.
- *
- * @return the currently executing Thread
- */
- static native Thread currentThread();
-
- /**
- * Yield to another thread. The Thread will not lose any locks it holds
- * during this time. There are no guarantees which thread will be
- * next to run, and it could even be this one, but most VMs will choose
- * the highest priority thread that has been waiting longest.
- */
- static native void yield();
-
- /**
- * Suspend the current Thread's execution for the specified amount of
- * time. The Thread will not lose any locks it has during this time. There
- * are no guarantees which thread will be next to run, but most VMs will
- * choose the highest priority thread that has been waiting longest.
- *
- * <p>Note that 1,000,000 nanoseconds == 1 millisecond, but most VMs do
- * not offer that fine a grain of timing resolution. Besides, there is
- * no guarantee that this thread can start up immediately when time expires,
- * because some other thread may be active. So don't expect real-time
- * performance.
- *
- * @param ms the number of milliseconds to sleep.
- * @param ns the number of extra nanoseconds to sleep (0-999999)
- * @throws InterruptedException if the Thread is (or was) interrupted;
- * it's <i>interrupted status</i> will be cleared
- */
- static void sleep(long ms, int ns) throws InterruptedException
- {
- // Note: JDK treats a zero length sleep is like Thread.yield(),
- // without checking the interrupted status of the thread.
- // It's unclear if this is a bug in the implementation or the spec.
- // See http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6213203
- if (ms == 0 && ns == 0)
- {
- if (Thread.interrupted())
- throw new InterruptedException();
- return;
- }
-
- // Compute end time, but don't overflow
- long now = System.currentTimeMillis();
- long end = now + ms;
- if (end < now)
- end = Long.MAX_VALUE;
-
- // A VM is allowed to return from wait() without notify() having been
- // called, so we loop to handle possible spurious wakeups.
- VMThread vt = Thread.currentThread().vmThread;
- synchronized (vt)
- {
- while (true)
- {
- vt.wait(ms, ns);
- now = System.currentTimeMillis();
- if (now >= end)
- break;
- ms = end - now;
- ns = 0;
- }
- }
- }
-
- /**
- * Determine whether the current Thread has been interrupted, and clear
- * the <i>interrupted status</i> in the process.
- *
- * @return whether the current Thread has been interrupted
- */
- static native boolean interrupted();
-
- /**
- * Checks whether the current thread holds the monitor on a given object.
- * This allows you to do <code>assert Thread.holdsLock(obj)</code>.
- *
- * @param obj the object to check
- * @return true if the current thread is currently synchronized on obj
- * @throws NullPointerException if obj is null
- */
-// static boolean holdsLock(Object obj)
-// {
-// /* Use obj.notify to check if the current thread holds
-// * the monitor of the object.
-// * If it doesn't, notify will throw an exception.
-// */
-// try
-// {
-// obj.notify();
-// // okay, current thread holds lock
-// return true;
-// }
-// catch (IllegalMonitorStateException e)
-// {
-// // it doesn't hold the lock
-// return false;
-// }
-// }
- static native boolean holdsLock(Object obj);
-
- /**
- * Returns the current state of the thread.
- * The value must be one of "BLOCKED", "NEW",
- * "RUNNABLE", "TERMINATED", "TIMED_WAITING" or
- * "WAITING".
- *
- * @return a string corresponding to one of the
- * thread enumeration states specified above.
- */
- native String getState();
-
-}