/* 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);
	vmThread.start(stacksize);
	thread.vmThread = vmThread;
    }

    /**
     * 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;
	}
    }

  /**
   * 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();

}
