Skip to main content

[faban-commits] [faban~source:c687fdea] Merge branch 'master' of ssh://git.java.net/faban~source

  • From: yaominchen@...
  • To: commits@...
  • Subject: [faban-commits] [faban~source:c687fdea] Merge branch 'master' of ssh://git.java.net/faban~source
  • Date: Tue, 6 Dec 2011 00:59:30 +0000

Project:    faban
Repository: source
Revision:   c687fdead415cc93856cc0dd67817c9da777aed4
Author:     yaominchen
Date:       2011-12-06 00:54:55 UTC
Link:       

Log Message:
------------
Fix for FABAN-1 - JAVA_HOME flag in the Faban UI is not propagated to drivers
Merge branch 'master' of ssh://git.java.net/faban~source


Revisions:
----------
3c7788a8ee3b1ddfc7cc81c4f1c95fed1c87de3c
c687fdead415cc93856cc0dd67817c9da777aed4


Modified Paths:
---------------
harness/src/com/sun/faban/harness/engine/CmdService.java
common/src/com/sun/faban/common/CommandHandleImpl.java
common/src/com/sun/faban/common/FabanNamespaceContext.java
common/src/com/sun/faban/common/FabanShell.java
common/src/com/sun/faban/common/FileTransfer.java
common/src/com/sun/faban/common/NameValuePair.java
common/src/com/sun/faban/common/ParamReader.java
common/src/com/sun/faban/common/RegistryImpl.java
common/src/com/sun/faban/common/RegistryLocator.java
common/src/com/sun/faban/common/SortableTableModel.java
common/src/com/sun/faban/common/TextTable.java
common/src/com/sun/faban/common/Utilities.java
common/test/com/sun/faban/common/UtilitiesTest.java
driver/src/com/sun/faban/driver/BenchmarkDefinition.java
driver/src/com/sun/faban/driver/BenchmarkDriver.java
driver/src/com/sun/faban/driver/HttpTransport.java
driver/src/com/sun/faban/driver/engine/AgentImpl.java
driver/src/com/sun/faban/driver/engine/AgentThread.java
driver/src/com/sun/faban/driver/engine/BenchmarkDefinition.java
driver/src/com/sun/faban/driver/engine/Cycle.java
driver/src/com/sun/faban/driver/engine/CycleThread.java
driver/src/com/sun/faban/driver/engine/DriverContext.java
driver/src/com/sun/faban/driver/engine/FixedSequence.java
driver/src/com/sun/faban/driver/engine/FixedTime.java
driver/src/com/sun/faban/driver/engine/FlatMix.java
driver/src/com/sun/faban/driver/engine/FlatSequenceMix.java
driver/src/com/sun/faban/driver/engine/MasterImpl.java
driver/src/com/sun/faban/driver/engine/MatrixMix.java
driver/src/com/sun/faban/driver/engine/Metrics.java
driver/src/com/sun/faban/driver/engine/Mix.java
driver/src/com/sun/faban/driver/engine/NegativeExponential.java
driver/src/com/sun/faban/driver/engine/NullContext.java
driver/src/com/sun/faban/driver/engine/Result.java
driver/src/com/sun/faban/driver/engine/RunInfo.java
driver/src/com/sun/faban/driver/engine/RuntimeMetrics.java
driver/src/com/sun/faban/driver/engine/TimeThread.java
driver/src/com/sun/faban/driver/engine/TimeThreadWithBackground.java
driver/src/com/sun/faban/driver/engine/Uniform.java
driver/src/com/sun/faban/driver/engine/VariableLoadHandler.java
driver/src/com/sun/faban/driver/engine/VariableLoadHandlerThread.java
driver/src/com/sun/faban/driver/transport/asynchronous/JMSPointToPoint.java
driver/src/com/sun/faban/driver/transport/asynchronous/MessageCacheTraceRegistry.java
driver/src/com/sun/faban/driver/transport/hc3/AboveTimedSSLSocketFactory.java
driver/src/com/sun/faban/driver/transport/hc3/ApacheHC3Transport.java
driver/src/com/sun/faban/driver/transport/hc3/BelowTimedSSLSocketFactory.java
driver/src/com/sun/faban/driver/transport/hc3/FabanCookieSpec.java
driver/src/com/sun/faban/driver/transport/hc3/ProtocolTimedSocketFactory.java
driver/src/com/sun/faban/driver/transport/sunhttp/HttpClient.java
driver/src/com/sun/faban/driver/transport/sunhttp/SunHttpTransport.java
driver/src/com/sun/faban/driver/transport/sunhttp/ThreadCookieHandler.java
driver/src/com/sun/faban/driver/transport/sunhttp/URLStreamHandlerFactory.java
driver/src/com/sun/faban/driver/transport/util/MultipleTransport.java
driver/src/com/sun/faban/driver/transport/util/TimedSocket.java
driver/src/com/sun/faban/driver/transport/util/TimedSocketFactory.java
driver/src/com/sun/faban/driver/transport/util/TimedSocketWrapperFactory.java
driver/src/com/sun/faban/driver/util/ContentSizeStats.java
driver/src/com/sun/faban/driver/util/FabanHTTPBench.java
driver/src/com/sun/faban/driver/util/PairwiseAggregator.java
driver/src/com/sun/faban/driver/util/PlotServer.java
driver/src/com/sun/faban/driver/util/Timer.java
driver/src/com/sun/faban/driver/util/timermeter/CommonUtilities.java
driver/src/com/sun/faban/driver/util/timermeter/MeasurementGroupsCluster.java
driver/src/com/sun/faban/driver/util/timermeter/StatisticalDescription.java
driver/src/com/sun/faban/driver/util/timermeter/TimerCharacterisation.java
driver/src/com/sun/faban/driver/util/timermeter/TimerMeter.java
driver/test/com/sun/faban/driver/engine/MetricsTest.java
driver/test/com/sun/faban/driver/util/PairwiseAggregatorTest.java
harness/src/com/sun/faban/harness/DefaultFabanBenchmark.java
harness/src/com/sun/faban/harness/DefaultFabanBenchmark2.java
harness/src/com/sun/faban/harness/FabanHostUnknownException.java
harness/src/com/sun/faban/harness/WildcardFileFilter.java
harness/src/com/sun/faban/harness/agent/AgentSocketFactory.java
harness/src/com/sun/faban/harness/agent/CmdAgentImpl.java
harness/src/com/sun/faban/harness/agent/FileAgentImpl.java
harness/src/com/sun/faban/harness/agent/FileServiceException.java
harness/src/com/sun/faban/harness/agent/FileServiceImpl.java
harness/src/com/sun/faban/harness/agent/OracleAgentImpl.java
harness/src/com/sun/faban/harness/agent/RMIClassLoaderProvider.java
harness/src/com/sun/faban/harness/agent/RemoteLogFormatter.java
harness/src/com/sun/faban/harness/agent/ToolAgentImpl.java
harness/src/com/sun/faban/harness/common/BenchmarkDescription.java
harness/src/com/sun/faban/harness/common/Run.java
harness/src/com/sun/faban/harness/common/RunId.java
harness/src/com/sun/faban/harness/engine/AnnotationBenchmarkWrapper.java
harness/src/com/sun/faban/harness/engine/ApacheHttpdService.java
harness/src/com/sun/faban/harness/engine/GenericBenchmark.java
harness/src/com/sun/faban/harness/engine/GlassfishService.java
harness/src/com/sun/faban/harness/engine/InitFilter.java
harness/src/com/sun/faban/harness/engine/LighttpdService.java
harness/src/com/sun/faban/harness/engine/LoginConfiguration.java
harness/src/com/sun/faban/harness/engine/MysqlService.java
harness/src/com/sun/faban/harness/engine/OracleService.java
harness/src/com/sun/faban/harness/engine/RunDaemon.java
harness/src/com/sun/faban/harness/engine/RunEntryException.java
harness/src/com/sun/faban/harness/engine/RunQ.java
harness/src/com/sun/faban/harness/formsgen/DriverConfigElement.java
harness/src/com/sun/faban/harness/formsgen/ElementHandler.java
harness/src/com/sun/faban/harness/formsgen/GenericElement.java
harness/src/com/sun/faban/harness/formsgen/HostConfigElement.java
harness/src/com/sun/faban/harness/formsgen/RunControlElement.java
harness/src/com/sun/faban/harness/formsgen/ServiceElement.java
harness/src/com/sun/faban/harness/formsgen/ThreadStartElement.java
harness/src/com/sun/faban/harness/formsgen/XformsGenerator.java
harness/src/com/sun/faban/harness/formsgen/XformsHandler.java
harness/src/com/sun/faban/harness/formsgen/XformsUtil.java
harness/src/com/sun/faban/harness/logging/Acceptor.java
harness/src/com/sun/faban/harness/logging/FlexBuffer.java
harness/src/com/sun/faban/harness/logging/Listener.java
harness/src/com/sun/faban/harness/logging/LogHandler.java
harness/src/com/sun/faban/harness/logging/LogServer.java
harness/src/com/sun/faban/harness/logging/PrimaryListener.java
harness/src/com/sun/faban/harness/logging/RequestProxy.java
harness/src/com/sun/faban/harness/logging/XMLFormatter.java
harness/src/com/sun/faban/harness/security/Permission.java
harness/src/com/sun/faban/harness/tools/Collector.java
harness/src/com/sun/faban/harness/tools/Cpustat.java
harness/src/com/sun/faban/harness/tools/GenericTool.java
harness/src/com/sun/faban/harness/tools/Jvmstat.java
harness/src/com/sun/faban/harness/tools/Lockstat.java
harness/src/com/sun/faban/harness/tools/MemcacheStats.java
harness/src/com/sun/faban/harness/tools/Mysqlstats.java
harness/src/com/sun/faban/harness/tools/OracleTool.java
harness/src/com/sun/faban/harness/tools/Statit.java
harness/src/com/sun/faban/harness/tools/Statspack.java
harness/src/com/sun/faban/harness/tools/ToolWrapper.java
harness/src/com/sun/faban/harness/util/CmdMap.java
harness/src/com/sun/faban/harness/util/DeployTask.java
harness/src/com/sun/faban/harness/util/InterfaceProbe.java
harness/src/com/sun/faban/harness/webclient/Authenticator.java
harness/src/com/sun/faban/harness/webclient/CLIServlet.java
harness/src/com/sun/faban/harness/webclient/Deployer.java
harness/src/com/sun/faban/harness/webclient/LogParseHandler.java
harness/src/com/sun/faban/harness/webclient/LogReader.java
harness/src/com/sun/faban/harness/webclient/RecordHandler.java
harness/src/com/sun/faban/harness/webclient/RunAnalyzer.java
harness/src/com/sun/faban/harness/webclient/RunResult.java
harness/src/com/sun/faban/harness/webclient/RunRetriever.java
harness/src/com/sun/faban/harness/webclient/RunUploader.java
harness/src/com/sun/faban/harness/webclient/TableHandler.java
harness/src/com/sun/faban/harness/webclient/TagEngine.java
harness/src/com/sun/faban/harness/webclient/XFormServlet.java
harness/test/com/sun/faban/harness/webclient/TagEngineTest.java
harness/web/targetlist.jsp
stage/master/bin/startup.sh


