diff options
Diffstat (limited to 'libjava/classpath/java/lang/ThreadLocalMap.java')
| -rw-r--r-- | libjava/classpath/java/lang/ThreadLocalMap.java | 325 |
1 files changed, 0 insertions, 325 deletions
diff --git a/libjava/classpath/java/lang/ThreadLocalMap.java b/libjava/classpath/java/lang/ThreadLocalMap.java deleted file mode 100644 index 7f67b13..0000000 --- a/libjava/classpath/java/lang/ThreadLocalMap.java +++ /dev/null @@ -1,325 +0,0 @@ -/* ThreadLocal -- a variable with a unique value per thread - Copyright (C) 2000, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. - -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; - -import java.lang.ref.WeakReference; - -/** - * ThreadLocalMap is the basic storage for the map of ThreadLocal instance - * to a thread's current value. - * - * Some applications really work out ThreadLocals, leading to this - * optimized implementation. - */ -final class ThreadLocalMap -{ - /** - * The log (base 2) of the initial size of the map - */ - private static final int LOG_INITIAL_SIZE = 3; - - /** - * The maximum occupancy rate (after which we grow) - */ - private static final float MAX_OCCUPANCY = 0.7f; - - /** - * The target occupancy rate. - */ - private static final float TARGET_OCCUPANCY = 0.5f; - - /** - * The deleted entry sentinel value. - */ - private static final Entry deletedEntry = new Entry(null); - - /** - * Constructor - */ - ThreadLocalMap() - { - /* Dummy value to ensure fast path can be optimized */ - entries = new Entry[1]; - hashMask = 0; - count = 0; - } - - /** - * The map entries - */ - private Entry[] entries; - - /** - * Used for start index computation - */ - private int hashMask; - - /** - * The number of entries currently in the map - */ - private int count; - - /** - * Create or grow the table to the specified size. The size must be a - * power of two for the efficient mask/hash computation. - * - * @param newSize The new table size. - */ - private void newEntryArray(int newSize) - { - int mask = newSize - 1; - Entry[] oldEntries = this.entries; - this.entries = new Entry[newSize]; - this.hashMask = mask; - - /* Copy old entries to new table */ - count = 0; - if (oldEntries != null) - { - for(Entry e: oldEntries) - { - if (e != null) - { - ThreadLocal<?> key = e.get(); - if (e != deletedEntry && key != null) - { - for(int i = key.fastHash & mask;; i = (i + 1) & mask) - { - if (entries[i] == null) - { - entries[i] = e; - count++; - break; - } - } - } - } - } - } - } - - /** - * We have run out of space in our locals. We use this as the - * trigger to attempt to find unused slots as ThreadLocals have - * died. If we recover any slots this way then we do not grow. - */ - private void overflow() - { - /* First 'actual' use */ - if (entries.length == 1) - { - newEntryArray(1 << LOG_INITIAL_SIZE); - return; - } - - /* Attempt to recover unused slots */ - int deleted = 0; - for(int i=0; i < entries.length; i++) - { - Entry e = entries[i]; - if (e != null) - { - if (e == deletedEntry) - { - deleted++; - } - else if (e.get() == null) - { - entries[i] = deletedEntry; - deleted++; - } - } - } - - if ((count-deleted) <= (TARGET_OCCUPANCY * entries.length)) - { - /* We currently rehash by simple reallocating into a same-sized table. - * An alternative would be to implement a clever hashing algorithm but - * as this happens infrequently this seems preferred */ - newEntryArray(entries.length); - return; - } - - /* Double the size */ - newEntryArray(entries.length << 1); - } - - /** - * This is the class that is used to refer to a thread local weakly. - * - * As we want to minimize indirections we extend WeakReference. - */ - static final class Entry extends WeakReference<ThreadLocal<?>> { - /** - * The value stored in this slot - */ - Object value; - - /** - * Constructor - */ - Entry(ThreadLocal<?> threadLocal) { - super(threadLocal); - } - } - - /** - * Gets the value associated with the ThreadLocal object for the currently - * executing Thread. If this is the first time the current thread has called - * get(), and it has not already called set(), the sentinel value is returned. - * - * @return the value of the variable in this thread, or sentinel if not present. - */ - public Object get(ThreadLocal<?> key) - { - int mask = this.hashMask; - for(int i = key.fastHash & mask;; i = (i + 1) & mask) { - Entry e = entries[i]; - if (e != null) { - if (e.get() == key) { - return e.value; - } - } else { - return ThreadLocal.sentinel; - } - } - } - - /** - * Sets the value associated with the ThreadLocal object for the currently - * executing Thread. This overrides any existing value associated with the - * current Thread and prevents <code>initialValue()</code> from being - * called if this is the first access to this ThreadLocal in this Thread. - * - * @param value the value to set this thread's view of the variable to - */ - public void set(ThreadLocal<?> key, Object value) - { - /* Overflow ? */ - if ((count+1) >= (MAX_OCCUPANCY * entries.length)) - { - overflow(); - } - - /* Set the entry */ - int mask = this.hashMask; - for(int i = key.fastHash & mask;; i = (i + 1) & mask) - { - Entry e = entries[i]; - if (e == null || e == deletedEntry) - { - /* Create entry */ - if (e == null) count++; - entries[i] = e = new Entry(key); - e.value = value; - return; - } - else - { - ThreadLocal<?> entryKey = e.get(); - if (entryKey == null) - { - entries[i] = deletedEntry; - } - else if (entryKey == key) - { - /* Update entry */ - e.value = value; - return; - } - } - } - } - - /** - * Removes the value associated with the ThreadLocal object for the - * currently executing Thread. - * @since 1.5 - */ - public void remove(ThreadLocal<?> key) - { - int mask = this.hashMask; - for(int i = key.fastHash & mask;; i = (i + 1) & mask) - { - Entry e = entries[i]; - if (e != null) - { - ThreadLocal<?> entryKey = e.get(); - if (entryKey != key) - { - if (entryKey == null) { - entries[i] = deletedEntry; - } - continue; - } - else - { - /* Remove from the table */ - entries[i] = deletedEntry; - } - } - return; - } - } - - /** - * Clear out the map. Done once during thread death. - */ - void clear() { - entries = null; - } - - /** - * Inherit all the InheritableThreadLocal instances from the given parent. - * - * @param parentMap The map to inherit from. - */ - public void inherit(ThreadLocalMap parentMap) { - for(Entry e: parentMap.entries) - { - if (e != null && e != deletedEntry) - { - ThreadLocal<?> key = e.get(); - if (key instanceof InheritableThreadLocal) - { - set(key, ((InheritableThreadLocal)key).childValue(e.value)); - } - } - } - } -} |
