Fix for potential race in measurement util.

Change-Id: I86544e9c1f2813c750c417c99e3ee51d3917ab5e
diff --git a/src/main/java/net/onrc/onos/ofcontroller/flowmanager/PerformanceMonitor.java b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/PerformanceMonitor.java
index 9e23555..3721ceb 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/flowmanager/PerformanceMonitor.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/PerformanceMonitor.java
@@ -1,8 +1,5 @@
 package net.onrc.onos.ofcontroller.flowmanager;
 
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Queue;
 import java.util.concurrent.ConcurrentHashMap;
@@ -15,7 +12,7 @@
  * Class for collecting performance measurements
  */
 public class PerformanceMonitor {
-    private final static Map<String, Queue<Measurement>> map = new ConcurrentHashMap<>();;
+    private final static ConcurrentHashMap<String, Queue<Measurement>> map = new ConcurrentHashMap<>();;
     private final static Logger log = LoggerFactory.getLogger(PerformanceMonitor.class);
     private static long overhead;
     private static long experimentStart = Long.MAX_VALUE;
@@ -23,10 +20,10 @@
 
     /**
      * Start a performance measurement, identified by a tag
-     * 
+     *
      * Note: Only a single measurement can use the same tag at a time.
      * ..... not true anymore.
-     * 
+     *
      * @param tag for performance measurement
      */
     public static Measurement start(String tag) {
@@ -37,7 +34,11 @@
 	Queue<Measurement> list = map.get(tag);
 	if(list == null) {
 	    list = new ConcurrentLinkedQueue<Measurement>();
-	    map.put(tag, list);
+	    Queue<Measurement> existing_list = map.putIfAbsent(tag, list);
+	    if (existing_list != null) {
+		// someone concurrently added, using theirs
+		list = existing_list;
+	    }
 	}
 	Measurement m = new Measurement();
 	list.add(m);
@@ -45,12 +46,12 @@
 	overhead += System.nanoTime() - start;
 	return m;
     }
-    
+
     /**
-     * Stop a performance measurement. 
-     * 
+     * Stop a performance measurement.
+     *
      * You must have already started a measurement with tag.
-     * 
+     *
      * @param tag for performance measurement
      */
     public static void stop(String tag) {
@@ -65,7 +66,7 @@
 	}
 	overhead += System.nanoTime() - time;
     }
-        
+
     /**
      * Clear all performance measurements.
      */
@@ -74,7 +75,7 @@
 	overhead = 0;
 	experimentStart = Long.MAX_VALUE;
     }
-    
+
     /**
      * Write all performance measurements to the log
      */
@@ -104,7 +105,7 @@
 		    if(stop > experimentEnd) {
 			experimentEnd = stop;
 		    }
-		}		
+		}
 		// Collect statistics for average
 		total += m.elapsed();
 		count++;
@@ -113,10 +114,10 @@
 	    // Normalize start/stop
 	    start -= experimentStart;
 	    stop -= experimentStart;
-	    result += key + '=' + 
-		    (avg / normalization) + '/' + 
-		    (start / normalization) + '/' + 
-		    (stop / normalization) + '/' + 
+	    result += key + '=' +
+		    (avg / normalization) + '/' +
+		    (start / normalization) + '/' +
+		    (stop / normalization) + '/' +
 		    count + '\n';
 	}
 	double overheadMs = overhead / normalization;
@@ -152,8 +153,8 @@
     public static class Measurement {
 	long start;
 	long stop = -1;
-	
-	/** 
+
+	/**
 	 * Start the measurement
 	 */
 	public void start() {
@@ -161,7 +162,7 @@
 		start = System.nanoTime();
 	    }
 	}
-	
+
 	/**
 	 * Stop the measurement
 	 */
@@ -169,7 +170,7 @@
 	    long now = System.nanoTime();
 	    stop(now);
 	}
-	
+
 	/**
 	 * Stop the measurement at a specific time
 	 * @param time to stop
@@ -179,10 +180,10 @@
 		stop = time;
 	    }
 	}
-	
+
 	/**
 	 * Compute the elapsed time of the measurement in nanoseconds
-	 * 
+	 *
 	 * @return the measurement time in nanoseconds, or -1 if the measurement is stil running.
 	 */
 	public long elapsed() {
@@ -193,19 +194,20 @@
 		return stop - start;
 	    }
 	}
-		
+
 	/**
 	 * Returns the number of milliseconds for the measurement as a String.
 	 */
+	@Override
 	public String toString() {
 	    double milli = elapsed() / normalization;
 	    double startMs = start / normalization;
 	    double stopMs = stop / normalization;
-	    
+
 	    return milli + "ms/" + startMs + '/' + stopMs;
 	}
     }
-    
+
     public static void main(String args[]){
 	// test the measurement overhead
 	String tag;