Added Paths:
------------
driver/src/com/sun/faban/driver/AgentFinal.java
driver/src/com/sun/faban/driver/AgentInit.java


Diffs:
------
diff --git a/harness/src/com/sun/faban/harness/engine/CmdService.java 
b/harness/src/com/sun/faban/harness/engine/CmdService.java
index e196f5f..64b765b 100644
--- a/harness/src/com/sun/faban/harness/engine/CmdService.java
+++ b/harness/src/com/sun/faban/harness/engine/CmdService.java
@@ -210,7 +210,7 @@ final public class CmdService {     // The final keyword 
prevents clones
      */
     public boolean setup(String benchName, ParamRepository par) {
 
-        String home = par.getParameter("fh:jvmConfig/fh:home");
+        String home = par.getParameter("fh:jvmConfig/fh:javaHome");
 
         if (home != null)
             home = home.trim();
diff --git a/common/src/com/sun/faban/common/CommandHandleImpl.java 
b/common/src/com/sun/faban/common/CommandHandleImpl.java
index bb1706e..7a54200 100644
--- a/common/src/com/sun/faban/common/CommandHandleImpl.java
+++ b/common/src/com/sun/faban/common/CommandHandleImpl.java
@@ -67,6 +67,7 @@ public class CommandHandleImpl implements CommandHandle {
      *
      * @return The command string executed.
      */    
+    @Override
     public String getCommandString() {
         return command.toString();
     }
@@ -74,6 +75,7 @@ public class CommandHandleImpl implements CommandHandle {
     /**
      * Forfully terminates the command.
      */    
+    @Override
     public void destroy() {
         command.killed = true;
         command.process.destroy();
@@ -84,6 +86,7 @@ public class CommandHandleImpl implements CommandHandle {
      *
      * @throws InterruptedException The waiting thread got interrupted
      */
+    @Override
     public void waitFor() throws InterruptedException {
         // Wait for the process to terminate
         command.process.waitFor();
@@ -101,6 +104,7 @@ public class CommandHandleImpl implements CommandHandle {
      * @param timeout The time out
      * @throws InterruptedException The waiting thread got interrupted.
      */
+    @Override
     public void waitFor(int timeout) throws InterruptedException {
         long t = System.currentTimeMillis();
         long dt = 0l;
@@ -146,6 +150,7 @@ public class CommandHandleImpl implements CommandHandle {
      *
      * @return The exit value of the command
      */
+    @Override
     public int exitValue() {
         return command.process.exitValue();
     }
@@ -156,6 +161,7 @@ public class CommandHandleImpl implements CommandHandle {
      * @return The output from stdout or stderr, or null if there is no 
output
      * @throws IOException There is an error getting the output
      */
+    @Override
     public byte[] fetchOutput(int streamId) throws IOException {
         if (command.streamHandling[streamId] == Command.TRICKLE_LOG)
             throw new IllegalStateException("Output not available if " +
@@ -178,6 +184,7 @@ public class CommandHandleImpl implements CommandHandle {
      * @throws IllegalStateException    The command is not yet terminated or
      *                                  does not record output
      */
+    @Override
     public FileTransfer fetchOutput(int streamId, String destFile)
             throws IOException, IllegalStateException {
         if (command.streamHandling[streamId] == Command.TRICKLE_LOG)
@@ -246,6 +253,7 @@ public class CommandHandleImpl implements CommandHandle {
             start();
         }
 
+        @Override
         public void run() {
             logger.log(Level.FINEST, "{0} ReaderThread started.", 
Command.STREAM_NAME[streamId]);
 
@@ -447,7 +455,7 @@ public class CommandHandleImpl implements CommandHandle {
                 logger.log(Level.FINE, "{0}: Constructing transfer from 
buffer to {1}", new Object[]{this, destFile});
             } else {
                 transfer = new FileTransfer(outputFile, destFile);
-                logger.fine(this + ": Constructing transfer " + outputFile + 
" -> " + destFile);
+                logger.log(Level.FINE, "{0}: Constructing transfer {1} -> 
{2}", new Object[]{this, outputFile, destFile});
             }
             return transfer;
         }
diff --git a/common/src/com/sun/faban/common/FabanNamespaceContext.java 
b/common/src/com/sun/faban/common/FabanNamespaceContext.java
index f8195af..ea5399f 100644
--- a/common/src/com/sun/faban/common/FabanNamespaceContext.java
+++ b/common/src/com/sun/faban/common/FabanNamespaceContext.java
@@ -88,6 +88,7 @@ public class FabanNamespaceContext implements 
NamespaceContext {
         }
     }
 
+    @Override
     public String getNamespaceURI(String prefix) {
         if (prefix == null)
             throw new IllegalArgumentException("prefix is null!");
@@ -98,6 +99,7 @@ public class FabanNamespaceContext implements 
NamespaceContext {
         return namespaceURI;
     }
 
+    @Override
     public String getPrefix(String namespaceURI) {
         if (namespaceURI == null)
             throw new IllegalArgumentException("namespaceURI is null!");
@@ -110,6 +112,7 @@ public class FabanNamespaceContext implements 
NamespaceContext {
     }
 
 
+    @Override
     public Iterator getPrefixes(String namespaceURI) {
         logger.log(Level.FINER, "getPrefixes(\"{0}\")", namespaceURI);
         if (namespaceURI == null)
diff --git a/common/src/com/sun/faban/common/FabanShell.java 
b/common/src/com/sun/faban/common/FabanShell.java
index f358773..a2d226c 100644
--- a/common/src/com/sun/faban/common/FabanShell.java
+++ b/common/src/com/sun/faban/common/FabanShell.java
@@ -54,6 +54,7 @@ public class FabanShell extends Thread {
         start();
     }
 
+    @Override
     public void run() {
         byte[] buffer = new byte[8192];
         try {
diff --git a/common/src/com/sun/faban/common/FileTransfer.java 
b/common/src/com/sun/faban/common/FileTransfer.java
index e575911..8030a56 100644
--- a/common/src/com/sun/faban/common/FileTransfer.java
+++ b/common/src/com/sun/faban/common/FileTransfer.java
@@ -159,6 +159,7 @@ public class FileTransfer implements Externalizable {
         return transferSize;
     }
 
+    @Override
     public void writeExternal(ObjectOutput out) throws IOException {
 
         // Flush headers and the first chunk.
@@ -206,6 +207,7 @@ public class FileTransfer implements Externalizable {
         }
     }
 
+    @Override
     public void readExternal(ObjectInput in)
             throws IOException, ClassNotFoundException {
 
diff --git a/common/src/com/sun/faban/common/NameValuePair.java 
b/common/src/com/sun/faban/common/NameValuePair.java
index 8c8f823..e1fb51d 100644
--- a/common/src/com/sun/faban/common/NameValuePair.java
+++ b/common/src/com/sun/faban/common/NameValuePair.java
@@ -62,6 +62,7 @@ public class NameValuePair<V> implements Serializable {
      * @param o The other NameValuePair
      * @return True if the o equals this object, false otherwise
      */
+    @Override
     public boolean equals(Object o) {
         if (this == o)
             return true;
@@ -84,6 +85,7 @@ public class NameValuePair<V> implements Serializable {
      * Obtains the hash code of this NameValuePair.
      * @return The hash code
      */
+    @Override
     public int hashCode() {
         int result;
         result = (name != null ? name.hashCode() : 0);
diff --git a/common/src/com/sun/faban/common/ParamReader.java 
b/common/src/com/sun/faban/common/ParamReader.java
index a35c729..2f328cc 100644
--- a/common/src/com/sun/faban/common/ParamReader.java
+++ b/common/src/com/sun/faban/common/ParamReader.java
@@ -256,23 +256,6 @@ public class ParamReader {
         return xPath;
     }
 
-    private void printXPath(String xPathExp) {
-        try {
-            String v = xPath.evaluate(xPathExp, root);
-            System.out.println(xPathExp + '=' + v);
-        } catch (XPathExpressionException e) {
-            e.printStackTrace();
-        }
-    }
-
-    private void basicTest() {
-        // Try printing common param file elements
-        printXPath("fh:jvmConfig/fh:javaHome");
-        printXPath("fh:jvmConfig/fh:jvmOptions");
-        printXPath("fa:runConfig/fa:runControl/fa:steadyState");
-        printXPath("fa:runConfig/@definition");
-    }
-
     /**
      * Invokes the ParamReader in conversion mode and actually saves the
      * conversion output to a file.
diff --git a/common/src/com/sun/faban/common/RegistryImpl.java 
b/common/src/com/sun/faban/common/RegistryImpl.java
index 3d779a6..29fc0c6 100644
--- a/common/src/com/sun/faban/common/RegistryImpl.java
+++ b/common/src/com/sun/faban/common/RegistryImpl.java
@@ -115,7 +115,7 @@ public class RegistryImpl extends UnicastRemoteObject 
implements Registry {
     private HashMap<String, HashMap<String, Remote>> servicesTypeTable =
             new HashMap<String, HashMap<String, Remote>>();
 //    private String className;
-    private static Logger logger =
+    private static final Logger logger =
             Logger.getLogger(RegistryImpl.class.getName());
 
     private RegistryImpl() throws RemoteException {
@@ -134,16 +134,15 @@ public class RegistryImpl extends UnicastRemoteObject 
implements Registry {
      * @return true if registration succeeded, false if there is already
      *         an object registered by this name.
      */
+    @Override
     public synchronized boolean register(String name, Remote service) {
 
-        logger.fine("Registry: Registering " + name +
-                " on machine " + getCaller());
+        logger.log(Level.FINE, "Registry: Registering {0} on machine {1}", 
new Object[]{name, getCaller()});
         if (servicesTable.get(name) == null) {
             servicesTable.put(name, service);
             return true;
         } else {
-            logger.fine("Failed registering. Service " + name +
-                        " already exists");
+            logger.log(Level.FINE, "Failed registering. Service {0} already 
exists", name);
             return false;
         }
     }
@@ -161,6 +160,7 @@ public class RegistryImpl extends UnicastRemoteObject 
implements Registry {
      * @return true if registration succeeded, false if there is already
      *         an object registered by this name.
      */
+    @Override
     public synchronized boolean register(String type, String name,
                                          Remote service) {
         if (service == null)
@@ -173,12 +173,10 @@ public class RegistryImpl extends UnicastRemoteObject 
implements Registry {
             h = new HashMap<String, Remote>();
             servicesTypeTable.put(type, h);
         } else if (h.get(name) != null) {
-            logger.fine("Failed registering. Service " + name +
-                        " already exists");
+            logger.log(Level.FINE, "Failed registering. Service {0} already 
exists", name);
             return false;
         }
-        logger.fine("Registry: Registering " + name +
-                " on machine " + getCaller());
+        logger.log(Level.FINE, "Registry: Registering {0} on machine {1}", 
new Object[]{name, getCaller()});
         h.put(name, service);
         return true;
     }
@@ -193,10 +191,10 @@ public class RegistryImpl extends UnicastRemoteObject 
implements Registry {
       * @param name public driverName of service
       * @param service Remote reference to service
       */
+    @Override
     public synchronized void reregister(String name, Remote service)
     {
-        logger.fine("Registry: Registering " + name +
-                " on machine " + getCaller());
+        logger.log(Level.FINE, "Registry: Registering {0} on machine {1}", 
new Object[]{name, getCaller()});
         servicesTable.put(name, service);
     }
 
@@ -210,6 +208,7 @@ public class RegistryImpl extends UnicastRemoteObject 
implements Registry {
       * @param name of service
       * @param service Remote reference to service
       */
+    @Override
     public synchronized void reregister(String type, String name, Remote 
service) {
 
         if (service == null)
@@ -223,8 +222,7 @@ public class RegistryImpl extends UnicastRemoteObject 
implements Registry {
             servicesTypeTable.put(type, h);
         }
 
-        logger.fine("Registry: Registering " + name +
-                " on machine " + getCaller());
+        logger.log(Level.FINE, "Registry: Registering {0} on machine {1}", 
new Object[]{name, getCaller()});
         h.put(name, service);
     }
 
@@ -235,6 +233,7 @@ public class RegistryImpl extends UnicastRemoteObject 
implements Registry {
       * the service exits.
       * @param name public driverName of service
       */
+    @Override
     public synchronized void unregister(String name) {
         servicesTable.remove(name);
     }
@@ -247,13 +246,13 @@ public class RegistryImpl extends UnicastRemoteObject 
implements Registry {
       * @param type of service
       * @param name public driverName of service
       */
+    @Override
     public synchronized void unregister(String type, String name) {
         // First check if the type of service exists
         HashMap<String, Remote> h = servicesTypeTable.get(type);
 
         if (h == null) {
-            logger.warning("Registry.unregister : " +
-                    "Cannot find Service type : " + type);
+            logger.log(Level.WARNING,"Registry.unregister : " + "Cannot find 
Service type : {0}", type);
         }
         else {
             h.remove(name);
@@ -269,6 +268,7 @@ public class RegistryImpl extends UnicastRemoteObject 
implements Registry {
       * @param name public driverName of service
       * @return remote reference
       */
+    @Override
     public synchronized Remote getService(String name) {
         return servicesTable.get(name);
     }
@@ -282,14 +282,14 @@ public class RegistryImpl extends UnicastRemoteObject 
implements Registry {
       * @param name public driverName of service
       * @return remote reference
       */
+    @Override
     public synchronized Remote getService(String type, String name) {
         Remote r = null;
         // First check if the type of service exists
         HashMap<String, Remote> h = servicesTypeTable.get(type);
 
         if (h == null) {
-            logger.warning("Registry.getService : " +
-                    "Cannot find Service type : " + type);
+            logger.log(Level.WARNING,"Registry.getService : " + "Cannot find 
Service type : {0}", type);
         }
         else {
             r = h.get(name);
@@ -305,14 +305,14 @@ public class RegistryImpl extends UnicastRemoteObject 
implements Registry {
       * @param type of service
       * @return remote references
       */
+    @Override
     public synchronized Remote[] getServices(String type) {
         Remote[] r = null;
         // First check if the type of service exists
         HashMap<String, Remote> h = servicesTypeTable.get(type);
 
         if (h == null) {
-            logger.warning("Registry.getServices : " +
-                    "Cannot find Service type : " + type);
+            logger.log(Level.WARNING,"Registry.getServices : " + "Cannot 
find Service type : {0}", type);
         }
         else {
             r = new Remote[h.size()];
@@ -326,13 +326,13 @@ public class RegistryImpl extends UnicastRemoteObject 
implements Registry {
       * @param type of service
       * @return int number of registered services
       */
+    @Override
     public synchronized int getNumServices(String type) {
         // First check if the type of service exists
         HashMap<String, Remote> h = servicesTypeTable.get(type);
         int i = 0;
         if (h == null) {
-            logger.warning("Registry.getNumServices : " +
-                    "Cannot find Service type : " + type);
+            logger.log(Level.WARNING,"Registry.getNumServices : " + "Cannot 
find Service type : {0}", type);
         }
         else {
             i = h.size();
@@ -357,18 +357,19 @@ public class RegistryImpl extends UnicastRemoteObject 
implements Registry {
     /**
      * Kill is called to exit the RMI registry and Registry.
      */
+    @Override
     public void kill() {
         logger.info("Unregistering Services");
 
         for (Iterator<String> iter = servicesTable.keySet().iterator();
              iter.hasNext();) {
-            logger.fine("Unregistering " + iter.next());
+            logger.log(Level.FINE, "Unregistering {0}", iter.next());
             iter.remove();
         }
 
         for (Iterator<String> iter = servicesTypeTable.keySet().iterator();
              iter.hasNext();) {
-            logger.fine("Unregistering " + iter.next());
+            logger.log(Level.FINE, "Unregistering {0}", iter.next());
             iter.remove();
         }
 
@@ -377,6 +378,7 @@ public class RegistryImpl extends UnicastRemoteObject 
implements Registry {
         // *** If the System.exit(0) is called in this method
         // *** the Service will get a RemoteException
         Thread exitThread = new Thread() {
+            @Override
             public void run() {
                 try {
                     Thread.sleep(5000);
@@ -410,8 +412,7 @@ public class RegistryImpl extends UnicastRemoteObject 
implements Registry {
         java.rmi.registry.Registry rmiRegistry = null;
         try {
             rmiRegistry = LocateRegistry.createRegistry(rmiPort);
-            logger.fine("Registry listening on port " +
-                    rmiPort + ".");
+            logger.log(Level.FINE, "Registry listening on port {0}.", 
rmiPort);
         } catch (Exception e) {
             logger.log(Level.SEVERE, "Exception starting registry.", e);
             System.exit(-1);
diff --git a/common/src/com/sun/faban/common/RegistryLocator.java 
b/common/src/com/sun/faban/common/RegistryLocator.java
index 86bb329..a93af98 100644
--- a/common/src/com/sun/faban/common/RegistryLocator.java
+++ b/common/src/com/sun/faban/common/RegistryLocator.java
@@ -96,7 +96,7 @@ public class RegistryLocator {
             throws RemoteException, NotBoundException {
 
         int port = getPort();
-        logger.fine("Obtaining registry at " + master + ':' + port);
+        logger.log(Level.FINE, "Obtaining registry at {0}:{1}", new 
Object[]{master, port});
         java.rmi.registry.Registry rmiRegistry =
                                 LocateRegistry.getRegistry(master, port);
         return (Registry) rmiRegistry.lookup(BIND_NAME);
diff --git a/common/src/com/sun/faban/common/SortableTableModel.java 
b/common/src/com/sun/faban/common/SortableTableModel.java
index acd6e9e..1719b8f 100644
--- a/common/src/com/sun/faban/common/SortableTableModel.java
+++ b/common/src/com/sun/faban/common/SortableTableModel.java
@@ -35,6 +35,7 @@ import java.util.TreeMap;
  * @author Akara Sucharitakul
  */
 public class SortableTableModel extends TableModel {
+
     int sortColumn = -1;
     SortDirection direction = SortDirection.ASCENDING;
     TreeMap<Comparable, ArrayList<Comparable[]>> ascMap;
@@ -64,13 +65,16 @@ public class SortableTableModel extends TableModel {
      */
     public void sort(String columnName, SortDirection direction) {
         int idx;
-        for (idx = 0; idx < headers.length; idx++)
-            if (columnName.equalsIgnoreCase(headers[idx]))
+        for (idx = 0; idx < headers.length; idx++) {
+            if (columnName.equalsIgnoreCase(headers[idx])) {
                 break;
+            }
+        }
 
-        if (idx >= headers.length)
-            throw new IndexOutOfBoundsException("Field \"" + columnName +
-                    "\" not found!");
+        if (idx >= headers.length) {
+            throw new IndexOutOfBoundsException("Field \"" + columnName
+                    + "\" not found!");
+        }
         sort(idx, direction);
     }
 
@@ -98,13 +102,14 @@ public class SortableTableModel extends TableModel {
             // a bottleneck, we can always switch to some other sort 
algorithms.
             TreeMap<Comparable, ArrayList<Comparable[]>> sorterMap;
             if (direction == SortDirection.ASCENDING) {
-                if (ascMap == null)
+                if (ascMap == null) {
                     ascMap = new TreeMap<Comparable, 
ArrayList<Comparable[]>>();
-                else
+                } else {
                     ascMap.clear();
+                }
                 sorterMap = ascMap;
             } else {
-                if (descMap == null)
+                if (descMap == null) {
                     descMap = new TreeMap<Comparable, 
ArrayList<Comparable[]>>(
                             new Comparator<Comparable>() {
 
@@ -112,13 +117,14 @@ public class SortableTableModel extends TableModel {
                                 // Comparable<T> to allow maximum type
                                 // flexibility.
                                 @SuppressWarnings("unchecked")
+                                @Override
                                 public int compare(Comparable c, Comparable 
d) {
                                     return d.compareTo(c);
                                 }
-                            }
-                    );
-                else
+                            });
+                } else {
                     descMap.clear();
+                }
                 sorterMap = descMap;
             }
 
@@ -135,8 +141,9 @@ public class SortableTableModel extends TableModel {
                 chain.add(fields);
             }
             rowList.clear();
-            for (ArrayList<Comparable[]> chain : sorterMap.values())
+            for (ArrayList<Comparable[]> chain : sorterMap.values()) {
                 rowList.addAll(chain);
+            }
 
             sortColumn = column;
             this.direction = direction;
diff --git a/common/src/com/sun/faban/common/TextTable.java 
b/common/src/com/sun/faban/common/TextTable.java
index 946a51c..57a0578 100644
--- a/common/src/com/sun/faban/common/TextTable.java
+++ b/common/src/com/sun/faban/common/TextTable.java
@@ -195,6 +195,7 @@ public class TextTable {
      *
      * @return a formatted string representation of the table.
      */
+    @Override
     public String toString() {
         StringBuilder b = new StringBuilder(8192);
         return format(b).toString();
diff --git a/common/src/com/sun/faban/common/Utilities.java 
b/common/src/com/sun/faban/common/Utilities.java
index 9c85e26..546fea2 100644
--- a/common/src/com/sun/faban/common/Utilities.java
+++ b/common/src/com/sun/faban/common/Utilities.java
@@ -41,6 +41,8 @@ import java.util.regex.Pattern;
  */
 public class Utilities {
 
+    public static final long TO_NANOS = 1000000L;
+
     /** The file separator on the master. */
     public static String masterFileSeparator;
 
diff --git a/common/test/com/sun/faban/common/UtilitiesTest.java 
b/common/test/com/sun/faban/common/UtilitiesTest.java
index 53154eb..1ad7028 100644
--- a/common/test/com/sun/faban/common/UtilitiesTest.java
+++ b/common/test/com/sun/faban/common/UtilitiesTest.java
@@ -6,7 +6,8 @@
 package com.sun.faban.common;
 
 import org.junit.Test;
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
 
 /**
  * Unit tests for the Utilities class.
diff --git a/driver/src/com/sun/faban/driver/AgentFinal.java 
b/driver/src/com/sun/faban/driver/AgentFinal.java
new file mode 100644
index 0000000..f0c2f1d
--- /dev/null
+++ b/driver/src/com/sun/faban/driver/AgentFinal.java
@@ -0,0 +1,51 @@
+/* The contents of this file are subject to the terms
+ * of the Common Development and Distribution License
+ * (the License). You may not use this file except in
+ * compliance with the License.
+ *
+ * You can obtain a copy of the License at
+ * https://faban.dev.java.net/public/CDDLv1.0.html or
+ * install_dir/license.txt
+ * See the License for the specific language governing
+ * permission and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL
+ * Header Notice in each file and include the License file
+ * at faban/src/legal/CDDLv1.0.txt.
+ * If applicable, add the following below the CDDL Header,
+ * with the fields enclosed by brackets [] replaced by
+ * your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ *
+ * $Id$
+ *
+ * Copyright 2005-2009 Sun Microsystems Inc. All Rights Reserved
+ */
+package com.sun.faban.driver;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.lang.annotation.ElementType;
+
+/**
+ * Designates a method to be called by each agent, just after the end of the
+ * benchmark run. It is always called from first thread from each agent.
+ * No other thread will be started until this method finishes. Note that only
+ * one method is allowed for the AgentFinal designation. If Faban finds
+ * more than one method with the AgentFinal annotation, it will throw a
+ * DefinitionException at startup.<p/>
+ * The AgentInit and AgentFinal annotations follow similarly
+ * the design of OnceBefore and OnceAfter annotations which are called by
+ * the first agent only. The AgentInit and AgentFinal
+ * annotations are used mainly for initializing and cleaning up shared 
resources
+ * among the threads of a agent, such as network stack and scratch space.
+ *
+ * @author ychen
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.METHOD)
+public @interface AgentFinal {
+       // marker attribute
+}
+
diff --git a/driver/src/com/sun/faban/driver/AgentInit.java 
b/driver/src/com/sun/faban/driver/AgentInit.java
new file mode 100644
index 0000000..3ad9759
--- /dev/null
+++ b/driver/src/com/sun/faban/driver/AgentInit.java
@@ -0,0 +1,50 @@
+/* The contents of this file are subject to the terms
+ * of the Common Development and Distribution License
+ * (the License). You may not use this file except in
+ * compliance with the License.
+ *
+ * You can obtain a copy of the License at
+ * https://faban.dev.java.net/public/CDDLv1.0.html or
+ * install_dir/license.txt
+ * See the License for the specific language governing
+ * permission and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL
+ * Header Notice in each file and include the License file
+ * at faban/src/legal/CDDLv1.0.txt.
+ * If applicable, add the following below the CDDL Header,
+ * with the fields enclosed by brackets [] replaced by
+ * your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ *
+ * $Id$
+ *
+ * Copyright 2005-2009 Sun Microsystems Inc. All Rights Reserved
+ */
+package com.sun.faban.driver;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.lang.annotation.ElementType;
+
+/**
+ * Designates a method to be called by each agent, just before the start of 
the
+ * benchmark run. It is always called from first thread from each agent.
+ * No other thread will be started until this method finishes. Note that only
+ * one method is allowed for the AgentInit designation. If Faban finds
+ * more than one method with the AgentInit annotation, it will throw a
+ * DefinitionException at startup.<p/>
+ * The AgentInit and AgentFinal annotations follow similarly
+ * the design of OnceBefore and OnceAfter annotations which are called by
+ * the first agent only. The AgentInit and AgentFinal
+ * annotations are used mainly for initializing and cleaning up shared 
resources
+ * among the threads of a agent, such as network stack and scratch space.
+ *
+ * @author ychen
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.METHOD)
+public @interface AgentInit {
+       // marker attribute
+}
diff --git a/driver/src/com/sun/faban/driver/BenchmarkDefinition.java 
b/driver/src/com/sun/faban/driver/BenchmarkDefinition.java
index c467df2..85ea9cd 100644
--- a/driver/src/com/sun/faban/driver/BenchmarkDefinition.java
+++ b/driver/src/com/sun/faban/driver/BenchmarkDefinition.java
@@ -23,7 +23,11 @@
  */
 package com.sun.faban.driver;
 
-import java.lang.annotation.*;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
 
 /**
  * The BenchmarkDefinition annotation defines the benchmark. Only one
diff --git a/driver/src/com/sun/faban/driver/BenchmarkDriver.java 
b/driver/src/com/sun/faban/driver/BenchmarkDriver.java
index d183e3a..6e83cea 100644
--- a/driver/src/com/sun/faban/driver/BenchmarkDriver.java
+++ b/driver/src/com/sun/faban/driver/BenchmarkDriver.java
@@ -23,7 +23,13 @@
  */
 package com.sun.faban.driver;
 
-import java.lang.annotation.*;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
 import java.util.concurrent.TimeUnit;
 
 /**
diff --git a/driver/src/com/sun/faban/driver/HttpTransport.java 
b/driver/src/com/sun/faban/driver/HttpTransport.java
index 6f685cc..3598c91 100644
--- a/driver/src/com/sun/faban/driver/HttpTransport.java
+++ b/driver/src/com/sun/faban/driver/HttpTransport.java
@@ -76,8 +76,7 @@ public class HttpTransport {
             try {
                 bufferSize = Integer.parseInt(bufferSizeString) * multiplier;
                 Logger.getLogger(HttpTransport.class.getName()).
-                        log(Level.INFO, "HTTP buffer size set to " +
-                        bufferSize);
+                        log(Level.INFO, "HTTP buffer size set to {0}", 
bufferSize);
 
             } catch (NumberFormatException e) {
                 Logger.getLogger(HttpTransport.class.getName()).
diff --git a/driver/src/com/sun/faban/driver/engine/AgentImpl.java 
b/driver/src/com/sun/faban/driver/engine/AgentImpl.java
index 4aadd9e..5bf3c5b 100644
--- a/driver/src/com/sun/faban/driver/engine/AgentImpl.java
+++ b/driver/src/com/sun/faban/driver/engine/AgentImpl.java
@@ -53,8 +53,8 @@ import java.util.logging.Logger;
 public class AgentImpl extends UnicastRemoteObject
         implements Agent, Unreferenced, Runnable {
 
-       private static final long serialVersionUID = 1L;
-       static AgentImpl agentImpl;
+    private static final long serialVersionUID = 1L;
+    static AgentImpl agentImpl;
     Master master;
     RunInfo runInfo;
     int driverType;
@@ -78,17 +78,14 @@ public class AgentImpl extends UnicastRemoteObject
     CountDownLatch postRunLatch;
     private boolean runAborted = false;
     StatsCollector statsCollector;
-
     // Time to wake up and switch the number of active threads.
     volatile long loadSwitchTime = 1l;
     // Running threads at given load level.
     // All threads should run at start.
     volatile int runningThreads = Integer.MAX_VALUE;
-
     VariableLoadHandlerThread threadController;
     private long earliestStartTime = Long.MIN_VALUE;
 
-
     /**
      * Constructs the AgentImpl object.
      * @param driverName The type name of the driver to execute
@@ -98,7 +95,7 @@ public class AgentImpl extends UnicastRemoteObject
      */
     AgentImpl(String driverName, String agentId, String master)
             throws Exception {
-        this (driverName, agentId);
+        this(driverName, agentId);
 
         host = InetAddress.getLocalHost().getHostName();
 
@@ -107,16 +104,16 @@ public class AgentImpl extends UnicastRemoteObject
         // do not want that baggage. So we make sure to crop it off.
         // i.e. brazilian.sfbay.Sun.COM should just show as brazilian.
         int dotIdx = host.indexOf('.');
-        if (dotIdx > 0)
+        if (dotIdx > 0) {
             host = host.substring(0, dotIdx);
+        }
 
         RegistryLocator.getRegistry(master).
                 reregister(agentType, agentName, this);
 
-        logger.fine(displayName + " started ...");
+        logger.log(Level.FINE, "{0} started ...", displayName);
     }
 
-
     AgentImpl(String driverName, String agentId) throws RemoteException {
         className = getClass().getName();
         logger = Logger.getLogger(className);
@@ -126,16 +123,17 @@ public class AgentImpl extends UnicastRemoteObject
         this.agentId = agentId;
         Thread.setDefaultUncaughtExceptionHandler(
                 new Thread.UncaughtExceptionHandler() {
+
+                    @Override
                     public void uncaughtException(Thread t, Throwable e) {
-                        logger.log(Level.SEVERE, t.getName() + ": " +
-                                e.getMessage(), e);
+                        logger.log(Level.SEVERE, t.getName() + ": "
+                                + e.getMessage(), e);
                     }
-                }
-        );
+                });
     }
 
     /**
-     * Configures each agents with the properties passed.
+     * Configures each agent with the properties passed.
      * @param master the remote interface to the Master
      * @param runInfo run information passed by Master
      * @param driverType 
@@ -143,7 +141,7 @@ public class AgentImpl extends UnicastRemoteObject
      * @throws RemoteException 
      */
     public void configure(Master master, RunInfo runInfo, int driverType,
-                          Timer timer) throws RemoteException {
+            Timer timer) throws RemoteException {
 
         runAborted = false;
         this.master = master;
@@ -155,23 +153,36 @@ public class AgentImpl extends UnicastRemoteObject
         driverBase = System.getProperty("faban.driver.base");
         if (driverBase == null) {
             File driverJar = Utilities.getJarFile(
-                                    runInfo.driverConfig.driverClass);
-            if (driverJar != null)
-                // Else find with jarpath/..
+                    runInfo.driverConfig.driverClass);
+            if (driverJar != null) // Else find with jarpath/..
+            {
                 driverBase = driverJar.getParentFile().getParent();
+            }
         }
 
         threadStartLatch = new CountDownLatch(runInfo.agentInfo.threads);
         timeSetLatch = new CountDownLatch(1);
         if (runInfo.agentInfo.startThreadNumber == 0) { // first agent
-            if (runInfo.driverConfig.preRun != null) {
-                               preRunLatch = new CountDownLatch(1);
+            if (runInfo.driverConfig.preRunGlobal != null ||
+                    runInfo.driverConfig.preRunLocal != null ) {
+                preRunLatch = new CountDownLatch(1);
                 startLatch = new CountDownLatch(1);
-                       }
-            if (runInfo.driverConfig.postRun != null) {
+            }
+            if (runInfo.driverConfig.postRunGlobal != null ||
+                    runInfo.driverConfig.postRunLocal != null) {
                 finishLatch = new CountDownLatch(1);
-                               postRunLatch = new CountDownLatch(1);
-                       }
+                postRunLatch = new CountDownLatch(1);
+            }
+        }
+        else { // other agents
+            if (runInfo.driverConfig.preRunLocal != null ) {
+                preRunLatch = new CountDownLatch(1);
+                startLatch = new CountDownLatch(1);
+            }
+            if (runInfo.driverConfig.postRunLocal != null) {
+                finishLatch = new CountDownLatch(1);
+                postRunLatch = new CountDownLatch(1);
+            }
         }
         try {
             runInfo.postDeserialize();
@@ -188,10 +199,12 @@ public class AgentImpl extends UnicastRemoteObject
     /**
      * Start all the driver threads.
      */
+    @Override
     public void startThreads() {
         // Agents will Start the threads in parallel if
         // parallelThreadStart is set.
-        if (runInfo.parallelAgentThreadStart) {
+        if (runInfo.parallelAgentThreadStart && 
+            numThreads > 1) {
             // start thread and return
             new Thread(this).start();
         } else {
@@ -220,7 +233,7 @@ public class AgentImpl extends UnicastRemoteObject
             long tm = master.currentTimeMillis();
             long t2 = System.currentTimeMillis();
 
-            int latency  = (int) (t2 - t1);
+            int latency = (int) (t2 - t1);
 
             // Capture the best latency.
             if (latency < minLatency) {
@@ -231,16 +244,12 @@ public class AgentImpl extends UnicastRemoteObject
             try {
                 Thread.sleep(100);
             } catch (InterruptedException e) {
-               logger.fine("Sleep Interrupted: " + e.getMessage());
+                logger.log(Level.FINE, "Sleep Interrupted: {0}", 
e.getMessage());
             }
         }
 
         if (minLatency > 10) {
-            logger.log(Level.SEVERE, "This run may be invalid! Minimum " +
-                    "achieved roundtrip time to master is " + minLatency +
-                    " ms. Latencies beyond 10ms are too high and will impact 
" +
-                    "the accuracy of the run startup and steady state times 
" +
-                    "across driver instances.");
+            logger.log(Level.SEVERE, "This run may be invalid! Minimum 
achieved roundtrip time to master is {0} ms. Latencies beyond 10ms are too 
high and will impact the accuracy of the run startup and steady state times 
across driver instances.", minLatency);
         }
 
         timer.adjustBaseTime(offset + minLatency / 2);
@@ -250,25 +259,26 @@ public class AgentImpl extends UnicastRemoteObject
         numThreads = runInfo.agentInfo.threads;
         agentThreads = new AgentThread[numThreads];
         try {
-            if (runInfo.agentInfo.startThreadNumber == 0 &&
-                    runInfo.driverConfig.preRun != null) {
+            if ( (runInfo.driverConfig.preRunLocal != null) ||
+                    (runInfo.agentInfo.startThreadNumber == 0
+                    && runInfo.driverConfig.preRunGlobal != null) ) {
                 agentThreads[0] = AgentThread.getInstance(agentType, agentId,
-                        0, runInfo.driverConfig.driverClass, timer,
-                        this);
+                        runInfo.agentInfo.startThreadNumber,
+                        runInfo.driverConfig.driverClass, timer, this);
+                logger.log(Level.INFO, "{0}: Starting agent thread " +
+                        " for pre-run processing", displayName);
                 agentThreads[0].start();
                 preRunLatch.await();
                 preRunLatch = null;
 
                 earliestStartTime = System.nanoTime() +
-                        runInfo.msBetweenThreadStart * 1000000L;
+                        runInfo.msBetweenThreadStart * Utilities.TO_NANOS;
             }
             if (runAborted) {
-                logger.warning(displayName +
-                        ": Run aborted starting initial driver threads.");
+                logger.log(Level.WARNING, "{0}: Run aborted starting initial 
driver threads.", displayName);
             }
         } catch (Exception e) {
-            logger.warning(displayName +
-                    ": Run aborted starting initial driver threads.");
+            logger.log(Level.WARNING, "{0}: Run aborted starting initial 
driver threads.", displayName);
             logger.log(Level.SEVERE, e.getMessage(), e);
             try {
                 master.abortRun();
@@ -282,12 +292,12 @@ public class AgentImpl extends UnicastRemoteObject
      * Starts the driver threads for this agent, possibly in it's own thread.
      * @see java.lang.Runnable#run()
      */
+    @Override
     public void run() {
-
         timer.idleTimerCheck(displayName);
 
         // Create the required number of threads
-        long nsBetweenThreadStart = runInfo.msBetweenThreadStart * 1000000L;
+        long nsBetweenThreadStart = runInfo.msBetweenThreadStart * 
Utilities.TO_NANOS;
         try {
             // We use System.nanoTime() here directly
             // instead of timer.getTime().
@@ -295,20 +305,22 @@ public class AgentImpl extends UnicastRemoteObject
             int count = 0;
 
             // First thread already started if preRun is there
-            if (runInfo.agentInfo.startThreadNumber == 0 &&
-                    runInfo.driverConfig.preRun != null) {
+            if ( (runInfo.driverConfig.preRunLocal != null) ||
+                    (runInfo.agentInfo.startThreadNumber == 0
+                        && runInfo.driverConfig.preRunGlobal != null)) {
                 // First thread already started, just let it run.
                 startLatch.countDown();
-                if (System.nanoTime() < earliestStartTime)
+                if (System.nanoTime() < earliestStartTime) {
                     timer.wakeupAt(earliestStartTime);
+                }
                 ++count;
             }
 
             calibrateTime();
 
             for (; count < numThreads && !runAborted; count++) {
-                int globalThreadId = runInfo.agentInfo.startThreadNumber +
-                        count;
+                int globalThreadId = runInfo.agentInfo.startThreadNumber
+                        + count;
                 agentThreads[count] = AgentThread.getInstance(agentType,
                         agentId, globalThreadId,
                         runInfo.driverConfig.driverClass, timer, this);
@@ -316,26 +328,23 @@ public class AgentImpl extends UnicastRemoteObject
 
                 // We ensure we catch up with the configured thread starting
                 // rate. If we fall short, we sleep less until we caught up.
-                long wakeupTime = nsBetweenThreadStart * (count + 1) +
-                        baseTime;
+                long wakeupTime = nsBetweenThreadStart * (count + 1)
+                        + baseTime;
                 long sleepTime = wakeupTime - System.nanoTime();
 
                 // In case we fall short, we sleep only 1/3 the interval
                 if (sleepTime <= 0) {
-                                       sleepTime = nsBetweenThreadStart / 3;
+                    sleepTime = nsBetweenThreadStart / 3;
                     wakeupTime = System.nanoTime() + sleepTime;
-                               }
+                }
 
                 timer.wakeupAt(wakeupTime);
             }
             if (runAborted) {
-                               logger.warning(displayName + ": Run aborted 
before starting " +
-                        numThreads + " driver threads.\n" + count +
-                        " threads were started.");
-                       } else {
-                               logger.info(displayName + ": Successfully 
started " +
-                        numThreads + " driver threads.");
-                       }
+                logger.log(Level.WARNING, "{0}: Run aborted before starting 
{1} driver threads.\n{2} threads were started.", new Object[]{displayName, 
numThreads, count});
+            } else {
+                logger.log(Level.INFO, "{0}: Successfully started {1} driver 
threads.", new Object[]{displayName, numThreads});
+            }
             if (runInfo.variableLoad) {
                 runInfo.variableLoadHandler = new VariableLoadHandler(
                         runInfo.driverConfig.variableLoadFile);
@@ -347,7 +356,7 @@ public class AgentImpl extends UnicastRemoteObject
             try {
                 master.abortRun();
             } catch (RemoteException e1) {
-               logger.log(Level.FINE, e1.getMessage(), e);
+                logger.log(Level.FINE, e1.getMessage(), e);
             }
         }
     }
@@ -356,6 +365,7 @@ public class AgentImpl extends UnicastRemoteObject
      * Obtains the id of this agent.
      * @return The id of this agent.
      */
+    @Override
     public int getId() {
         return Integer.parseInt(agentId);
     }
@@ -366,22 +376,24 @@ public class AgentImpl extends UnicastRemoteObject
      */
     public synchronized void abortRun() {
         if (runAborted) {
-                       return;     // the master again. Once per agent is 
enough.
-               }
+            return;     // the master again. Once per agent is enough.
+        }
         runAborted = true;
-        if (startLatch != null) 
+        if (startLatch != null) {
             try {
                 startLatch.countDown();
             } catch (Exception e) {
                 // Just make sure we don't get stuck here.
             }
+        }
 
-        if (postRunLatch != null)
+        if (postRunLatch != null) {
             try {
                 postRunLatch.countDown();
             } catch (Exception e) {
                 // Just make sure we don't get stuck here.
             }
+        }
 
         try {
             master.abortRun();
@@ -394,24 +406,35 @@ public class AgentImpl extends UnicastRemoteObject
     /**
      * Wait until all threads are started.
      */
+    @Override
     public void waitForThreadStart() {
         if (!runAborted) {
-                       try {
+            try {
+                logger.log(Level.FINE, "{0} awaiting threadStartLatch",
+                    displayName);
                 threadStartLatch.await();
+                logger.log(Level.FINER, "{0} threadStartLatch unlocked",
+                    displayName);
             } catch (InterruptedException e) {
-               logger.log(Level.FINE, e.getMessage(), e);
+                logger.log(Level.FINE, e.getMessage(), e);
             }
-               }
+        }
     }
 
     /**
      * Sets the actual run start time.
      * @param time The relative millisec time of the benchmark start
      */
+    @Override
     public void setStartTime(int time) {
         runInfo.benchStartTime = time;
         startTime = timer.toAbsNanos(time);
         runInfo.start = timer.toAbsMillis(time);
+        logger.log(Level.FINE, 
+            "{0}: benchmark starting at relative time {1} msec, " + 
+            "{2} absolute nsec", 
+            new Object[]{displayName, time, startTime}); 
+        logger.log(Level.FINER, "{0}: unlocking timeSetLatch", displayName);
         timeSetLatch.countDown();
         if (runInfo.runtimeStatsEnabled) {
             statsCollector = new StatsCollector();
@@ -419,30 +442,32 @@ public class AgentImpl extends UnicastRemoteObject
 
         // After we know the start time, we calibrate
         // the timer during the ramp up.
-        timer.calibrate(displayName, startTime, 
-                        startTime + runInfo.rampUp * 1000000000l);
+        timer.calibrate(displayName, startTime,
+                startTime + runInfo.rampUp * 1000000000l);
     }
-    
+
     /**
      * This method kills off the current run.
      * It terminates all threads.
      */
+    @Override
     public synchronized void kill() {
         runAborted = true;
-        logger.warning(displayName + ": Killing benchmark run");
+        logger.log(Level.WARNING, "{0}: Killing benchmark run", displayName);
         for (int i = 0; i < numThreads; i++) {
-                       if (agentThreads[i] != null && 
agentThreads[i].isAlive()) {
-                               try {
+            if (agentThreads[i] != null && agentThreads[i].isAlive()) {
+                try {
                     agentThreads[i].stopExecution();
                 } catch (Throwable t) {
-                    logger.log(Level.SEVERE, agentThreads[i].name +
-                            ": Error killing thread.", t);
+                    logger.log(Level.SEVERE, agentThreads[i].name
+                            + ": Error killing thread.", t);
                 }
-                       }
-               }
+            }
+        }
         // cleanup
-        if (statsCollector != null)
+        if (statsCollector != null) {
             statsCollector.cancel();
+        }
     }
 
     /**
@@ -451,107 +476,114 @@ public class AgentImpl extends UnicastRemoteObject
      * wait for the threads to terminate (join). Terminate is called
      * while join is hanging on some thread that refuses to terminate.
      */
+    @Override
     public synchronized void terminate() {
         boolean terminationLogged = false;
         int terminationCount = 0;
         Throwable t = null;
         for (int i = numThreads - 1; i > 0; i--) {
-                       if (agentThreads[i] != null && 
agentThreads[i].isAlive()) {
-                               try {
+            if (agentThreads[i] != null && agentThreads[i].isAlive()) {
+                try {
                     if (!terminationLogged) { // Log this only once.
-                        logger.warning(displayName +
-                                ": Forcefully terminating benchmark run");
+                        logger.log(Level.WARNING, "{0}: Forcefully 
terminating benchmark run", displayName);
                         terminationLogged = true;
                     }
                     t = new Throwable(
                             "Stack of non-terminating thread.");
                     t.setStackTrace(agentThreads[i].getStackTrace());
-                    logger.log(Level.FINE, agentThreads[i].name +
-                            ": Thread not Terminated. " +
-                            "Dumping stack and force termination.", t);
+                    logger.log(Level.FINE, agentThreads[i].name
+                            + ": Thread not Terminated. "
+                            + "Dumping stack and force termination.", t);
                     ++terminationCount;
                     agentThreads[i].stopExecution();
                 } catch (Throwable e) {
-                    logger.log(Level.SEVERE, agentThreads[i].name +
-                            ": Error killing thread.", e);
+                    logger.log(Level.SEVERE, agentThreads[i].name
+                            + ": Error killing thread.", e);
                 }
-                       }
-               }
-
-        if (runInfo.agentInfo.startThreadNumber == 0 &&
-                runInfo.driverConfig.postRun != null &&
-                agentThreads[0] != null) {
-            if (agentThreads[0].getThreadState() ==
-                    AgentThread.RunState.RUNNING) {
+            }
+        }
+
+        if ( (runInfo.driverConfig.postRunLocal != null ||
+                (runInfo.agentInfo.startThreadNumber == 0
+                    && runInfo.driverConfig.postRunGlobal != null ) ) &&
+                    agentThreads[0] != null) {
+            if (agentThreads[0].getThreadState()
+                    == AgentThread.RunState.RUNNING) {
                 try {
                     if (!terminationLogged) { // Log this only once.
-                        logger.warning(displayName +
-                                ": Forcefully terminating benchmark run");
+                        logger.log(Level.WARNING, "{0}: Forcefully 
terminating benchmark run", displayName);
                         terminationLogged = true;
                     }
                     t = new Throwable(
                             "Stack of non-terminating thread.");
                     t.setStackTrace(agentThreads[0].getStackTrace());
-                    logger.log(Level.FINE, agentThreads[0].name +
-                            ": Thread not Terminated. " +
-                            "Dumping stack and force termination.", t);
+                    logger.log(Level.FINE, agentThreads[0].name
+                            + ": Thread not Terminated. "
+                            + "Dumping stack and force termination.", t);
                     ++terminationCount;
                     agentThreads[0].stopExecution();
                 } catch (Throwable e) {
-                    logger.log(Level.SEVERE, agentThreads[0].name +
-                      
[truncated due to length]



[faban-commits] [faban~source:c687fdea] Merge branch 'master' of ssh://git.java.net/faban~source

yaominchen 12/06/2011
 
 
Close
loading
Please Confirm
Close