Working on IO loop tests commands.
diff --git a/apps/foo/src/main/java/org/onlab/onos/foo/IOLoopTestClient.java b/apps/foo/src/main/java/org/onlab/onos/foo/IOLoopTestClient.java
index ebbe5bc..5c96d49 100644
--- a/apps/foo/src/main/java/org/onlab/onos/foo/IOLoopTestClient.java
+++ b/apps/foo/src/main/java/org/onlab/onos/foo/IOLoopTestClient.java
@@ -27,6 +27,7 @@
 
 import static java.lang.String.format;
 import static java.lang.System.currentTimeMillis;
+import static java.lang.System.nanoTime;
 import static java.lang.System.out;
 import static org.onlab.onos.foo.IOLoopTestServer.PORT;
 import static org.onlab.util.Tools.delay;
@@ -185,7 +186,7 @@
      */
     public void report() {
         DecimalFormat f = new DecimalFormat("#,##0");
-        out.println(format("Client: %s messages; %s bytes; %s mps; %s Mbs; %s ms latency",
+        out.println(format("Client: %s messages; %s bytes; %s mps; %s Mbs; %s ns latency",
                            f.format(messages.total()), f.format(bytes.total()),
                            f.format(messages.throughput()),
                            f.format(bytes.throughput() / (1024 * msgLength)),
@@ -233,7 +234,7 @@
                                        MessageStream<TestMessage> stream) {
             for (TestMessage message : messages) {
                 // TODO: summarize latency data better
-                latencyTotal += currentTimeMillis() - message.requestorTime();
+                latencyTotal += nanoTime() - message.requestorTime();
                 latencyCount++;
             }
             worker.release(messages.size());
@@ -254,7 +255,7 @@
      */
     private class Worker implements Runnable {
 
-        private static final int BATCH_SIZE = 1000;
+        private static final int BATCH_SIZE = 10;
         private static final int PERMITS = 2 * BATCH_SIZE;
 
         private TestMessageStream stream;
@@ -297,7 +298,7 @@
             // Build a batch of messages
             List<TestMessage> batch = Lists.newArrayListWithCapacity(size);
             for (int i = 0; i < size; i++) {
-                batch.add(new TestMessage(msgLength, currentTimeMillis(), 0,
+                batch.add(new TestMessage(msgLength, nanoTime(), 0,
                                           stream.padding()));
             }
             acquire(size);
diff --git a/apps/foo/src/main/java/org/onlab/onos/foo/IOLoopTestServer.java b/apps/foo/src/main/java/org/onlab/onos/foo/IOLoopTestServer.java
index 778f217..ad7e6b8 100644
--- a/apps/foo/src/main/java/org/onlab/onos/foo/IOLoopTestServer.java
+++ b/apps/foo/src/main/java/org/onlab/onos/foo/IOLoopTestServer.java
@@ -24,6 +24,7 @@
 
 import static java.lang.String.format;
 import static java.lang.System.currentTimeMillis;
+import static java.lang.System.nanoTime;
 import static java.lang.System.out;
 import static org.onlab.util.Tools.delay;
 import static org.onlab.util.Tools.namedThreads;
@@ -92,6 +93,7 @@
             int r = server.prune();
             remaining = remaining == -1 && r == 0 ? remaining : r;
         }
+        server.stop();
     }
 
     /**
@@ -220,7 +222,7 @@
             List<TestMessage> responses = Lists.newArrayListWithCapacity(messages.size());
             for (TestMessage message : messages) {
                 responses.add(new TestMessage(message.length(), message.requestorTime(),
-                                              currentTimeMillis(), message.padding()));
+                                              nanoTime(), message.padding()));
             }
             return responses;
         }
diff --git a/utils/nio/src/test/java/org/onlab/nio/IOLoopTestClient.java b/utils/nio/src/test/java/org/onlab/nio/IOLoopTestClient.java
index 6f6bd6d..dba0b18 100644
--- a/utils/nio/src/test/java/org/onlab/nio/IOLoopTestClient.java
+++ b/utils/nio/src/test/java/org/onlab/nio/IOLoopTestClient.java
@@ -25,6 +25,7 @@
 
 import static java.lang.String.format;
 import static java.lang.System.currentTimeMillis;
+import static java.lang.System.nanoTime;
 import static java.lang.System.out;
 import static org.onlab.nio.IOLoopTestServer.PORT;
 import static org.onlab.util.Tools.delay;
@@ -183,7 +184,7 @@
      */
     public void report() {
         DecimalFormat f = new DecimalFormat("#,##0");
-        out.println(format("Client: %s messages; %s bytes; %s mps; %s Mbs; %s ms latency",
+        out.println(format("Client: %s messages; %s bytes; %s mps; %s Mbs; %s ns latency",
                            f.format(messages.total()), f.format(bytes.total()),
                            f.format(messages.throughput()),
                            f.format(bytes.throughput() / (1024 * msgLength)),
@@ -231,7 +232,7 @@
                                        MessageStream<TestMessage> stream) {
             for (TestMessage message : messages) {
                 // TODO: summarize latency data better
-                latencyTotal += currentTimeMillis() - message.requestorTime();
+                latencyTotal += nanoTime() - message.requestorTime();
                 latencyCount++;
             }
             worker.release(messages.size());
@@ -252,7 +253,7 @@
      */
     private class Worker implements Runnable {
 
-        private static final int BATCH_SIZE = 1000;
+        private static final int BATCH_SIZE = 50;
         private static final int PERMITS = 2 * BATCH_SIZE;
 
         private TestMessageStream stream;
@@ -295,8 +296,7 @@
             // Build a batch of messages
             List<TestMessage> batch = Lists.newArrayListWithCapacity(size);
             for (int i = 0; i < size; i++) {
-                batch.add(new TestMessage(msgLength, currentTimeMillis(), 0,
-                                          stream.padding()));
+                batch.add(new TestMessage(msgLength, nanoTime(), 0, stream.padding()));
             }
             acquire(size);
             stream.write(batch);
diff --git a/utils/nio/src/test/java/org/onlab/nio/IOLoopTestServer.java b/utils/nio/src/test/java/org/onlab/nio/IOLoopTestServer.java
index 18566d7..457023b 100644
--- a/utils/nio/src/test/java/org/onlab/nio/IOLoopTestServer.java
+++ b/utils/nio/src/test/java/org/onlab/nio/IOLoopTestServer.java
@@ -82,11 +82,14 @@
         IOLoopTestServer server = new IOLoopTestServer(ip, wc, ml, PORT);
         server.start();
 
-        // Start pruning clients.
-        while (true) {
+        // Start pruning clients and keep going until their number goes to 0.
+        int remaining = -1;
+        while (remaining == -1 || remaining > 0) {
             delay(PRUNE_FREQUENCY);
-            server.prune();
+            int r = server.prune();
+            remaining = remaining == -1 && r == 0 ? remaining : r;
         }
+        server.stop();
     }
 
     /**
@@ -158,11 +161,15 @@
 
     /**
      * Prunes the IO loops of stale message buffers.
+     *
+     * @return number of remaining IO loops among all workers.
      */
-    public void prune() {
+    public int prune() {
+        int count = 0;
         for (CustomIOLoop l : iloops) {
-            l.pruneStaleStreams();
+            count += l.pruneStaleStreams();
         }
+        return count;
     }
 
     // Get the next worker to which a client should be assigned
@@ -211,7 +218,7 @@
             List<TestMessage> responses = Lists.newArrayListWithCapacity(messages.size());
             for (TestMessage message : messages) {
                 responses.add(new TestMessage(message.length(), message.requestorTime(),
-                                              currentTimeMillis(), message.padding()));
+                                              System.nanoTime(), message.padding()));
             }
             return responses;
         }