aboutsummaryrefslogtreecommitdiff
path: root/libjava/classpath/java/lang/ThreadLocalMap.java
diff options
context:
space:
mode:
Diffstat (limited to 'libjava/classpath/java/lang/ThreadLocalMap.java')
-rw-r--r--libjava/classpath/java/lang/ThreadLocalMap.java325
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));
- }
- }
- }
- }
-}