Commit: fa5fe58f486b74da10fed3cb378077731e6131d4
Author: Matt Ficken <v-maf...@microsoft.com> Tue, 17 Sep 2013
12:47:12 -0700
Parents: ff0d9ac940eeab1925297ff2eb9a81355604b3ca
Branches: master
Link:
http://git.php.net/?p=pftt2.git;a=commitdiff;h=fa5fe58f486b74da10fed3cb378077731e6131d4
Log:
thread pool support windows hack
Changed paths:
M src/com/mostc/pftt/runner/AbstractLocalTestPackRunner.java
M src/com/mostc/pftt/runner/BuiltinWebHttpPhptTestCaseRunner.java
M src/com/mostc/pftt/runner/HttpPhptTestCaseRunner.java
M src/com/mostc/pftt/scenario/BuiltinWebServerScenario.java
M src/com/mostc/pftt/util/TimerUtil.java
diff --git a/src/com/mostc/pftt/runner/AbstractLocalTestPackRunner.java
b/src/com/mostc/pftt/runner/AbstractLocalTestPackRunner.java
index bbe4a3d..1f9de53 100644
--- a/src/com/mostc/pftt/runner/AbstractLocalTestPackRunner.java
+++ b/src/com/mostc/pftt/runner/AbstractLocalTestPackRunner.java
@@ -180,7 +180,10 @@ public abstract class AbstractLocalTestPackRunner<A
extends ActiveTestPack, S ex
return null;
}
//
- cm.println(EPrintType.CLUE, getClass(), "Scenario Set:
"+scenario_set_setup.getNameWithVersionInfo());
+ if (scenario_set_setup!=null)
+ cm.println(EPrintType.CLUE, getClass(), "Scenario Set:
"+scenario_set_setup.getNameWithVersionInfo());
+ else if (scenario_set!=null)
+ cm.println(EPrintType.CLUE, getClass(), "Scenario Set:
"+scenario_set.getName());
setupStorageAndTestPack(storage_dir, test_cases);
return storage_dir;
diff --git a/src/com/mostc/pftt/runner/BuiltinWebHttpPhptTestCaseRunner.java
b/src/com/mostc/pftt/runner/BuiltinWebHttpPhptTestCaseRunner.java
index 6f9e8c4..7a82e66 100644
--- a/src/com/mostc/pftt/runner/BuiltinWebHttpPhptTestCaseRunner.java
+++ b/src/com/mostc/pftt/runner/BuiltinWebHttpPhptTestCaseRunner.java
@@ -22,6 +22,7 @@ import com.mostc.pftt.results.ITestResultReceiver;
import com.mostc.pftt.runner.LocalPhptTestPackRunner.PhptThread;
import com.mostc.pftt.scenario.BuiltinWebServerScenario;
import com.mostc.pftt.scenario.ScenarioSetSetup;
+import com.mostc.pftt.util.TimerUtil;
public class BuiltinWebHttpPhptTestCaseRunner extends HttpPhptTestCaseRunner {
@@ -57,13 +58,13 @@ public class BuiltinWebHttpPhptTestCaseRunner extends
HttpPhptTestCaseRunner {
final Socket s = test_socket;
if (s==null)
return;
- new Thread() {
+ TimerUtil.runThread(new Runnable() {
public void run() {
try {
s.close();
} catch ( Exception ex ) {}
}
- };
+ });
test_socket = null;
}
diff --git a/src/com/mostc/pftt/runner/HttpPhptTestCaseRunner.java
b/src/com/mostc/pftt/runner/HttpPhptTestCaseRunner.java
index fafcd4f..3390bfc 100644
--- a/src/com/mostc/pftt/runner/HttpPhptTestCaseRunner.java
+++ b/src/com/mostc/pftt/runner/HttpPhptTestCaseRunner.java
@@ -304,13 +304,13 @@ public class HttpPhptTestCaseRunner extends
AbstractPhptTestCaseRunner2 {
final Socket s = test_socket;
if (s==null)
return;
- new Thread() {
+ TimerUtil.runThread(new Runnable() {
public void run() {
try {
s.close();
} catch ( Exception ex ) {}
}
- };
+ });
test_socket = null;
}
diff --git a/src/com/mostc/pftt/scenario/BuiltinWebServerScenario.java
b/src/com/mostc/pftt/scenario/BuiltinWebServerScenario.java
index 287a955..2f4f55c 100644
--- a/src/com/mostc/pftt/scenario/BuiltinWebServerScenario.java
+++ b/src/com/mostc/pftt/scenario/BuiltinWebServerScenario.java
@@ -65,12 +65,12 @@ public class BuiltinWebServerScenario extends
WebServerScenario {
@Override
public int getApprovedInitialThreadPoolSize(AHost host, int threads) {
// XXX update this calculation from time to time as this web
server's performance improves (probably decrease number)
- return host.getCPUCount() * 6;//8;
+ return host.getCPUCount() * 4;
}
@Override
public int getApprovedMaximumThreadPoolSize(AHost host, int threads) {
- return host.getCPUCount() * 8;// TODO 10;
+ return host.getCPUCount() * 6;
}
@Override
diff --git a/src/com/mostc/pftt/util/TimerUtil.java
b/src/com/mostc/pftt/util/TimerUtil.java
index cd5dc70..cfe073b 100644
--- a/src/com/mostc/pftt/util/TimerUtil.java
+++ b/src/com/mostc/pftt/util/TimerUtil.java
@@ -1,11 +1,104 @@
package com.mostc.pftt.util;
import java.lang.Thread.UncaughtExceptionHandler;
+import java.util.LinkedList;
import java.util.concurrent.atomic.AtomicBoolean;
+import com.mostc.pftt.host.LocalHost;
import com.mostc.pftt.results.ConsoleManager;
public final class TimerUtil {
+
+ private static LinkedList<ThreadRunnableProxy> trp_pool = new
LinkedList<ThreadRunnableProxy>();
+ static {
+ final int pool_size = Math.max(128, new
LocalHost().getCPUCount() * 16);
+ for ( int i = 0 ; i < pool_size ; i++ ) {
+ ThreadRunnableProxy trp = new ThreadRunnableProxy();
+ new Thread(trp).start();
+ synchronized(trp_pool) {
+ trp_pool.add(trp);
+ }
+ }
+ }
+
+ private static class ThreadRunnableProxy implements Runnable {
+ private Runnable r;
+ private final Object lock = new Object();
+ private Thread thread;
+ private boolean run = true;
+
+ private void setRunnable(Runnable r) {
+ this.r = r;
+ synchronized(lock) {
+ lock.notify();
+ }
+ }
+
+ @SuppressWarnings("unused")
+ private void stop() {
+ run = false;
+ }
+
+ public void run() {
+ thread = Thread.currentThread();
+ while(run) {
+ if (r!=null) {
+ try {
+ r.run();
+ } catch (Throwable t) {
+
thread.getUncaughtExceptionHandler().uncaughtException(thread, t);
+ }
+ r = null;
+ synchronized(trp_pool) {
+ trp_pool.add(this);
+ }
+ }
+ try {
+ synchronized(lock) {
+ lock.wait();
+ }
+ } catch ( Throwable t ) {
+ try {
+ Thread.sleep(100);
+ } catch ( InterruptedException i ) {}
+ }
+ }
+ }
+ } // end private static class ThreadRunnableProxy
+
+ /** Windows, at least, has problems creating threads late in some test
runs sometimes.
+ *
+ * Creating a thread requires getting a handle, and sometimes if
Windows has allocated too
+ * many handles, it will wait a long time before allocating more, which
delays thread creation
+ * (which in turn can delay things like killing off timed out
processes, which in turn frees up handles).
+ *
+ * Instead, a bunch of threads are preallocated in a pool at startup.
This gets one of
+ * those threads and has it run the given Runnable.
+ *
+ * Note: you may not call #start or #setDaemon on the returned Thread.
you will get an IllegalThreadStateException if you do.
+ *
+ * @param r
+ * @return
+ */
+ public static Thread runThread(Runnable r) {
+ ThreadRunnableProxy trp = null;
+ synchronized(trp_pool) {
+ if (!trp_pool.isEmpty())
+ trp = trp_pool.removeLast();
+ }
+ if (trp==null) {
+ return new Thread(r);
+ } else {
+ trp.setRunnable(r);
+ return trp.thread;
+ }
+ }
+
+ public static Thread runThread(String prefix, Runnable r) {
+ Thread t = runThread(r);
+ t.setName(prefix);
+ return t;
+ }
public interface ObjectRunnable<E extends Object> {
E run() throws Exception;
@@ -19,12 +112,9 @@ public final class TimerUtil {
public static <E extends Object> WaitableRunnable<E>
runWaitSeconds(String name_prefix, int seconds, ObjectRunnable<E> or) {
WaitableRunnable<E> wr = new WaitableRunnable<E>(or);
- Thread t = new Thread(wr);
+ Thread t = runThread(name_prefix, wr);
t.setUncaughtExceptionHandler(IGNORE);
- t.setDaemon(true);
- t.setName(name_prefix+t.getName());
wr.t = t;
- t.start();
wr.block(seconds);
return wr;
}
@@ -111,10 +201,14 @@ public final class TimerUtil {
public interface RepeatingRunnable {
public void run(RepeatingThread thread);
}
+
+ protected static void createRThread(RepeatingOrTimingThread t) {
+ t.t = runThread("Timer", (Runnable)t);
+ }
public static RepeatingThread repeatEverySeconds(int seconds,
RepeatingRunnable r) {
RepeatingThread t = new RepeatingThread(seconds, r);
- t.start();
+ createRThread(t);
return t;
}
@@ -148,7 +242,7 @@ public final class TimerUtil {
} else {
t = new TimerThread2SX(seconds1, r1, seconds2,
runnables2);
}
- t.start();
+ createRThread(t);
return t;
}
@@ -178,11 +272,11 @@ public final class TimerUtil {
@Override
protected void fire2() {
- new Thread() {
+ runThread(new Runnable() {
public void run() {
b2.run();
}
- }.start();
+ });
a2.run();
}
@@ -203,12 +297,12 @@ public final class TimerUtil {
for ( int i=1 ; i < runnables2.length ; i++ ) {
final Runnable r = runnables2[i];
- new Thread() {
+ runThread(new Runnable() {
@Override
public void run() {
r.run();
}
- }.start();
+ });
}
runnables2[0].run();
}
@@ -267,7 +361,7 @@ public final class TimerUtil {
} else {
t = new TimerThreadX(seconds, runnables);
}
- t.start();
+ createRThread(t);
return t;
}
@@ -297,11 +391,11 @@ public final class TimerUtil {
@Override
protected void fire() {
- new Thread() {
+ runThread(new Runnable() {
public void run() {
b.run();
}
- }.start();
+ });
a.run();
}
@@ -322,12 +416,12 @@ public final class TimerUtil {
for ( int i=1 ; i < runnables.length ; i++ ) {
final Runnable r = runnables[i];
- new Thread() {
+ runThread(new Runnable() {
@Override
public void run() {
r.run();
}
- }.start();
+ });
}
runnables[0].run();
}
@@ -361,24 +455,23 @@ public final class TimerUtil {
}
- protected static class RepeatingOrTimingThread extends Thread
implements IClosable {
+ protected static abstract class RepeatingOrTimingThread implements
Runnable, IClosable {
protected final int seconds;
protected final AtomicBoolean b, sleeping;
+ protected Thread t;
public RepeatingOrTimingThread(int seconds) {
this.seconds = seconds;
b = new AtomicBoolean(false);
sleeping = new AtomicBoolean(false);
- setName("Timer"+getName());
- setDaemon(true);
}
public void close() {
b.set(true);
if (sleeping.get()) {
// interrupt #sleep not #fire
- RepeatingOrTimingThread.this.interrupt();
+ t.interrupt();
}
}
--
PHP Quality Assurance Mailing List <http://www.php.net/>
To unsubscribe, visit: http://www.php.net/unsub.php