Changeset 11553


Ignore:
Timestamp:
01/11/09 08:29:20 (12 years ago)
Author:
ehuelsmann
Message:

Increase performance of LispThread?.currentThread() by more than 50% (uncontended case).
MAPCAR-THREADS correctness: use a concurrent hashmap.

  • Increases function initialization of most lisp functions (which call currentThread())
  • Simplifies LispThread? code (eliminating synchronized blocks and caching variables)
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/abcl/src/org/armedbear/lisp/LispThread.java

    r11539 r11553  
    3434package org.armedbear.lisp;
    3535
    36 import java.util.WeakHashMap;
    3736import java.util.Iterator;
     37import java.util.concurrent.ConcurrentHashMap;
    3838
    3939public final class LispThread extends LispObject
     
    4141    private static boolean use_fast_calls = false;
    4242
    43     private static final Object lock = new Object();
    44 
    45     private static WeakHashMap<Thread,LispThread> map =
    46        new WeakHashMap<Thread,LispThread>();
    47 
    48     private static Thread currentJavaThread;
    49     private static LispThread currentLispThread;
     43    // use a concurrent hashmap: we may want to add threads
     44    // while at the same time iterating the hash
     45    final private static ConcurrentHashMap<Thread,LispThread> map =
     46       new ConcurrentHashMap<Thread,LispThread>();
     47
     48    private static ThreadLocal<LispThread> threads = new ThreadLocal<LispThread>(){
     49        @Override
     50        public LispThread initialValue() {
     51            Thread thisThread = Thread.currentThread();
     52            LispThread newThread = new LispThread(thisThread);
     53            LispThread.map.put(thisThread,newThread);
     54            return newThread;
     55        }
     56    };
    5057
    5158    public static final LispThread currentThread()
    5259    {
    53         Thread javaThread = Thread.currentThread();
    54         synchronized (lock) {
    55             if (javaThread == currentJavaThread)
    56                 return currentLispThread;
    57         }
    58         LispThread lispThread = (LispThread) map.get(javaThread);
    59         if (lispThread == null) {
    60             lispThread = new LispThread(javaThread);
    61             put(javaThread, lispThread);
    62         }
    63         synchronized (lock) {
    64             currentJavaThread = javaThread;
    65             currentLispThread = lispThread;
    66         }
    67         return lispThread;
    68     }
    69 
    70     private static void put(Thread javaThread, LispThread lispThread)
    71     {
    72         synchronized (lock) {
    73             WeakHashMap<Thread,LispThread> m = new WeakHashMap<Thread,LispThread>(map);
    74             m.put(javaThread, lispThread);
    75             map = m;
    76         }
    77     }
    78 
    79     public static void remove(Thread javaThread)
    80     {
    81         synchronized (lock) {
    82             WeakHashMap<Thread,LispThread> m = new WeakHashMap<Thread,LispThread>(map);
    83             m.remove(javaThread);
    84             map = m;
    85         }
    86     }
    87 
    88     private final Thread javaThread;
     60        return threads.get();
     61    }
     62
     63   private final Thread javaThread;
    8964    private boolean destroyed;
    9065    private final LispObject name;
     
    12297                }
    12398                finally {
    124                     remove(javaThread);
     99                    // make sure the thread is *always* removed from the hash again
     100                    map.remove(Thread.currentThread());
    125101                }
    126102            }
    127103        };
    128104        javaThread = new Thread(r);
    129         put(javaThread, this);
    130105        this.name = name;
    131106        javaThread.setDaemon(true);
Note: See TracChangeset for help on using the changeset viewer.