Update of /cvsroot/freenet/freenet/src/freenet/thread In directory sc8-pr-cvs1:/tmp/cvs-serv22073/src/freenet/thread
Modified Files: QThreadFactory.java Log Message: More locking improvements. -Moved KillSurplusConnections to a thread of it's own, this is in the hopes of reducing contention for the highly contested lru lock in OpenConnectionManager -Completely redid locking in QThreadFactory, locking the whole class for most of the operations in here didn't make sense, so I used several different locks to ensure synchronization w/o blocking threads trying to return themselves (Committed at Zab's request) Index: QThreadFactory.java =================================================================== RCS file: /cvsroot/freenet/freenet/src/freenet/thread/QThreadFactory.java,v retrieving revision 1.31 retrieving revision 1.32 diff -u -r1.31 -r1.32 --- QThreadFactory.java 26 Sep 2003 01:50:43 -0000 1.31 +++ QThreadFactory.java 26 Sep 2003 02:02:09 -0000 1.32 @@ -27,11 +27,14 @@ private final ThreadGroup tg; + private final CountLock countLock = new CountLock(); private int active = 0; private int available = 0; + private final NumLock numLock = new NumLock(); private long threadNumber = 0; + private final HeadLock headLock = new HeadLock(); private QThread headerThread = null; private final Object maxLock = new Object(); @@ -49,31 +52,50 @@ while (true) { Throwable lastEx = null; try { + boolean adjust=false; int desired=Integer.MAX_VALUE; while ( true ) { - synchronized(this) { + synchronized(countLock) { if ( desired != Integer.MAX_VALUE || - available < MINIMUM_AVAILABLE_ABS || + available < MINIMUM_AVAILABLE_ABS || available < active * MINIMUM_AVAILABLE_RATIO ) { desired = Math.min(Math.max((int) (active * IDEAL_AVAILABLE_RATIO), 2 * MINIMUM_AVAILABLE_ABS),desired); if ( available < desired || - available < active * MINIMUM_AVAILABLE_RATIO ) { - createThread(); - } else break; - } else break; + available < active * MINIMUM_AVAILABLE_RATIO ) { + adjust=true;; + } else { + try { + long start = System.currentTimeMillis(); + countLock.wait(500); + if ( System.currentTimeMillis() < start + 500 ) + continue; + } catch ( InterruptedException ie ) {} + break; + } + } else { + try { + long start = System.currentTimeMillis(); + countLock.wait(500); + if ( System.currentTimeMillis() < start + 500 ) + continue; + } catch ( InterruptedException ie ) {} + break; + } } + createThread(); } Core.logger.log(this,"Thread creation thread past creation loop, available: " + available + ", desired: " + desired + ", active: " + active, Core.logger.DEBUG); + adjust=false; desired=0; while ( true ) { - synchronized(this) { + synchronized(countLock) { if ( desired != 0 || - ( available > (3 * MINIMUM_AVAILABLE_ABS) && + ( available > (3 * MINIMUM_AVAILABLE_ABS) && available > active * MAXIMUM_AVAILABLE_RATIO ) ) { desired = @@ -82,22 +104,23 @@ if ( available > desired || - available > active * MAXIMUM_AVAILABLE_RATIO ) { - destroyThread(); - } else break; - } else break; + available > active * MAXIMUM_AVAILABLE_RATIO ) { + adjust=true; + } else { + try { countLock.wait(500); } catch ( InterruptedException ie ) {} + break; + } + } else { + try { countLock.wait(500); } catch ( InterruptedException ie ) {} + break; + } } + destroyThread(); } Core.logger.log(this,"Thread creation thread past deletion loop, available: " + available + ", desired: " + desired + ", active: " + active, Core.logger.DEBUG); - try { - synchronized(this) { - wait(1000); - } - } catch (InterruptedException e) { - } } catch (Throwable e) { if (lastEx == null || !lastEx.getClass().equals(e.getClass())) Core.logger.log(this, "Exception in QThreadFactory. " @@ -137,19 +160,30 @@ /** * @param job The job to be executed */ - public synchronized final Thread getThread(Runnable job) { - - // hopefully this will not happen often. - if (headerThread == null) { - createThread(); + public final Thread getThread(Runnable job) { + boolean gotHead; + QThread thread=null; + synchronized(headLock) { + // hopefully this will not happen often. + if (headerThread == null) { + gotHead=false; + } else { + gotHead=true; + thread = headerThread; + headerThread = headerThread.next; + } + } + if (!gotHead) { + synchronized(numLock) { + thread = new QThread(++threadNumber); + } } - - QThread thread = headerThread; - headerThread = headerThread.next; thread.next = null; thread.job = job; - ++active; - --available; + synchronized(countLock) { + active++; + available-=gotHead?1:0; + } thread.start(); awaken(); @@ -159,39 +193,59 @@ /** * Creates a thread and adds it to the stack. */ - private synchronized final void createThread() { - QThread newThread = new QThread(++threadNumber); - newThread.next = headerThread; - headerThread = newThread; - available++; + private final void createThread() { + QThread newThread; + synchronized(numLock) { + newThread = new QThread(++threadNumber); + } + synchronized(headLock) { + newThread.next = headerThread; + headerThread = newThread; + } + synchronized(countLock) { + available++; + } } /** * Removes a thread from the stack and signals it to die. */ - private synchronized final void destroyThread() { - QThread dyingThread = headerThread; - headerThread = headerThread.next; - dyingThread.die(); - available--; + private final void destroyThread() { + QThread dyingThread; + synchronized(headLock) { + dyingThread = headerThread; + headerThread = headerThread.next; + } + if ( dyingThread != null ) { + dyingThread.die(); + } + synchronized(countLock) { + available--; + } } /** * Returns a thread to the stack when it is finished executing. */ - private synchronized final void returnThread(QThread returnThread) { - returnThread.next = headerThread; - headerThread = returnThread; - active--; - available++; + private final void returnThread(QThread returnThread) { + synchronized(headLock) { + returnThread.next = headerThread; + headerThread = returnThread; + } + synchronized(countLock) { + active--; + available++; + } } private synchronized final void awaken() { - if ( ( available < MINIMUM_AVAILABLE_ABS) || - ( available < active * MINIMUM_AVAILABLE_RATIO) || - ( ( available > (3 * MINIMUM_AVAILABLE_ABS)) && + synchronized(countLock) { + if ( ( available < MINIMUM_AVAILABLE_ABS) || + ( available < active * MINIMUM_AVAILABLE_RATIO) || + ( ( available > (3 * MINIMUM_AVAILABLE_ABS)) && ( available > active * MAXIMUM_AVAILABLE_RATIO))) { - notifyAll(); + notifyAll(); + } } } @@ -269,6 +323,10 @@ } } } + + private class NumLock {} + private class HeadLock {} + private class CountLock {} } _______________________________________________ cvs mailing list [EMAIL PROTECTED] http://dodo.freenetproject.org/cgi-bin/mailman/listinfo/cvs