diff options
author | Andrew John Hughes <gnu_andrew@member.fsf.org> | 2006-03-20 00:32:54 +0000 |
---|---|---|
committer | Andrew John Hughes <gnu_andrew@member.fsf.org> | 2006-03-20 00:32:54 +0000 |
commit | 4f1902554ebf0c2f6bddcf099851be09eef346b0 (patch) | |
tree | b58fb9be832680554116d7d8458ff5ac12e6c364 | |
parent | b2a543058a0bf760fbfd9a964819db82ab01d50d (diff) | |
download | classpath-4f1902554ebf0c2f6bddcf099851be09eef346b0.tar.gz |
2006-03-20 Andrew John Hughes <gnu_andrew@member.fsf.org>
* java/lang/System.java:
(nanoTime()): Documented.
* java/lang/Thread.java:
(setUncaughtExceptionHandler(UncaughtExceptionHandler):
Added docs and security check.
(getUncaughtExceptionHandler()): Documented.
(setDefaultUncaughtExceptionHandler(UncaughtExceptionHandler):
Added docs and security check.
(getDefaultUncaughtExceptionHandler()): Documented.
(getId()): Documented.
(Thread.State): Documented.
* vm/reference/gnu/classpath/Unsafe.java:
Documented.
(getUnsafe()): Updated to handle security.
2006-03-20 Tom Tromey <tromey@redhat.com>
* java/lang/System.java:
(nanoTime()): Implemented.
* java/lang/Thread.java:
(getId()): Implemented.
* java/util/AbstractMap.java:
(SimpleImmutableEntry): New 1.6 class.
(BasicMapEntry): Modified to be SimpleEntry.
* java/util/Collections.java:
Modified to use SimpleEntry.
* java/util/EnumMap.java: Likewise.
* java/util/HashMap.java: Likewise.
* java/util/Hashtable.java: Likewise.
* java/util/TreeMap.java: Likewise.
* vm/reference/gnu/classpath/Unsafe.java:
New class to handle low-level facilities for concurrency.
* vm/reference/java/lang/VMSystem.java:
(nanoTime()): Implemented.
-rw-r--r-- | ChangeLog | 37 | ||||
-rw-r--r-- | java/lang/System.java | 30 | ||||
-rw-r--r-- | java/lang/Thread.java | 120 | ||||
-rw-r--r-- | java/util/AbstractMap.java | 61 | ||||
-rw-r--r-- | java/util/Collections.java | 2 | ||||
-rw-r--r-- | java/util/EnumMap.java | 2 | ||||
-rw-r--r-- | java/util/HashMap.java | 8 | ||||
-rw-r--r-- | java/util/Hashtable.java | 8 | ||||
-rw-r--r-- | java/util/TreeMap.java | 2 | ||||
-rw-r--r-- | vm/reference/gnu/classpath/Unsafe.java | 328 | ||||
-rw-r--r-- | vm/reference/java/lang/VMSystem.java | 5 |
11 files changed, 577 insertions, 26 deletions
@@ -1,3 +1,40 @@ +2006-03-20 Andrew John Hughes <gnu_andrew@member.fsf.org> + + * java/lang/System.java: + (nanoTime()): Documented. + * java/lang/Thread.java: + (setUncaughtExceptionHandler(UncaughtExceptionHandler): + Added docs and security check. + (getUncaughtExceptionHandler()): Documented. + (setDefaultUncaughtExceptionHandler(UncaughtExceptionHandler): + Added docs and security check. + (getDefaultUncaughtExceptionHandler()): Documented. + (getId()): Documented. + (Thread.State): Documented. + * vm/reference/gnu/classpath/Unsafe.java: + Documented. + (getUnsafe()): Updated to handle security. + +2006-03-20 Tom Tromey <tromey@redhat.com> + + * java/lang/System.java: + (nanoTime()): Implemented. + * java/lang/Thread.java: + (getId()): Implemented. + * java/util/AbstractMap.java: + (SimpleImmutableEntry): New 1.6 class. + (BasicMapEntry): Modified to be SimpleEntry. + * java/util/Collections.java: + Modified to use SimpleEntry. + * java/util/EnumMap.java: Likewise. + * java/util/HashMap.java: Likewise. + * java/util/Hashtable.java: Likewise. + * java/util/TreeMap.java: Likewise. + * vm/reference/gnu/classpath/Unsafe.java: + New class to handle low-level facilities for concurrency. + * vm/reference/java/lang/VMSystem.java: + (nanoTime()): Implemented. + 2006-03-13 Tom Tromey <tromey@redhat.com> * javax/swing/text/html/StyleSheet.java (removeAttributes): diff --git a/java/lang/System.java b/java/lang/System.java index 1fb59794f..c0d897354 100644 --- a/java/lang/System.java +++ b/java/lang/System.java @@ -233,6 +233,36 @@ public final class System { return VMSystem.currentTimeMillis(); } + + /** + * <p> + * Returns the current value of a nanosecond-precise system timer. + * The value of the timer is an offset relative to some arbitrary fixed + * time, which may be in the future (making the value negative). This + * method is useful for timing events where nanosecond precision is + * required. This is achieved by calling this method before and after the + * event, and taking the difference betweent the two times: + * </p> + * <p> + * <code>long startTime = System.nanoTime();</code><br /> + * <code>... <emph>event code</emph> ...</code><br /> + * <code>long endTime = System.nanoTime();</code><br /> + * <code>long duration = endTime - startTime;</code><br /> + * </p> + * <p> + * Note that the value is only nanosecond-precise, and not accurate; there + * is no guarantee that the difference between two values is really a + * nanosecond. Also, the value is prone to overflow if the offset + * exceeds 2^63. + * </p> + * + * @return the time of a system timer in nanoseconds. + * @since 1.5 + */ + public static long nanoTime() + { + return VMSystem.nanoTime(); + } /** * Copy one array onto another from <code>src[srcStart]</code> ... diff --git a/java/lang/Thread.java b/java/lang/Thread.java index 398a3864b..b4ebd58e4 100644 --- a/java/lang/Thread.java +++ b/java/lang/Thread.java @@ -131,9 +131,18 @@ public class Thread implements Runnable /** The context classloader for this Thread. */ private ClassLoader contextClassLoader; + + /** This thread's ID. */ + private final long threadId; + + /** The park blocker. See LockSupport. */ + Object parkBlocker; /** The next thread number to use. */ private static int numAnonymousThreadsCreated; + + /** The next thread ID to use. */ + private static long nextThreadId; /** The default exception handler. */ private static UncaughtExceptionHandler defaultHandler; @@ -349,6 +358,11 @@ public class Thread implements Runnable this.name = name.toString(); this.runnable = target; this.stacksize = size; + + synchronized (Thread.class) + { + this.threadId = nextThreadId++; + } priority = current.priority; daemon = current.daemon; @@ -378,6 +392,10 @@ public class Thread implements Runnable this.priority = priority; this.daemon = daemon; this.contextClassLoader = ClassLoader.getSystemClassLoader(); + synchronized (Thread.class) + { + this.threadId = nextThreadId++; + } } /** @@ -1020,29 +1038,100 @@ public class Thread implements Runnable return locals; } - /** @since 1.5 */ + /** + * Assigns the given <code>UncaughtExceptionHandler</code> to this + * thread. This will then be called if the thread terminates due + * to an uncaught exception, pre-empting that of the + * <code>ThreadGroup</code>. + * + * @param h the handler to use for this thread. + * @throws SecurityException if the current thread can't modify this thread. + * @since 1.5 + */ public void setUncaughtExceptionHandler(UncaughtExceptionHandler h) { + SecurityManager sm = SecurityManager.current; // Be thread-safe. + if (sm != null) + sm.checkAccess(this); exceptionHandler = h; } - /** @since 1.5 */ + /** + * <p> + * Returns the handler used when this thread terminates due to an + * uncaught exception. The handler used is determined by the following: + * </p> + * <ul> + * <li>If this thread has its own handler, this is returned.</li> + * <li>If not, then the handler of the thread's <code>ThreadGroup</code> + * object is returned.</li> + * <li>If both are unavailable, then <code>null</code> is returned.</li> + * </ul> + * + * @return the appropriate <code>UncaughtExceptionHandler</code> or + * <code>null</code> if one can't be obtained. + * @since 1.5 + */ public UncaughtExceptionHandler getUncaughtExceptionHandler() { return exceptionHandler; } - /** @since 1.5 */ - public static void setDefaultUncaughtExceptionHandler(UncaughtExceptionHandler h) + /** + * <p> + * Sets the default uncaught exception handler used when one isn't + * provided by the thread or its associated <code>ThreadGroup</code>. + * This exception handler is used when the thread itself does not + * have an exception handler, and the thread's <code>ThreadGroup</code> + * does not override this default mechanism with its own. As the group + * calls this handler by default, this exception handler should not defer + * to that of the group, as it may lead to infinite recursion. + * </p> + * <p> + * Uncaught exception handlers are used when a thread terminates due to + * an uncaught exception. Replacing this handler allows default code to + * be put in place for all threads in order to handle this eventuality. + * </p> + * + * @param h the new default uncaught exception handler to use. + * @throws SecurityException if a security manager is present and + * disallows the runtime permission + * "setDefaultUncaughtExceptionHandler". + * @since 1.5 + */ + public static void + setDefaultUncaughtExceptionHandler(UncaughtExceptionHandler h) { + SecurityManager sm = SecurityManager.current; // Be thread-safe. + if (sm != null) + sm.checkPermission(new RuntimePermission("setDefaultUncaughtExceptionHandler")); defaultHandler = h; } - /** @since 1.5 */ + /** + * Returns the handler used by default when a thread terminates + * unexpectedly due to an exception, or <code>null</code> if one doesn't + * exist. + * + * @return the default uncaught exception handler. + * @since 1.5 + */ public static UncaughtExceptionHandler getDefaultUncaughtExceptionHandler() { return defaultHandler; } + + /** + * Returns the unique identifier for this thread. This ID is generated + * on thread creation, and may be re-used on its death. + * + * @return a positive long number representing the thread's ID. + * @since 1.5 + */ + public long getId() + { + return threadId; + } /** * <p> @@ -1102,7 +1191,26 @@ public class Thread implements Runnable void uncaughtException(Thread thr, Throwable exc); } - /** @since 1.5 */ + /** + * <p> + * Represents the current state of a thread, according to the VM rather + * than the operating system. It can be one of the following: + * </p> + * <ul> + * <li>NEW -- The thread has just been created but is not yet running.</li> + * <li>RUNNABLE -- The thread is currently running or can be scheduled + * to run.</li> + * <li>BLOCKED -- The thread is blocked waiting on an I/O operation + * or to obtain a lock.</li> + * <li>WAITING -- The thread is waiting indefinately for another thread + * to do something.</li> + * <li>TIMED_WAITING -- The thread is waiting for a specific amount of time + * for another thread to do something.</li> + * <li>TERMINATED -- The thread has exited.</li> + * </ul> + * + * @since 1.5 + */ public enum State { BLOCKED, NEW, RUNNABLE, TERMINATED, TIMED_WAITING, WAITING; diff --git a/java/util/AbstractMap.java b/java/util/AbstractMap.java index 9b543b026..29249e1dc 100644 --- a/java/util/AbstractMap.java +++ b/java/util/AbstractMap.java @@ -39,6 +39,8 @@ exception statement from your version. */ package java.util; +import java.io.Serializable; + /** * An abstract implementation of Map to make it easier to create your own * implementations. In order to create an unmodifiable Map, subclass @@ -67,7 +69,41 @@ package java.util; */ public abstract class AbstractMap<K, V> implements Map<K, V> { - /** An "enum" of iterator types. */ + /** @since 1.6 */ + public static class SimpleImmutableEntry<K, V> + implements Entry<K, V>, Serializable + { + K key; + V value; + + public SimpleImmutableEntry(K key, V value) + { + this.key = key; + this.value = value; + } + + public SimpleImmutableEntry(Entry<? extends K, ? extends V> entry) + { + this(entry.getKey(), entry.getValue()); + } + + public K getKey() + { + return key; + } + + public V getValue() + { + return value; + } + + public V setValue(V value) + { + throw new UnsupportedOperationException("setValue not supported on immutable entry"); + } + } + +/** An "enum" of iterator types. */ // Package visible for use by subclasses. static final int KEYS = 0, VALUES = 1, @@ -629,10 +665,10 @@ public abstract class AbstractMap<K, V> implements Map<K, V> * * @author Jon Zeppieri * @author Eric Blake (ebb9@email.byu.edu) + * + * @since 1.6 */ - // XXX - FIXME Use fully qualified implements as gcj 3.1 workaround. - // Bug still exists in 3.4.1 - static class BasicMapEntry<K, V> implements Map.Entry<K, V> + public static class SimpleEntry<K, V> implements Entry<K, V>, Serializable { /** * The key. Package visible for direct manipulation. @@ -649,11 +685,16 @@ public abstract class AbstractMap<K, V> implements Map<K, V> * @param newKey the key * @param newValue the value */ - BasicMapEntry(K newKey, V newValue) + public SimpleEntry(K newKey, V newValue) { key = newKey; value = newValue; } + + public SimpleEntry(Entry<? extends K, ? extends V> entry) + { + this(entry.getKey(), entry.getValue()); + } /** * Compares the specified object with this entry. Returns true only if @@ -668,14 +709,14 @@ public abstract class AbstractMap<K, V> implements Map<K, V> * @param o the object to compare * @return <code>true</code> if it is equal */ - public final boolean equals(Object o) + public boolean equals(Object o) { if (! (o instanceof Map.Entry)) return false; // Optimize for our own entries. - if (o instanceof BasicMapEntry) + if (o instanceof SimpleEntry) { - BasicMapEntry e = (BasicMapEntry) o; + SimpleEntry e = (SimpleEntry) o; return (AbstractMap.equals(key, e.key) && AbstractMap.equals(value, e.value)); } @@ -751,5 +792,7 @@ public abstract class AbstractMap<K, V> implements Map<K, V> { return key + "=" + value; } - } // class BasicMapEntry + } // class SimpleEntry + + } diff --git a/java/util/Collections.java b/java/util/Collections.java index 6cf21a53b..29ee4dfe6 100644 --- a/java/util/Collections.java +++ b/java/util/Collections.java @@ -1943,7 +1943,7 @@ public class Collections { if (entries == null) { - Map.Entry<K,V> entry = new AbstractMap.BasicMapEntry<K, V>(k, v) + Map.Entry<K,V> entry = new AbstractMap.SimpleEntry<K, V>(k, v) { /** * Sets the value of the map entry to the supplied value. diff --git a/java/util/EnumMap.java b/java/util/EnumMap.java index 31c003d61..477dff8e0 100644 --- a/java/util/EnumMap.java +++ b/java/util/EnumMap.java @@ -329,7 +329,7 @@ public class EnumMap<K extends Enum<K>, V> ; // FIXME: we could just return something that // only knows the index. That would be cleaner. - return new AbstractMap.BasicMapEntry<K, V>(enumClass.getEnumConstants()[index], + return new AbstractMap.SimpleEntry<K, V>(enumClass.getEnumConstants()[index], store[index]) { public V setValue(V newVal) diff --git a/java/util/HashMap.java b/java/util/HashMap.java index 2ce74becc..715569a3f 100644 --- a/java/util/HashMap.java +++ b/java/util/HashMap.java @@ -162,7 +162,7 @@ public class HashMap<K, V> extends AbstractMap<K, V> * * @author Eric Blake (ebb9@email.byu.edu) */ - static class HashEntry<K, V> extends AbstractMap.BasicMapEntry<K, V> + static class HashEntry<K, V> extends AbstractMap.SimpleEntry<K, V> { /** * The next entry in the linked list. Package visible for use by subclass. @@ -386,10 +386,10 @@ public class HashMap<K, V> extends AbstractMap<K, V> for (Map.Entry<K,V> e : addMap.entrySet()) { // Optimize in case the Entry is one of our own. - if (e instanceof AbstractMap.BasicMapEntry) + if (e instanceof AbstractMap.SimpleEntry) { - AbstractMap.BasicMapEntry<? extends K, ? extends V> entry - = (AbstractMap.BasicMapEntry<? extends K, ? extends V>) e; + AbstractMap.SimpleEntry<? extends K, ? extends V> entry + = (AbstractMap.SimpleEntry<? extends K, ? extends V>) e; put(entry.key, entry.value); } else diff --git a/java/util/Hashtable.java b/java/util/Hashtable.java index 37ee03ccc..de3c4a944 100644 --- a/java/util/Hashtable.java +++ b/java/util/Hashtable.java @@ -175,7 +175,7 @@ public class Hashtable<K, V> extends Dictionary<K, V> * `null' is not allowed for keys and values. */ private static final class HashEntry<K, V> - extends AbstractMap.BasicMapEntry<K, V> + extends AbstractMap.SimpleEntry<K, V> { /** The next entry in the linked list. */ HashEntry<K, V> next; @@ -512,10 +512,10 @@ public class Hashtable<K, V> extends Dictionary<K, V> for (Map.Entry<K,V> e : addMap.entrySet()) { // Optimize in case the Entry is one of our own. - if (e instanceof AbstractMap.BasicMapEntry) + if (e instanceof AbstractMap.SimpleEntry) { - AbstractMap.BasicMapEntry<? extends K, ? extends V> entry - = (AbstractMap.BasicMapEntry<? extends K, ? extends V>) e; + AbstractMap.SimpleEntry<? extends K, ? extends V> entry + = (AbstractMap.SimpleEntry<? extends K, ? extends V>) e; put(entry.key, entry.value); } else diff --git a/java/util/TreeMap.java b/java/util/TreeMap.java index 46f405c59..d366f067e 100644 --- a/java/util/TreeMap.java +++ b/java/util/TreeMap.java @@ -162,7 +162,7 @@ public class TreeMap<K, V> extends AbstractMap<K, V> * * @author Eric Blake (ebb9@email.byu.edu) */ - private static final class Node<K, V> extends AbstractMap.BasicMapEntry<K, V> + private static final class Node<K, V> extends AbstractMap.SimpleEntry<K, V> { // All fields package visible for use by nested classes. /** The color of this node. */ diff --git a/vm/reference/gnu/classpath/Unsafe.java b/vm/reference/gnu/classpath/Unsafe.java new file mode 100644 index 000000000..3494f5fc6 --- /dev/null +++ b/vm/reference/gnu/classpath/Unsafe.java @@ -0,0 +1,328 @@ +/* Unsafe.java - Unsafe operations needed for concurrency + Copyright (C) 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 gnu.classpath; + +import java.lang.reflect.Field; + +/** + * This class should provide access to low-level operations and its + * use should be limited to trusted code. Fields can be accessed using + * memory addresses, with undefined behaviour occurring if invalid memory + * addresses are given. + * + * @author Tom Tromey (tromey@redhat.com) + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + */ +public class Unsafe +{ + // Singleton class. + private static Unsafe unsafe = new Unsafe(); + + /** + * Private default constructor to prevent creation of an arbitrary + * number of instances. + */ + private Unsafe() + { + } + + /** + * Retrieve the singleton instance of <code>Unsafe</code>. The calling + * method should guard this instance from untrusted code, as it provides + * access to low-level operations such as direct memory access. + * + * @throws SecurityException if a security manager exists and prevents + * access to the system properties. + */ + public static Unsafe getUnsafe() + { + SecurityManager sm = System.getSecurityManager(); + if (sm != null) + sm.checkPropertiesAccess(); + return unsafe; + } + + /** + * Returns the memory address offset of the given static field. + * The offset is merely used as a means to access a particular field + * in the other methods of this class. The value is unique to the given + * field and the same value should be returned on each subsequent call. + * + * @param field the field whose offset should be returned. + * @return the offset of the given field. + */ + public native long objectFieldOffset(Field field); + + /** + * Compares the value of the integer field at the specified offset + * in the supplied object with the given expected value, and updates + * it if they match. The operation of this method should be atomic, + * thus providing an uninterruptible way of updating an integer field. + * + * @param obj the object containing the field to modify. + * @param offset the offset of the integer field within <code>obj</code>. + * @param expect the expected value of the field. + * @param update the new value of the field if it equals <code>expect</code>. + * @return true if the field was changed. + */ + public native boolean compareAndSwapInt(Object obj, long offset, + int expect, int update); + + /** + * Compares the value of the long field at the specified offset + * in the supplied object with the given expected value, and updates + * it if they match. The operation of this method should be atomic, + * thus providing an uninterruptible way of updating a long field. + * + * @param obj the object containing the field to modify. + * @param offset the offset of the long field within <code>obj</code>. + * @param expect the expected value of the field. + * @param update the new value of the field if it equals <code>expect</code>. + * @return true if the field was changed. + */ + public native boolean compareAndSwapLong(Object obj, long offset, + long expect, long update); + + /** + * Compares the value of the object field at the specified offset + * in the supplied object with the given expected value, and updates + * it if they match. The operation of this method should be atomic, + * thus providing an uninterruptible way of updating an object field. + * + * @param obj the object containing the field to modify. + * @param offset the offset of the object field within <code>obj</code>. + * @param expect the expected value of the field. + * @param update the new value of the field if it equals <code>expect</code>. + * @return true if the field was changed. + */ + public native boolean compareAndSwapObject(Object obj, long offset, + Object expect, Object update); + + /** + * Sets the value of the integer field at the specified offset in the + * supplied object to the given value. This is an ordered or lazy + * version of <code>putIntVolatile(Object,long,int)</code>, which + * doesn't guarantee the immediate visibility of the change to other + * threads. It is only really useful where the integer field is + * <code>volatile</code>, and is thus expected to change unexpectedly. + * + * @param obj the object containing the field to modify. + * @param offset the offset of the integer field within <code>obj</code>. + * @param value the new value of the field. + * @see #putIntVolatile(Object,long,int) + */ + public native void putOrderedInt(Object obj, long offset, int value); + + /** + * Sets the value of the long field at the specified offset in the + * supplied object to the given value. This is an ordered or lazy + * version of <code>putLongVolatile(Object,long,long)</code>, which + * doesn't guarantee the immediate visibility of the change to other + * threads. It is only really useful where the long field is + * <code>volatile</code>, and is thus expected to change unexpectedly. + * + * @param obj the object containing the field to modify. + * @param offset the offset of the long field within <code>obj</code>. + * @param value the new value of the field. + * @see #putLongVolatile(Object,long,long) + */ + public native void putOrderedLong(Object obj, long offset, long value); + + /** + * Sets the value of the object field at the specified offset in the + * supplied object to the given value. This is an ordered or lazy + * version of <code>putObjectVolatile(Object,long,Object)</code>, which + * doesn't guarantee the immediate visibility of the change to other + * threads. It is only really useful where the object field is + * <code>volatile</code>, and is thus expected to change unexpectedly. + * + * @param obj the object containing the field to modify. + * @param offset the offset of the object field within <code>obj</code>. + * @param value the new value of the field. + */ + public native void putOrderedObject(Object obj, long offset, Object value); + + /** + * Sets the value of the integer field at the specified offset in the + * supplied object to the given value, with volatile store semantics. + * + * @param obj the object containing the field to modify. + * @param offset the offset of the integer field within <code>obj</code>. + * @param value the new value of the field. + */ + public native void putIntVolatile(Object obj, long offset, int value); + + /** + * Retrieves the value of the integer field at the specified offset in the + * supplied object with volatile load semantics. + * + * @param obj the object containing the field to read. + * @param offset the offset of the integer field within <code>obj</code>. + */ + public native int getIntVolatile(Object obj, long offset); + + /** + * Sets the value of the long field at the specified offset in the + * supplied object to the given value, with volatile store semantics. + * + * @param obj the object containing the field to modify. + * @param offset the offset of the long field within <code>obj</code>. + * @param value the new value of the field. + * @see #putLong(Object,long,long) + */ + public native void putLongVolatile(Object obj, long offset, long value); + + /** + * Sets the value of the long field at the specified offset in the + * supplied object to the given value. + * + * @param obj the object containing the field to modify. + * @param offset the offset of the long field within <code>obj</code>. + * @param value the new value of the field. + * @see #putLongVolatile(Object,long,long) + */ + public native void putLong(Object obj, long offset, long value); + + /** + * Retrieves the value of the long field at the specified offset in the + * supplied object with volatile load semantics. + * + * @param obj the object containing the field to read. + * @param offset the offset of the long field within <code>obj</code>. + * @see #getLong(Object,long) + */ + public native long getLongVolatile(Object obj, long offset); + + /** + * Retrieves the value of the long field at the specified offset in the + * supplied object. + * + * @param obj the object containing the field to read. + * @param offset the offset of the long field within <code>obj</code>. + * @see #getLongVolatile(Object,long) + */ + public native long getLong(Object obj, long offset); + + /** + * Sets the value of the object field at the specified offset in the + * supplied object to the given value, with volatile store semantics. + * + * @param obj the object containing the field to modify. + * @param offset the offset of the object field within <code>obj</code>. + * @param value the new value of the field. + * @see #putObject(Object,long,Object) + */ + public native void putObjectVolatile(Object obj, long offset, Object value); + + /** + * Sets the value of the object field at the specified offset in the + * supplied object to the given value. + * + * @param obj the object containing the field to modify. + * @param offset the offset of the object field within <code>obj</code>. + * @param value the new value of the field. + * @see #putObjectVolatile(Object,long,Object) + */ + public native void putObject(Object obj, long offset, Object value); + + /** + * Retrieves the value of the object field at the specified offset in the + * supplied object with volatile load semantics. + * + * @param obj the object containing the field to read. + * @param offset the offset of the object field within <code>obj</code>. + */ + public native Object getObjectVolatile(Object obj, long offset); + + /** + * Returns the offset of the first element for a given array class. + * To access elements of the array class, this value may be used along + * with that returned by + * <a href="#arrayIndexScale"><code>arrayIndexScale</code></a>, + * if non-zero. + * + * @param arrayClass the class for which the first element's address should + * be obtained. + * @return the offset of the first element of the array class. + * @see arrayIndexScale(Class) + */ + public native int arrayBaseOffset(Class arrayClass); + + /** + * Returns the scale factor used for addressing elements of the supplied + * array class. Where a suitable scale factor can not be returned (e.g. + * for primitive types), zero should be returned. The returned value + * can be used with + * <a href="#arrayBaseOffset"><code>arrayBaseOffset</code></a> + * to access elements of the class. + * + * @param arrayClass the class whose scale factor should be returned. + * @return the scale factor, or zero if not supported for this array class. + */ + public native int arrayIndexScale(Class arrayClass); + + /** + * Releases the block on a thread created by + * <a href="#park"><code>park</code></a>. This method can also be used + * to terminate a blockage caused by a prior call to <code>park</code>. + * This operation is unsafe, as the thread must be guaranteed to be + * live. This is true of Java, but not native code. + * + * @param thread the thread to unblock. + */ + public native void unpark(Thread thread); + + /** + * Blocks the thread until a matching + * <a href="#unpark"><code>unpark</code></a> occurs, the thread is + * interrupted or the optional timeout expires. If an <code>unpark</code> + * call has already occurred, this also counts. A timeout value of zero + * is defined as no timeout. When <code>isAbsolute</code> is + * <code>true</code>, the timeout is in milliseconds relative to the + * epoch. Otherwise, the value is the number of nanoseconds which must + * occur before timeout. This call may also return spuriously (i.e. + * for no apparent reason). + * + * @param isAbsolute true if the timeout is specified in milliseconds from + * the epoch. + * @param time either the number of nanoseconds to wait, or a time in + * milliseconds from the epoch to wait for. + */ + public native void park(boolean isAbsolute, long time); + +} diff --git a/vm/reference/java/lang/VMSystem.java b/vm/reference/java/lang/VMSystem.java index 6002ab132..5ed2228c8 100644 --- a/vm/reference/java/lang/VMSystem.java +++ b/vm/reference/java/lang/VMSystem.java @@ -137,6 +137,11 @@ final class VMSystem */ public static native long currentTimeMillis(); + public static long nanoTime() + { + return currentTimeMillis() * 1000; + } + /** * Returns a list of 'name=value' pairs representing the current environment * variables. |