From 11f5689e46394e4d1303fbcd9e55498353e1dba7 Mon Sep 17 00:00:00 2001
From: Letitia Li <letitia.li@telecom-paristech.fr>
Date: Fri, 25 Nov 2016 14:54:32 +0100
Subject: [PATCH] Latency measurement fixes

---
 simulators/c++2/src_simulator/arch/Bus.cpp    | 13 +++
 simulators/c++2/src_simulator/arch/Bus.h      |  2 +-
 .../src_simulator/arch/SchedulableDevice.h    |  2 +-
 .../c++2/src_simulator/arch/SingleCoreCPU.cpp | 14 +++
 .../c++2/src_simulator/arch/SingleCoreCPU.h   |  3 +-
 .../c++2/src_simulator/sim/Simulator.cpp      | 16 ++++
 simulators/c++2/src_simulator/sim/Simulator.h |  1 +
 src/remotesimulation/CommandParser.java       | 14 ++-
 src/ui/MainGUI.java                           |  7 ++
 src/ui/TGComponent.java                       | 22 ++++-
 .../JFrameInteractiveSimulation.java          | 86 +++++++++++++------
 .../LatencyTableModel.java                    | 19 +++-
 .../SimulationLatency.java                    |  5 +-
 13 files changed, 168 insertions(+), 36 deletions(-)

diff --git a/simulators/c++2/src_simulator/arch/Bus.cpp b/simulators/c++2/src_simulator/arch/Bus.cpp
index 09e1ab3577..25b6a4375e 100644
--- a/simulators/c++2/src_simulator/arch/Bus.cpp
+++ b/simulators/c++2/src_simulator/arch/Bus.cpp
@@ -203,6 +203,19 @@ int Bus::allTrans2XML(std::ostringstream& glob, int maxNbOfTrans) const {
   return total;
 }
 
