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