+void Bus::latencies2XML(std::ostringstream& glob, int id1, int id2) {
+
+  for(TransactionList::const_iterator i=_transactList.begin(); i != _transactList.end(); ++i){
+	if ((*i)->getCommand() !=NULL){
+		if ((*i)->getCommand()->getID() == id1 || (*i)->getCommand()->getID() == id2){
+		    (*i)->toXML(glob, 1, _name);
+		}
+	}
+  }
+  return;
+}
+
+
 
 //Returns the next signal change (for vcd output)
 void Bus::getNextSignalChange(bool iInit, SignalChangeData* oSigData){
diff --git a/simulators/c++2/src_simulator/arch/Bus.h b/simulators/c++2/src_simulator/arch/Bus.h
index aa9bcd3992..5acf3fa3f6 100644
--- a/simulators/c++2/src_simulator/arch/Bus.h
+++ b/simulators/c++2/src_simulator/arch/Bus.h
@@ -107,7 +107,7 @@ public:
       	\param glob refers to the output stream
     	*/
 	int allTrans2XML(std::ostringstream& glob, int maxNbOfTrans) const;
-
+	void latencies2XML(std::ostringstream& glob, int id1, int id2);
 	/**
       	\param myfile Reference to the ofstream object representing the output file
     	*/
diff --git a/simulators/c++2/src_simulator/arch/SchedulableDevice.h b/simulators/c++2/src_simulator/arch/SchedulableDevice.h
index adc5b16d5f..3a7823dcbb 100644
--- a/simulators/c++2/src_simulator/arch/SchedulableDevice.h
+++ b/simulators/c++2/src_simulator/arch/SchedulableDevice.h
@@ -92,7 +92,7 @@ public:
       	\param glob references the output stream object 
     	*/
 	virtual int allTrans2XML(std::ostringstream& glob, int maxNbOfTrans) const =0;
-	
+	virtual void latencies2XML(std::ostringstream& glob, int id1, int id2)=0;
 	virtual std::string toString() const =0;
 	virtual std::istream& readObject(std::istream &is){
 		READ_STREAM(is,_endSchedule);
diff --git a/simulators/c++2/src_simulator/arch/SingleCoreCPU.cpp b/simulators/c++2/src_simulator/arch/SingleCoreCPU.cpp
index 59fc8b6d4f..460066119e 100644
--- a/simulators/c++2/src_simulator/arch/SingleCoreCPU.cpp
+++ b/simulators/c++2/src_simulator/arch/SingleCoreCPU.cpp
@@ -428,6 +428,20 @@ int SingleCoreCPU::allTrans2XML(std::ostringstream& glob, int maxNbOfTrans) cons
   return total;
 }
 
+void SingleCoreCPU::latencies2XML(std::ostringstream& glob, int id1, int id2) {
+
+  for(TransactionList::const_iterator i=_transactList.begin(); i != _transactList.end(); ++i){
+	if ((*i)->getCommand() !=NULL){
+	if ((*i)->getCommand()->getID() == id1 || (*i)->getCommand()->getID() == id2){
+	    (*i)->toXML(glob, 1, _name);
+	}
+	}
+  }
+  return;
+}
+
+
+
 //TMLTime SingleCoreCPU::getNextSignalChange(bool iInit, std::string& oSigChange, bool& oNoMoreTrans){
 void SingleCoreCPU::getNextSignalChange(bool iInit, SignalChangeData* oSigData){
   //new (oSigData) SignalChangeData(RUNNING, aCurrTrans->getStartTimeOperation(), this);
diff --git a/simulators/c++2/src_simulator/arch/SingleCoreCPU.h b/simulators/c++2/src_simulator/arch/SingleCoreCPU.h
index 5ff3f8bfad..50be70a414 100644
--- a/simulators/c++2/src_simulator/arch/SingleCoreCPU.h
+++ b/simulators/c++2/src_simulator/arch/SingleCoreCPU.h
@@ -116,7 +116,8 @@ public:
       	\param glob refers to the output stream
     	*/
 	int allTrans2XML(std::ostringstream& glob, int maxNbOfTrans) const;
-	
+
+	void latencies2XML(std::ostringstream& glob, int id1, int id2);
 	virtual void streamBenchmarks(std::ostream& s) const;
 	virtual void reset();
 	inline void streamStateXML(std::ostream& s) const {streamBenchmarks(s);}
diff --git a/simulators/c++2/src_simulator/sim/Simulator.cpp b/simulators/c++2/src_simulator/sim/Simulator.cpp
index ebe8daf377..af2e94f770 100644
--- a/simulators/c++2/src_simulator/sim/Simulator.cpp
+++ b/simulators/c++2/src_simulator/sim/Simulator.cpp
@@ -229,6 +229,15 @@ int Simulator::allTrans2XML(std::ostringstream& glob, int maxNbOfTrans) const{
   return total;
 }
 
+void Simulator::latencies2XML(std::ostringstream& glob, int id1, int id2) {
+	for(CPUList::const_iterator i=_simComp->getCPUList().begin(); i != _simComp->getCPUList().end(); ++i){
+    (*i)->latencies2XML(glob, id1, id2);
+  }
+
+  for(BusList::const_iterator j=_simComp->getBusList().begin(); j != _simComp->getBusList().end(); ++j){
+    (*j)->latencies2XML(glob, id1,id2);
+  }
+}
 
 
 void Simulator::schedule2HTML(std::string& iTraceFileName) const{
@@ -1254,6 +1263,13 @@ void Simulator::decodeCommand(std::string iCmd, std::ostream& iXmlOutStream){
     anEntityMsg << TAG_TRANSACTION_NBo << "nb=\"" << returnedNbOfTransactions << "\"" << TAG_TRANSACTION_NBc <<  std::endl;
     std::cout << "End list of transactions." << std::endl;
     break;
+  case 23:
+	aInpStream >> aParam1;
+	aInpStream >> aParam2;
+	std::cout <<"Calculate latencies between " << aParam1 << " and " << aParam2 << std::endl;
+	latencies2XML(anEntityMsg, aParam1, aParam2);
+	std::cout << "latencies " << &anEntityMsg << std::endl;
+	break;
   default:
     anEntityMsg << TAG_MSGo << MSG_CMDNFOUND<< TAG_MSGc << std::endl;
     anErrorCode=3;
diff --git a/simulators/c++2/src_simulator/sim/Simulator.h b/simulators/c++2/src_simulator/sim/Simulator.h
index 954c33e532..f5515aa904 100644
--- a/simulators/c++2/src_simulator/sim/Simulator.h
+++ b/simulators/c++2/src_simulator/sim/Simulator.h
@@ -246,6 +246,7 @@ public:
 	*/
 	int allTrans2XML(std::ostringstream& glob, int maxNbOfTrans) const;
 	
+	void latencies2XML(std::ostringstream& glob, int id1, int id2);
 	
 	///Is true if the simulator is busy
 	/**
diff --git a/src/remotesimulation/CommandParser.java b/src/remotesimulation/CommandParser.java
index 34ddae4618..c14807b195 100755
--- a/src/remotesimulation/CommandParser.java
+++ b/src/remotesimulation/CommandParser.java
@@ -136,7 +136,7 @@ public class CommandParser {
         int cpt = 0;
 
         String cmds[] = cmd.split(" ");
-        //System.out.println("cmd " + cmd + " has " + cmds.length + " elements");
+      //  System.out.println("cmd " + cmd + " has " + cmds.length + " elements");
 
         for(SimulationCommand sc: commandList) {
             // Same command name?
@@ -478,6 +478,18 @@ public class CommandParser {
         paramNames[0] = "Max. nb of transactions";
         sc = new SimulationCommand("list-transactions", "lt", "22", params, paramNames, "Get the most recent transactions");
         commandList.add(sc);
+
+
+	// Get latencies
+		params = new int[2];
+		paramNames = new String[2];
+		params[0] = 1;
+		paramNames[0]="Checkpoint 1 id";
+		params[1] = 1;
+		paramNames[1] = "Checkpoint2 id";
+		sc = new SimulationCommand("calculate-latencies", "cl", "23", params, paramNames, "Calculate latencies between checkpoints");
+		commandList.add(sc);
+		
     }
 
     
diff --git a/src/ui/MainGUI.java b/src/ui/MainGUI.java
index 75637b0576..481ae5ba5f 100644
--- a/src/ui/MainGUI.java
+++ b/src/ui/MainGUI.java
@@ -7843,6 +7843,13 @@ public  class MainGUI implements ActionListener, WindowListener, KeyListener, Pe
 
         return statusMap;
     }
+
+	public String getStatus(String s){
+		if (statusMap==null){
+			return null;
+		}
+		return statusMap.get(s);
+	}
     public synchronized LoadInfo isLoadID(int id) {
         if (loadIDs == null) {
             return null;
diff --git a/src/ui/TGComponent.java b/src/ui/TGComponent.java
index 60f2af5561..3081b92a65 100755
--- a/src/ui/TGComponent.java
+++ b/src/ui/TGComponent.java
@@ -53,7 +53,7 @@ import java.awt.event.*;
 import java.awt.geom.*;
 
 import java.util.*;
-
+import java.util.concurrent.*;
 import org.w3c.dom.*;
 
 import myutil.*;
@@ -1101,7 +1101,20 @@ public abstract class TGComponent implements CDElement, GenericTree {
 				}				
 			    }
 			}
-			Map<String, String> statMap = tdp.getMGUI().getStatus(getDIPLOID());
+			for (int i=0; i<nbInternalTGComponent; i++){
+				Object ob = getChild(i);
+				if (ob instanceof TMLArchiArtifact){
+					TMLArchiArtifact art = (TMLArchiArtifact) ob;
+					String stat=tdp.getMGUI().getStatus(art.getValue().replaceAll(":","_"));
+					if (stat!=null){
+						art.runningStatus=stat;
+						art.drawStatus(g);
+						tdp.repaint();
+					}
+				}
+			}/*
+			//This code is horrible and I should fix it 
+			ConcurrentHashMap<String, String> statMap = tdp.getMGUI().getStatus(getDIPLOID());
 			for (String name:statMap.keySet()){
 			    String stat =statMap.get(name);
 			    for (int i=0; i< nbInternalTGComponent; i++){	
@@ -1115,8 +1128,9 @@ public abstract class TGComponent implements CDElement, GenericTree {
 				     }
 				}
 			    }
-			}
-		    
+			
+		    }*/
+	
                     }
                     /*if (this instanceof TMLArchiCPUNode) {
 
diff --git a/src/ui/interactivesimulation/JFrameInteractiveSimulation.java b/src/ui/interactivesimulation/JFrameInteractiveSimulation.java
index d8ba059955..264591805d 100755
--- a/src/ui/interactivesimulation/JFrameInteractiveSimulation.java
+++ b/src/ui/interactivesimulation/JFrameInteractiveSimulation.java
@@ -997,13 +997,15 @@ public  class JFrameInteractiveSimulation extends JFrame implements ActionListen
         ((jtablePI.getColumnModel()).getColumn(0)).setPreferredWidth(400);
         ((jtablePI.getColumnModel()).getColumn(1)).setPreferredWidth(400);
         ((jtablePI.getColumnModel()).getColumn(2)).setPreferredWidth(50);
-
+        ((jtablePI.getColumnModel()).getColumn(3)).setPreferredWidth(50);
+        ((jtablePI.getColumnModel()).getColumn(4)).setPreferredWidth(50);
+        ((jtablePI.getColumnModel()).getColumn(5)).setPreferredWidth(50);
         jtablePI.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
         jspLatency = new JScrollPane(jtablePI);
         jspLatency.setWheelScrollingEnabled(true);
         jspLatency.getVerticalScrollBar().setUnitIncrement(10);
         jspLatency.setMinimumSize(new Dimension(300, 250));
-        jspLatency.setPreferredSize(new Dimension(450, 250));
+        jspLatency.setPreferredSize(new Dimension(950, 250));
         latencyPanel.add(jspLatency, c0);
 
 
@@ -1723,7 +1725,6 @@ public  class JFrameInteractiveSimulation extends JFrame implements ActionListen
 
                             st.deviceName = elt.getAttribute("devicename");
                             String commandT = elt.getAttribute("command");
-                            TraceManager.addDev("command found: " + commandT);
                             if (commandT != null) {
                                 int index = commandT.indexOf(": ");
                                 if (index == -1){
@@ -2314,7 +2315,10 @@ public  class JFrameInteractiveSimulation extends JFrame implements ActionListen
 		SimulationLatency sl = new SimulationLatency();
 		sl.trans1 = transaction1.getSelectedItem().toString();
 		sl.trans2 = transaction2.getSelectedItem().toString();
-		sl.time="0";
+		sl.minTime="??";
+		sl.maxTime="??";
+		sl.avTime="??";
+		sl.stDev="??";
 		boolean found=false;
 		for (Object o:latencies){
 			SimulationLatency s = (SimulationLatency) o;
@@ -2326,37 +2330,65 @@ public  class JFrameInteractiveSimulation extends JFrame implements ActionListen
 			latencies.add(sl);
 		}
 		updateLatency();
-		latm.setData(latencies);
+		if (latm !=null && latencies.size()>0){
+			latm.setData(latencies);
+		}
 	}
 	private void updateLatency(){
-	   sendCommand("lt 20");
+		for (Object o:latencies){
+			SimulationLatency sl = (SimulationLatency) o;
+			//calcuate response + checkpoint 1 id + checkpoint 2 id
+			sendCommand("cl " + sl.trans1.split("ID: ")[1].split("\\)")[0] + " " + sl.trans2.split("ID: ")[1].split("\\)")[0]);
+		}
 	}
 
 	private void processLatency(){
  
-//		TraceManager.addDev(transTimes.toString());
+		TraceManager.addDev(transTimes.toString());
 		for (Object o: latencies){
 			SimulationLatency sl = (SimulationLatency) o;
-			sl.time="??";
+			sl.minTime="??";
+			sl.maxTime="??";
+			sl.avTime="??";
+			sl.stDev="??";
 			for (String st1:transTimes.keySet()){
 				for (String st2:transTimes.keySet()){
 					if (st1!=st2){
 						if (checkTable.get(st2).contains(sl.trans2) && checkTable.get(st1).contains(sl.trans1)){
-							ArrayList<Integer> minTimes = new ArrayList<Integer>();							
-							for(String time1: transTimes.get(st1)){
+							ArrayList<Integer> minTimes = new ArrayList<Integer>();		
+							if (transTimes.get(st1) !=null && transTimes.get(st2)!=null){
+								for(String time1: transTimes.get(st1)){
 								//Find the first subsequent transaction
-								int time = Integer.MAX_VALUE;
-								for (String time2: transTimes.get(st2)){
-									int diff = Integer.valueOf(time1) - Integer.valueOf(time2);
-									if (diff < time && diff >=0){
-										time=diff;
-									}	
+									int time = Integer.MAX_VALUE;
+									for (String time2: transTimes.get(st2)){
+										int diff = Integer.valueOf(time2) - Integer.valueOf(time1);
+										if (diff < time && diff >=0){
+											time=diff;
+										}	
+									}
+									if (time!=Integer.MAX_VALUE){
+										minTimes.add(time);						
+									}
 								}
-								if (time!=Integer.MAX_VALUE){
-									minTimes.add(time);						
+								if (minTimes.size()>0){
+									int sum=0;
+									sl.minTime=Integer.toString(Collections.min(minTimes));
+									sl.maxTime=Integer.toString(Collections.max(minTimes));	
+									for (int time: minTimes){
+										sum+=time;
+									}
+									double average = (double) sum/ (double) minTimes.size();
+									double stdev =0.0;
+									for (int time:minTimes){
+										stdev +=(time - average)*(time-average);
+									}
+									stdev= stdev/minTimes.size();
+									stdev = Math.sqrt(stdev);
+									sl.avTime= String.format("%.1f",average);	
+									sl.stDev = String.format("%.1f",stdev);
 								}
 							}
-							sl.time=Integer.toString(Collections.max(minTimes));	
+							
 						}
 						
 					}
@@ -2364,7 +2396,9 @@ public  class JFrameInteractiveSimulation extends JFrame implements ActionListen
 
 			}
 		}
-		latm.setData(latencies);
+		if (latm!=null && latencies.size()>0){
+			latm.setData(latencies);
+		}
 	}
 
     private void updateTaskCommands() {
@@ -3057,13 +3091,17 @@ public  class JFrameInteractiveSimulation extends JFrame implements ActionListen
 		
 		//System.out.println(tmap.getTMLModeling().getCheckedComps());
 		for (String s: tmap.getTMLModeling().getCheckedActivities()){
-			TraceManager.addDev(s);
-			checkedTransactions.add(s.split("__")[s.split("__").length-1]);
+			
+			//checkedTransactions.add(s.split("__")[s.split("__").length-1]);
 		}
 		for (String s: tmap.getTMLModeling().getCheckedComps().keySet()){
 			//System.out.println(tmap.getTMLModeling().getCheckedComps().get(s).getDIPLOID() + " "+s);
-			checkTable.put(Integer.toString(tmap.getTMLModeling().getCheckedComps().get(s).getDIPLOID()),s);
+			TraceManager.addDev(s);
+			checkedTransactions.add(s+"(ID: " + tmap.getTMLModeling().getCheckedComps().get(s).getDIPLOID()+")");
+			checkTable.put(Integer.toString(tmap.getTMLModeling().getCheckedComps().get(s).getDIPLOID()),s+"(ID: " + tmap.getTMLModeling().getCheckedComps().get(s).getDIPLOID()+")");
 		}
+		//System.out.println(checkedTransactions);
+		//System.out.println(checkTable);
 	}
     public void activeBreakPoint(boolean active) {
         if (mode == STARTED_AND_CONNECTED) {
@@ -3074,7 +3112,7 @@ public  class JFrameInteractiveSimulation extends JFrame implements ActionListen
             }
         }
     }
-
+    
     public void setVariables(int _idTask, int _idVariable, String _value) {
         sendCommand("set-variable " + _idTask + " " + _idVariable + " " + _value);
         sendCommand("get-variable-of-task " + _idTask + " " + _idVariable);
diff --git a/src/ui/interactivesimulation/LatencyTableModel.java b/src/ui/interactivesimulation/LatencyTableModel.java
index 97eb848eb8..6403531f9c 100755
--- a/src/ui/interactivesimulation/LatencyTableModel.java
+++ b/src/ui/interactivesimulation/LatencyTableModel.java
@@ -74,7 +74,7 @@ public class LatencyTableModel extends AbstractTableModel {
     }
 
     public int getColumnCount() {
-        return 3;
+        return 6;
     }
 
     public synchronized Object getValueAt(int row, int column) {
@@ -94,7 +94,13 @@ public class LatencyTableModel extends AbstractTableModel {
         case 1:
             return st.trans2;
         case 2:
-            return st.time;
+            return st.minTime;
+		case 3:
+			return st.maxTime;
+		case 4:	
+			return st.avTime;
+		case 5:
+			return st.stDev;
         }
         return "unknown";		
     }
@@ -106,8 +112,15 @@ public class LatencyTableModel extends AbstractTableModel {
         case 1:
             return "Transaction 2";
         case 2:
-            return "Time";
+            return "Min";
+		case 3:
+			return "Max";
+		case 4:
+			return "Average";
+		case 5:
+			return "St Dev";
         }
+		
         return "unknown";
     }
 
diff --git a/src/ui/interactivesimulation/SimulationLatency.java b/src/ui/interactivesimulation/SimulationLatency.java
index 75a3c125e7..6a3e0a2b8b 100644
--- a/src/ui/interactivesimulation/SimulationLatency.java
+++ b/src/ui/interactivesimulation/SimulationLatency.java
@@ -56,7 +56,10 @@ public class SimulationLatency  {
 
     public String trans1;
     public String trans2;
-    public String time=""; 
+    public String minTime=""; 
+	public String maxTime="";
+	public String avTime="";
+	public String stDev="";
 
     public SimulationLatency() {
     }
-- 
GitLab