--- a/codeRev/src/hla/model/LinkToRti/link_to_rti.cc Sat Aug 18 15:01:04 2012 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,174 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2012 Mudit Raj Gupta
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Author: Mudit Raj Gupta <mudit.raaj.gupta@gmail.com>
- */
-
-#include "ns3/log.h"
-#include "ns3/link_to_rti.h"
-
-#include <string.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <pthread.h>
-
-NS_LOG_COMPONENT_DEFINE ("LinkToRti");
-
-namespace ns3 {
-
-//socket related variables
-int i;
-pthread_t alt;
-socklen_t clilen;
-struct sockaddr_in serv_addr, cli_addr;
-int rc,sockfd, newsockfd, portno, flag=0, noWork=0,n,count=0;
-char buffer[256];
-
-int link_to_rti::RTI_CLK;
-int link_to_rti::RTI_STOP=0;
-int link_to_rti::RTI_START=0;
-
-//Connection to RTI
-
-void * rtiLink(void* p)
-{
- link_to_rti obj;// = new link_to_rti;
- while(!flag)
- {
- count++;
- n=read(newsockfd,buffer,256);
- if(n>0)
- {
- if(strcmp(buffer, "#####")==0)
- {
-
- obj.timeAdv();
-
- }
-
- if(strcmp(buffer, "+++++")==0)
- {
- obj.stopSim();
- flag=1;
- }
-
- else
- {
- NS_LOG_LOGIC("New Message Received");
- }
-
- bzero(buffer,256);
-
-
- }
- if (n < 0)
- NS_LOG_ERROR("ERROR reading from socket");
- }
- obj.close_sock();
- return NULL;
-}
-//ask RTI to advance time
-
-void link_to_rti::reqTimeAdv(void)
-{
- // timeAdv();
-NS_LOG_UNCOND("Sending Request");
- n = write(newsockfd,"*",1);
- if (n < 0)
- NS_LOG_UNCOND("ERROR writing to socket");
- NS_LOG_LOGIC("Time Advance Requested\n");
-}
-
-//When time advance granted
-
-void link_to_rti::timeAdv(void)
-{
- RTI_CLK++;
- NS_LOG_LOGIC("Time Advance Granted");
- NS_LOG_UNCOND("TEST");
-}
-
-//To start the simulation
-
-void link_to_rti::startSim(void)
-{
- RTI_START=1;
- NS_LOG_LOGIC("Starting Simulation\n");
- rc = pthread_create(&alt, NULL, &rtiLink, NULL);
- if(rc)
- NS_LOG_ERROR("Thread: listen creation failed");
- RTI_CLK=0;
-}
-
-//To stop the simulation
-
-void link_to_rti::stopSim(void)
-{
- RTI_STOP=1;
- NS_LOG_LOGIC("Stopping simulation\n");
-}
-
-//Initialization
-
-void link_to_rti::init_sock(void)
-{
- sockfd = socket(AF_INET, SOCK_STREAM, 0);
- if (sockfd < 0)
- NS_LOG_ERROR("ERROR opening socket");
- bzero((char *) &serv_addr, sizeof(serv_addr));
- portno = PORT_NO;
- serv_addr.sin_family = AF_INET;
- serv_addr.sin_addr.s_addr = INADDR_ANY;
- serv_addr.sin_port = htons(portno);
- if (bind(sockfd, (struct sockaddr *) &serv_addr,
- sizeof(serv_addr)) < 0)
- NS_LOG_ERROR("ERROR on binding");
- listen(sockfd,5);
- clilen = sizeof(cli_addr);
- newsockfd = accept(sockfd,
- (struct sockaddr *) &cli_addr,
- &clilen);
- if (newsockfd < 0)
- NS_LOG_ERROR("ERROR on accept");
-}
-
-//closing
-
-void link_to_rti::close_sock(void)
-{
- close(newsockfd);
- close(sockfd);
-}
-
-//Have to be removed
-
-void link_to_rti::connectToRTI(void)
-{
-//startSim();
-
- init_sock();
- n=read(newsockfd,buffer,256);
- if(n>0)
- {
- if(strcmp(buffer, "*****")==0)
- startSim();
- }
-}
-
-}// namespace ns3
--- a/codeRev/src/hla/model/LinkToRti/link_to_rti.h Sat Aug 18 15:01:04 2012 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,77 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2012 Mudit Raj Gupta
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Author: Mudit Raj Gupta <mudit.raaj.gupta@gmail.com>
- */
-
-#ifndef LINK_TO_RTI_H
-#define LINK_TO_RTI_H
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <pthread.h>
-
-#define PORT_NO 2201
-
-namespace ns3 {
-
-class link_to_rti
-{
-
-public:
-
-//RTI clock
-static int RTI_CLK;
-static int RTI_START;
-static int RTI_STOP;
-
-// This method is invoked in a different thread, it acts as a link between the JAVA
-//code and the C++ code
-//void* rtiLink(void*);
-
-
-//This methods sends a time advance request from ns-3 to RTI
-void reqTimeAdv(void);
-
-//This method is called when a time advance callback is received
-void timeAdv(void);
-
-//This method is called when the start string is received
-void startSim(void);
-
-//This method is called when the stop string is received
-void stopSim(void);
-
-//This method is called to initialize the socket
-void init_sock(void);
-
-//This method is called to close the socket
-void close_sock(void);
-
-//Temperary Method
-void connectToRTI(void);
-
-};
-
-}// namespace ns3
-
-#endif /*link-to-rti*/
--- a/codeRev/src/hla/model/hla-interface.cc Sat Aug 18 15:01:04 2012 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,55 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2012 Mudit Raj Gupta
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Author: Mudit Raj Gupta <mudit.raaj.gupta@gmail.com>
- */
-
-#include "ns3/hla-interface.h"
-#include "ns3/log.h"
-#include "ns3/pointer.h"
-#include <iostream>
-#include <vector>
-
-using namespace std;
-
-namespace ns3 {
-
-NS_LOG_COMPONENT_DEFINE ("HlaInterface");
-
-HlaInterface::HlaInterface ()
-{
-
-}
-HlaInterface::~HlaInterface ()
-{
-}
-void
-HlaInterface::SetName(string name)
-{
- m_id = name;
- NS_LOG_UNCOND("Yeah!!!");
-}
-
-void
-HlaInterface::AddAttribute(string name, string init)
-{
- m_attributes.push_back(name);
- m_values.push_back(init);
- NS_LOG_UNCOND("Yeah!!!");
-}
-
-} // namespace ns3
--- a/codeRev/src/hla/model/hla-interface.h Sat Aug 18 15:01:04 2012 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,79 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2012 Mudit Raj Gupta
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Author: Mudit Raj Gupta <mudit.raaj.gupta@gmail.com>
- */
-
-#include <iostream>
-#include <vector>
-#include <string>
-
-#ifndef HLA_INTERFACE_H
-#define HLA_INTERFACE_H
-
-using namespace std;
-
-namespace ns3 {
-
-/**
- * \ingroup hla
- * \brief class to help create a hla interface
- */
-
-class HlaInterface
-{
-public:
- /**
- * Construct a hla interface to make it easier when working
- * with HLA.
- */
- HlaInterface ();
-
- /**
- * \internal
- * Destroy a hla interface
- */
- ~HlaInterface ();
-
- /**
- * Create an attribute of the created object
- *
- * \param name name of the attribute
- * \param init initial value
- */
- void AddAttribute (string name, string init);
-
- /**
- * Create an attribute of the created object
- *
- * \param name name of the attribute
- * \param init initial value
- */
- void SetName (string name);
- //private:
- /**
- * \internal
- */
- //static void HlaInitialize (void);
- vector<string> m_attributes;
- vector<string> m_values;
- string m_id;
-};
-
-} // namespace ns3
-
-#endif /* HLA_INTERFACE_H */
--- a/codeRev/src/hla/model/ns3Federate/linux.sh Sat Aug 18 15:01:04 2012 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,77 +0,0 @@
-#!/bin/bash
-
-USAGE="usage: linux.sh [compile] [clean] [execute [federate-name]]"
-
-################################
-# check command line arguments #
-################################
-if [ $# = 0 ]
-then
- echo $USAGE
- exit;
-fi
-
-######################
-# test for JAVA_HOME #
-######################
-JAVA=java
-if [ "$JAVA_HOME" = "" ]
-then
- echo WARNING Your JAVA_HOME environment variable is not set!
- #exit;
-else
- JAVA=$JAVA_HOME/bin/java
-fi
-
-#####################
-# test for RTI_HOME #
-#####################
-if [ "$RTI_HOME" = "" ]
-then
- cd ../../RTI
- RTI_HOME=$PWD
- export RTI_HOME
- cd ../model/ns3Federate
- echo WARNING Your RTI_HOME environment variable is not set, assuming $RTI_HOME
-fi
-
-############################################
-### (target) clean #########################
-############################################
-
-if [ $1 = "clean" ]
-then
- echo "deleting ns3Federate jar file and left over logs"
- rm src/*.class
- rm ns3Federate.jar
- rm -Rf logs
- exit;
-fi
-
-############################################
-### (target) compile #######################
-############################################
-
-if [ $1 = "compile" ]
-then
- echo "compiling ns3Federate"
- cd src
- javac -cp ./:$RTI_HOME/lib/portico.jar *.java
- jar -cf ../ns3Federate.jar *.class
- cd ../
- exit;
-fi
-
-############################################
-### (target) execute #######################
-############################################
-
-if [ $1 = "execute" ]
-then
- shift;
- java -cp ./ns3Federate.jar:$RTI_HOME/lib/portico.jar ns3Federate $*
- exit;
-fi
-
-echo $USAGE
-
Binary file codeRev/src/hla/model/ns3Federate/ns3Federate.jar has changed
--- a/codeRev/src/hla/model/ns3Federate/src/ns3FedAmb.java Sat Aug 18 15:01:04 2012 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,345 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2012 Mudit Raj Gupta
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * This class handles all the callbacks for the ns3Federate. On each callback, it will
- * just create a string describing the event and add that string to a list of events that have
- * happened. At the end of processing, the contents of this list can be printed so we can see
- * exactly what events happened in what order.
- *
- * Author: Mudit Raj Gupta <mudit.raaj.gupta@gmail.com>
- *
- */
-
-import java.util.ArrayList;
-import java.util.List;
-
-import hla.rti.EventRetractionHandle;
-import hla.rti.LogicalTime;
-import hla.rti.ReceivedInteraction;
-import hla.rti.ReflectedAttributes;
-import hla.rti.jlc.EncodingHelpers;
-import hla.rti.jlc.NullFederateAmbassador;
-
-import org.portico.impl.hla13.types.DoubleTime;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.Socket;
-
-
-
-public class ns3FedAmb extends NullFederateAmbassador
-{
-
- //socket related variables
- public Socket socketClient;
- public OutputStream oStream=null;
- public InputStream iStream=null;
- private String bufferReceiveString;
- private byte[] bufferReceiveByte=new byte[2000];
- public static String rtiAddressDefault="127.0.0.1";
- public String comnet="127.0.0.1";
-
- //counters and flags
- private int count=0;
- public int msgNum=1;
- private int val=0;
- private int offset=0;
- //federate's state variables
- protected double federateTime = 0.0;
- protected double federateLookahead = 1.0;
-
- protected boolean isRegulating = false;
- protected boolean isConstrained = false;
- protected boolean isAdvancing = false;
-
- protected boolean isAnnounced = false;
- protected boolean isReadyToRun = false;
-
- protected List<String> events = new ArrayList<String>();
-
-
- //constructor
- public ns3FedAmb()
- {
- System.setProperty("portico.lrc.connection", "org.portico.binding.jsop.lrc.JSOPClientConnection");
- System.setProperty("portico.lrc.jsop.host", "127.0.0.1");
- System.out.println(System.getProperty("portico.lrc.jsop.host"));
- }
-
- private double convertTime( LogicalTime logicalTime )
- {
- return ((DoubleTime)logicalTime).getTime();
- }
-
- //adding events to queue
- private synchronized void queue( String message )
- {
- events.add( message );
- }
-
- //CALL BACKS
- public void synchronizationPointRegistrationFailed( String label )
- {
- queue( "Failed to register sync point: " + label );
- }
-
- public void synchronizationPointRegistrationSucceeded( String label )
- {
- queue( "Successfully registered sync point: " + label );
- }
-
- public void announceSynchronizationPoint( String label, byte[] tag )
- {
- queue( "Synchronization point announced: " + label );
- if( label.equals(ns3Federate.READY_TO_RUN) )
- this.isAnnounced = true;
- }
-
- public void federationSynchronized( String label )
- {
- queue( "Federation Synchronized: " + label );
- if( label.equals(ns3Federate.READY_TO_RUN) )
- this.isReadyToRun = true;
- }
-
- // The RTI has informed us that time regulation is now enabled.
- public void timeRegulationEnabled( LogicalTime theFederateTime )
- {
- this.federateTime = convertTime( theFederateTime );
- this.isRegulating = true;
- queue( "Regulation Enabled: time=" + federateTime );
- }
-
- public void timeConstrainedEnabled( LogicalTime theFederateTime )
- {
- this.federateTime = convertTime( theFederateTime );
- this.isConstrained = true;
- queue( "Constrained Enabled: time=" + federateTime );
- }
-
- //Time Advance Granted
- public void timeAdvanceGrant( LogicalTime theTime )
- {
- Ns3TimeAdv();
- this.federateTime = convertTime( theTime );
- this.isAdvancing = false;
- queue( "ADVANCE("+federateTime+") Granted: time=" + federateTime );
- }
-
- public void discoverObjectInstance( int theObject,
- int theObjectClass,
- String objectName )
- {
- queue( "DISCOVERY objectHandle=" + theObject + ", classHandle=" +
- theObjectClass + ", name=" + objectName );
- }
-
- public void reflectAttributeValues( int theObject,
- ReflectedAttributes theAttributes,
- byte[] tag )
- {
- // just pass it on to the other method for printing purposes
- // passing null as the time will let the other method know it
- // it from us, not from the RTI
- reflectAttributeValues( theObject, theAttributes, tag, null, null );
-
- }
-
- public void reflectAttributeValues( int theObject,
- ReflectedAttributes theAttributes,
- byte[] tag,
- LogicalTime theTime,
- EventRetractionHandle retractionHandle )
- {
- String send,send1;
- String start = "REFLECTION(RO) objectHandle=";
- if( theTime != null )
- start = "REFLECTION("+theTime+") objectHandle=";
- StringBuilder builder = new StringBuilder( start );
- builder.append( theObject );
- builder.append( ", tag=" + EncodingHelpers.decodeString(tag) );
- builder.append( ", attributes=" + theAttributes.size() );
- if( theTime != null )
- {
- builder.append( ", time=" + convertTime(theTime) );
- builder.append( " {TIMESTAMPED}" );
- }
-
- try
- {
- send1 = "Time = "+federateTime+"::"+EncodingHelpers.decodeString(theAttributes.getValue(0))+"::";
- send=send1+EncodingHelpers.decodeString(theAttributes.getValue(1));
- TellNs3(send);
- queue(EncodingHelpers.decodeString(theAttributes.getValue(0)));
- queue(EncodingHelpers.decodeString(theAttributes.getValue(1)));
- }
- catch(Exception e)
- {
- System.out.println("ERRORE PS: " + e);
- }
-
- System.out.println( events.get(val) );
- val++;
- queue( builder.toString() );
- }
-
- public void removeObjectInstance( int theObject, byte[] userSuppliedTag )
- {
- queue( "REMOVE objectHandle=" + theObject );
- }
-
- public void removeObjectInstance( int theObject,
- byte[] userSuppliedTag,
- LogicalTime theTime,
- EventRetractionHandle retractionHandle )
- {
- queue( "REMOVE("+theTime+") objectHandle=" + theObject +
- ", time=" + convertTime(theTime) + " {TIMESTAMPED}");
- }
-
- //sends the start sequence to ns3 and instructs it to start
- public void StartNs3()
- {
- count++;
- String oo="*****";
- try
- {
- oStream.write((oo).getBytes());}
- catch (IOException e)
- {
- e.printStackTrace();
- }
- }
-
- //everytime a time advance is received from the RTI ns3 is informed to make the RTI_CLK tick
- private void Ns3TimeAdv()
- {
- count++;
- String oo="#####";
- try
- {
- oStream.write((oo).getBytes());}
- catch (IOException e)
- {
- e.printStackTrace();
- }
- }
-
- //Message is send if a callback is received from RTI
- private void TellNs3(String s)
- {
- System.out.println(count);
- try
- {
- oStream.write((s).getBytes());
- }
- catch (IOException e)
- {
- e.printStackTrace();
- }
- }
-
- //At the end of the simulation a stopping string is send to ns3
- public void StopNs3()
- {
- try
- {
- String temp="+++++";
- this.oStream.write((temp).getBytes());
- }
- catch (IOException e)
- {
- e.printStackTrace();
- }
- CloseSock();
- }
-
- //The method handles requests from ns3
- public void AskNs3()
- {
- try
- {
-
-
- while(!(new String(bufferReceiveByte).contains("***")))
- {
- this.iStream.read(bufferReceiveByte,offset,1);
- offset++;
- }
- }
- catch (IOException e)
- {
- e.printStackTrace();
- }
- System.out.println(bufferReceiveString);
- bufferReceiveString=null;
- bufferReceiveByte=new byte[2000];
- }
-
- //At present a dummy method to mimic a time advance request
- public void readTimeAdv()
- {
- //String x;
- //byte[] x=new byte[1];
-try{
-iStream.read(bufferReceiveByte,offset,1);
-offset++;
- }
-catch (IOException e)
- {
-
- e.printStackTrace();
- }
- //bufferReceiveString=new String(bufferReceiveByte);
- //if(bufferReceiveString.equals("1"))
- //return true;
- //else
- //return false;
- }
-
- //Method to initialize sockets
- public void TellInitialize()
- {
- try
- {
- socketClient = new Socket(comnet, 2201);
- oStream = socketClient.getOutputStream();
- iStream = socketClient.getInputStream();
- }
- catch (Exception e)
- {
- System.out.println("ERRORE PS: " + e);
- }
- }
-
- //Method to close socket section
- public void CloseSock()
- {
- try
- {
- socketClient.close();
- }
- catch (Exception e)
- {
- System.out.println("ERRORE PS: " + e);
- }
- }
-
-
-}
--- a/codeRev/src/hla/model/ns3Federate/src/ns3Federate.java Sat Aug 18 15:01:04 2012 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,360 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2012 Mudit Raj Gupta
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * It stores up information about all the messages it receives as callbacks
- * and logs them at the end of execution (in order).
- *
- * Authors: Mudit Raj Gupta <mudit.raaj.gupta@gmail.com>
- *
- */
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.InputStreamReader;
-import java.net.MalformedURLException;
-
-import hla.rti.AttributeHandleSet;
-import hla.rti.FederatesCurrentlyJoined;
-import hla.rti.FederationExecutionAlreadyExists;
-import hla.rti.FederationExecutionDoesNotExist;
-import hla.rti.LogicalTime;
-import hla.rti.LogicalTimeInterval;
-import hla.rti.RTIambassador;
-import hla.rti.RTIexception;
-import hla.rti.ResignAction;
-import hla.rti.SuppliedAttributes;
-import hla.rti.SuppliedParameters;
-import hla.rti.jlc.EncodingHelpers;
-import hla.rti.jlc.RtiFactoryFactory;
-
-import org.portico.impl.hla13.types.DoubleTime;
-import org.portico.impl.hla13.types.DoubleTimeInterval;
-
-
-public class ns3Federate
-{
-
- //Length of simulation
- public static final int ITERATIONS = 20;
-
- // The sync point all federates will sync up on before starting
- public static final String READY_TO_RUN = "ReadyToRun";
-
- //For accessing other classes
- private RTIambassador rtiamb;
- private ns3FedAmb fedamb;
-
-
- //This is just a helper method to make sure all logging it output in the same form
- private void log( String message )
- {
- System.out.println( "ns3 : " + message );
- }
-
- //This method will block until the user presses enter
- private void waitForUser()
- {
- log( " >>>>>>>>>> Press Enter to Continue <<<<<<<<<<" );
- BufferedReader reader = new BufferedReader( new InputStreamReader(System.in) );
- try
- {
- reader.readLine();
- }
- catch( Exception e )
- {
- log( "Error while waiting for user input: " + e.getMessage() );
- e.printStackTrace();
- }
- }
-
- // As all time-related code is Portico-specific, it is isolated into a
- // single method. For a different RTI, change this code, rather than more
- // code throughout the whole class.
- //
-
- private LogicalTime convertTime( double time )
- {
- // PORTICO SPECIFIC!!
- return new DoubleTime( time );
- }
-
- private LogicalTimeInterval convertInterval( double time )
- {
- // PORTICO SPECIFIC!!
- return new DoubleTimeInterval( time );
- }
-
-
- //This is the main simulation loop.
- public void runFederate( String federateName ) throws RTIexception
- {
-
- //create the RTIambassador
- rtiamb = RtiFactoryFactory.getRtiFactory().createRtiAmbassador();
-
- // create the federation
- // NOTE: some other federate may have already created the federation,
- // in that case, we'll just try and join it
- //
-
- try
- {
- File fom = new File( "testfom.fed" );
- rtiamb.createFederationExecution( "ExampleFederation",
- fom.toURI().toURL() );
- log( "Created Federation" );
- }
-
- catch( FederationExecutionAlreadyExists exists )
- {
- log( "Didn't create federation, it already existed" );
- }
-
- catch( MalformedURLException urle )
- {
- log( "Exception processing fom: " + urle.getMessage() );
- urle.printStackTrace();
- return;
- }
-
- //join the federation
- // create the federate ambassador and join the federation
-
- fedamb = new ns3FedAmb();
- rtiamb.joinFederationExecution( federateName, "ExampleFederation", fedamb );
- log( "Joined Federation as " + federateName );
-
- //announce the sync point
- // announce a sync point to get everyone on the same page. if the point
- // has already been registered, we'll get a callback saying it failed,
- // but we don't care about that, as long as someone registered it
- rtiamb.registerFederationSynchronizationPoint( READY_TO_RUN, null );
-
- // wait until the point is announced
- while( fedamb.isAnnounced == false )
- {
- rtiamb.tick();
- }
-
- // WAIT FOR USER TO KICK US OFF
- // So that there is time to add other federates, we will wait until the
- // user hits enter before proceeding.
- waitForUser();
-
- //achieve the point and wait for synchronization
- // tell the RTI we are ready to move past the sync point and then wait
- // until the federation has synchronized on
-
- rtiamb.synchronizationPointAchieved( READY_TO_RUN );
- log( "Achieved sync point: " +READY_TO_RUN+ ", waiting for federation..." );
- while( fedamb.isReadyToRun == false )
- {
- rtiamb.tick();
- }
-
- //enable time policies
- // in this section we enable/disable all time policies
- // note that this step is optional!
- enableTimePolicy();
- log( "Time Policy Enabled" );
-
- //publish and subscribe
- // in this section we tell the RTI of all the data we are going to
- // produce, and all the data we want to know about
- publishAndSubscribe();
- log( "Published and Subscribed" );
-
- //register an object to update
- int objectHandle = registerObject();
- log( "Registered Object, handle=" + objectHandle );
-
- //Tell ns3 main code to intialize a socket
- fedamb.TellInitialize();
-
- //Tell ns3 to start the simulation
- fedamb.StartNs3();
-
- // do the main simulation loop
- // here is where we do the meat of our work. in each iteration, we will
- // update the attribute values of the object we registered.
-
- for( int i = 0; i < ITERATIONS; i++ )
- {
- //request a time advance and wait until we get it
- fedamb.readTimeAdv();
- advanceTime(1.0);/*fedamb.readTimeAdv() );*/
- log( "Time Advanced to " + fedamb.federateTime );
- if(i==(ITERATIONS-1))
- fedamb.StopNs3();
- }
-
- //delete the object we created
- deleteObject( objectHandle );
- log( "Deleted Object, handle=" + objectHandle );
-
- //resign from the federation
- rtiamb.resignFederationExecution( ResignAction.NO_ACTION );
- log( "Resigned from Federation" );
-
- // try and destroy the federation
- // NOTE: we won't die if we can't do this because other federates
- // remain. in that case we'll leave it for them to clean up
-
- try
- {
- rtiamb.destroyFederationExecution( "ExampleFederation" );
- log( "Destroyed Federation" );
- }
- catch( FederationExecutionDoesNotExist dne )
- {
- log( "No need to destroy federation, it doesn't exist" );
- }
- catch( FederatesCurrentlyJoined fcj )
- {
- log( "Didn't destroy federation, federates still joined" );
- }
-
- // print out all the events
- System.out.println( " ================= Ordered Event List =================" );
- for( int i = 0; i < fedamb.events.size(); i++ )
- System.out.println( "["+i+"]: " + fedamb.events.get(i) );
- System.out.println( " ======================================================" );
- }
-
- // Helper Methods
-
- // This method will attempt to enable the various time related properties for
- // the federate
- //
- private void enableTimePolicy() throws RTIexception
- {
- // NOTE: Unfortunately, the LogicalTime/LogicalTimeInterval create code is
- // Portico specific.
- LogicalTime currentTime = convertTime( fedamb.federateTime );
- LogicalTimeInterval lookahead = convertInterval( fedamb.federateLookahead );
-
- // enable time regulation
- this.rtiamb.enableTimeRegulation( currentTime, lookahead );
-
- // tick until we get the callback
- while( fedamb.isRegulating == false )
- {
- rtiamb.tick();
- }
-
- // enable time constrained
- this.rtiamb.enableTimeConstrained();
-
- // tick until we get the callback
- while( fedamb.isConstrained == false )
- {
- rtiamb.tick();
- }
- }
-
- // This method will inform the RTI about the types of data that the federate will
- // be creating, and the types of data we are interested in hearing about as other
- // federates produce it.
-
- private void publishAndSubscribe() throws RTIexception
- {
- // publish all attributes of ObjectRoot.PingPong
- // before we can register instance of the object class ObjectRoot.PingPong and
- // update the values of the various attributes, we need to tell the RTI
- // that we intend to publish this information
- // get all the handle information for the attributes of ObjectRoot.A
-
- int classHandle = rtiamb.getObjectClassHandle( "ObjectRoot.PingPong" );
- int MsgTypeHandle = rtiamb.getAttributeHandle( "MsgType", classHandle );
- int MsgHandle = rtiamb.getAttributeHandle( "Msg", classHandle );
-
- AttributeHandleSet attributes =
- RtiFactoryFactory.getRtiFactory().createAttributeHandleSet();
- attributes.add( MsgTypeHandle );
- attributes.add( MsgHandle );
-
- // do the actual publication
- rtiamb.publishObjectClass( classHandle, attributes );
-
- // subscribe to all attributes of ObjectRoot.PingPong
- // we also want to hear about the same sort of information as it is
- // created and altered in other federates, so we need to subscribe to it
- rtiamb.subscribeObjectClassAttributes( classHandle, attributes );
-
- }
-
- // This method will register an instance of the class ObjectRoot.A and will
- // return the federation-wide unique handle for that instance. Later in the
- // simulation, we will update the attribute values for this instance
-
- private int registerObject() throws RTIexception
- {
- int classHandle = rtiamb.getObjectClassHandle( "ObjectRoot.PingPong" );
- return rtiamb.registerObjectInstance( classHandle );
- }
-
- // This method will request a time advance to the current time, plus the given
- // timestep. It will then wait until a notification of the time advance grant
- // has been received.
-
- private void advanceTime( double timestep ) throws RTIexception
- {
- // request the advance
- fedamb.isAdvancing = true;
- LogicalTime newTime = convertTime( fedamb.federateTime + timestep );
- rtiamb.timeAdvanceRequest( newTime );
-
- // wait for the time advance to be granted. ticking will tell the
- // LRC to start delivering callbacks to the federate
- while( fedamb.isAdvancing )
- {
- rtiamb.tick();
- }
-
- }
-
- // This method will attempt to delete the object instance of the given
- // handle. We can only delete objects we created, or for which we own the
- // privilegeToDelete attribute.
-
- private void deleteObject( int handle ) throws RTIexception
- {
- rtiamb.deleteObjectInstance( handle, null );
- }
-
- //Main Function
- public static void main( String[] args )
- {
- // setFederateName as ns3
- String federateName = "ns3";
- if( args.length != 0 )
- {
- federateName = args[0];
- }
-
- try
- {
- // run the example federate
- new ns3Federate().runFederate( federateName );
- }
- catch( RTIexception rtie )
- {
- // an exception occurred, just log the information and exit
- rtie.printStackTrace();
- }
- }
-}
--- a/codeRev/src/hla/model/ns3Federate/testfom.fed Sat Aug 18 15:01:04 2012 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,50 +0,0 @@
-;; A comment in the test file, just to show I'm cool ;;
-(FED
- (Federation Portico-Test)
- (FEDversion v1.3)
- (spaces
- (space TestSpace
- (dimension TestDimension)
- )
- (space OtherSpace
- (dimension OtherDimension)
- )
- )
- (objects
- (class ObjectRoot
- (attribute privilegeToDelete reliable timestamp)
- (class RTIprivate)
- (class PingPong
- (attribute MsgType reliable timestamp TestSpace) ;; more comments!
- (attribute Msg reliable timestamp TestSpace)
- (attribute ac reliable timestamp TestSpace)
- (class B
- (attribute ba reliable timestamp TestSpace)
- (attribute bb reliable timestamp TestSpace)
- (attribute bc reliable timestamp TestSpace)
- )
- )
- )
- )
- (interactions
- (class InteractionRoot reliable timestamp
- (class RTIprivate reliable timestamp)
- (class X reliable timestamp TestSpace
- (parameter xa)
- (parameter xb)
- (parameter xc)
- (class Y reliable timestamp ;; note the absence of any space definition
- (parameter ya)
- (parameter yb)
- (parameter yc)
- (class Z reliable timestamp TestSpace
- (parameter za)
- (parameter zb)
- (parameter zc)
- )
- )
- )
- )
- )
-)
-
--- a/codeRev/src/hla/model/rti-clock-synchronizer.cc Sat Aug 18 15:01:04 2012 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,431 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2008 University of Washington
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <time.h>
-#include <sys/time.h>
-
-#include "ns3/log.h"
-#include "ns3/system-condition.h"
-
-#include "ns3/rti-clock-synchronizer.h"
-#include "ns3/link_to_rti.h"
-
-NS_LOG_COMPONENT_DEFINE ("RtiClockSynchronizer");
-
-namespace ns3 {
-
-link_to_rti obj;
-//int link_to_rti::RTI_CLK;
-
-RtiClockSynchronizer::RtiClockSynchronizer ()
-{
- NS_LOG_FUNCTION_NOARGS ();
-//
-// In Linux, the basic timekeeping unit is derived from a variable called HZ
-// HZ is the frequency in hertz of the system timer. The system timer fires
-// every 1/HZ seconds and a counter, called the jiffies counter is incremented
-// at each tick. The time between ticks is called a jiffy (American slang for
-// a short period of time). The ticking of the jiffies counter is how the
-// the kernel tells time.
-//
-// Now, the shortest time the kernel can sleep is one jiffy since a timer
-// has to be set to expire and trigger the process to be made ready. The
-// Posix clock CLOCK_REALTIME is defined as a 1/HZ clock, so by doing a
-// clock_getres () on the realtime clock we can infer the scheduler quantum
-// and the minimimum sleep time for the system. This is most certainly NOT
-// going to be one nanosecond even though clock_nanosleep () pretends it is.
-//
-// The reason this number is important is that we are going to schedule lots
-// of waits for less time than a jiffy. The clock_nanosleep function is
-// going to guarantee that it will sleep for AT LEAST the time specified.
-// The least time that it will sleep is a jiffy.
-//
-// In order to deal with this, we are going to do a spin-wait if the simulator
-// requires a delay less than a jiffy. This is on the order of one millisecond
-// (999848 ns) on the ns-regression machine.
-//
-// If the underlying OS does not support posix clocks, we'll just assume a
-// one millisecond quantum and deal with this as best we can
-
-#ifdef CLOCK_REALTIME
- struct timespec ts;
- clock_getres (CLOCK_REALTIME, &ts);
- m_jiffy = ts.tv_sec * NS_PER_SEC + ts.tv_nsec;
- NS_LOG_INFO ("Jiffy is " << m_jiffy << " ns");
-#else
- m_jiffy = 1000000;
-#endif
-}
-
-RtiClockSynchronizer::~RtiClockSynchronizer ()
-{
- NS_LOG_FUNCTION_NOARGS ();
-}
-
-bool
-RtiClockSynchronizer::DoRealtime (void)
-{
- NS_LOG_FUNCTION_NOARGS ();
- return true;
-}
-
-uint64_t
-RtiClockSynchronizer::DoGetCurrentRealtime (void)
-{
- NS_LOG_FUNCTION_NOARGS ();
- return GetNormalizedRealtime ();
-}
-
-void
-RtiClockSynchronizer::DoSetOrigin (uint64_t ns)
-{
- NS_LOG_FUNCTION_NOARGS ();
-//
-// In order to make sure we're really locking the simulation time to some
-// wall-clock time, we need to be able to compare that simulation time to
-// that wall-clock time. The wall clock will have been running for some
-// long time and will probably have a huge count of nanoseconds in it. We
-// save the real time away so we can subtract it from "now" later and get
-// a count of nanoseconds in real time since the simulation started.
-//
- m_realtimeOriginNano = GetRealtime ();
- NS_LOG_INFO ("origin = " << m_realtimeOriginNano);
-}
-
-int64_t
-RtiClockSynchronizer::DoGetDrift (uint64_t ns)
-{
- NS_LOG_FUNCTION_NOARGS ();
-//
-// In order to make sure we're really locking the simulation time to some
-// wall-clock time, we need to be able to compare that simulation time to
-// that wall-clock time. In DoSetOrigin we saved the real time at the start
-// of the simulation away. This is the place where we subtract it from "now"
-// to a count of nanoseconds in real time since the simulation started. We
-// then subtract the current real time in normalized nanoseconds we just got
-// from the normalized simulation time in nanoseconds that is passed in as
-// the parameter ns. We return an integer difference, but in reality all of
-// the mechanisms that cause wall-clock to simuator time drift cause events
-// to be late. That means that the wall-clock will be higher than the
-// simulation time and drift will be positive. I would be astonished to
-// see a negative drift, but the possibility is admitted for other
-// implementations; and we'll use the ability to report an early result in
-// DoSynchronize below.
-//
- uint64_t nsNow = GetNormalizedRealtime ();
-
- if (nsNow > ns)
- {
-//
-// Real time (nsNow) is larger/later than the simulator time (ns). We are
-// behind real time and the difference (drift) is positive.
-//
- return (int64_t)(nsNow - ns);
- }
- else
- {
-//
-// Real time (nsNow) is smaller/earlier than the simulator time (ns). We are
-// ahead of real time and the difference (drift) is negative.
-//
- return -(int64_t)(ns - nsNow);
- }
-}
-
-bool
-RtiClockSynchronizer::DoSynchronize (uint64_t nsCurrent, uint64_t nsDelay)
-{
- NS_LOG_FUNCTION_NOARGS ();
-//
-// This is the belly of the beast. We have received two parameters from the
-// simulator proper -- a current simulation time (nsCurrent) and a simulation
-// time to delay which identifies the time the next event is supposed to fire.
-//
-// The first thing we need to do is to (try and) correct for any realtime
-// drift that has happened in the system. In this implementation, we realize
-// that all mechanisms for drift will cause the drift to be such that the
-// realtime is greater than the simulation time. This typically happens when
-// our process is put to sleep for a given time, but actually sleeps for
-// longer. So, what we want to do is to "catch up" to realtime and delay for
-// less time than we are actually asked to delay. DriftCorrect will return a
-// number from 0 to nsDelay corresponding to the amount of catching-up we
-// need to do. If we are more than nsDelay behind, we do not wait at all.
-//
-// Note that it will be impossible to catch up if the amount of drift is
-// cumulatively greater than the amount of delay between events. The method
-// GetDrift () is available to clients of the syncrhonizer to keep track of
-// the cumulative drift. The client can assert if the drift gets out of
-// hand, print warning messages, or just ignore the situation and hope it will
-// go away.
-//
- uint64_t ns = DriftCorrect (nsCurrent, nsDelay);
- NS_LOG_INFO ("Synchronize ns = " << ns);
-//
-// Once we've decided on how long we need to delay, we need to split this
-// time into sleep waits and busy waits. The reason for this is described
-// in the comments for the constructor where jiffies and jiffy resolution is
-// explained.
-//
-// Here, I'll just say that we need that the jiffy is the minimum resolution
-// of the system clock. It can only sleep in blocks of time equal to a jiffy.
-// If we want to be more accurate than a jiffy (we do) then we need to sleep
-// for some number of jiffies and then busy wait for any leftover time.
-//
- uint64_t numberJiffies = ns / m_jiffy;
- NS_LOG_INFO ("Synchronize numberJiffies = " << numberJiffies);
-//
-// This is where the real world interjects its very ugly head. The code
-// immediately below reflects the fact that a sleep is actually quite probably
-// going to end up sleeping for some number of jiffies longer than you wanted.
-// This is because your system is going to be off doing other unimportant
-// stuff during that extra time like running file systems and networks. What
-// we want to do is to ask the system to sleep enough less than the requested
-// delay so that it comes back early most of the time (coming back early is
-// fine, coming back late is bad). If we can convince the system to come back
-// early (most of the time), then we can busy-wait until the requested
-// completion time actually comes around (most of the time).
-//
-// The tradeoff here is, of course, that the less time we spend sleeping, the
-// more accurately we will sync up; but the more CPU time we will spend busy
-// waiting (doing nothing).
-//
-// I'm not really sure about this number -- a boss of mine once said, "pick
-// a number and it'll be wrong." But this works for now.
-//
-// XXX BUGBUG Hardcoded tunable parameter below.
-//
- if (numberJiffies > 3)
- {
- NS_LOG_INFO ("SleepWait for " << numberJiffies * m_jiffy << " ns");
- NS_LOG_INFO ("SleepWait until " << nsCurrent + numberJiffies * m_jiffy
- << " ns");
-//
-// SleepWait is interruptible. If it returns true it meant that the sleep
-// went until the end. If it returns false, it means that the sleep was
-// interrupted by a Signal. In this case, we need to return and let the
-// simulator re-evaluate what to do.
-//
- if (SleepWait ((numberJiffies - 3) * m_jiffy) == false)
- {
- NS_LOG_INFO ("SleepWait interrupted");
- return false;
- }
- }
- NS_LOG_INFO ("Done with SleepWait");
-//
-// We asked the system to sleep for some number of jiffies, but that doesn't
-// mean we actually did. Let's re-evaluate what we need to do here. Maybe
-// we're already late. Probably the "real" delay time left has little to do
-// with what we would calculate it to be naively.
-//
-// We are now at some Realtime. The important question now is not, "what
-// would we calculate in a mathematicians paradise," it is, "how many
-// nanoseconds do we need to busy-wait until we get to the Realtime that
-// corresponds to nsCurrent + nsDelay (in simulation time). We have a handy
-// function to do just that -- we ask for the time the realtime clock has
-// drifted away from the simulation clock. That's our answer. If the drift
-// is negative, we're early and we need to busy wait for that number of
-// nanoseconds. The place were we want to be is described by the parameters
-// we were passed by the simulator.
-//
- int64_t nsDrift = DoGetDrift (nsCurrent + nsDelay);
-//
-// If the drift is positive, we are already late and we need to just bail out
-// of here as fast as we can. Return true to indicate that the requested time
-// has, in fact, passed.
-//
- if (nsDrift >= 0)
- {
- NS_LOG_INFO ("Back from SleepWait: IML8 " << nsDrift);
- return true;
- }
-//
-// There are some number of nanoseconds left over and we need to wait until
-// the time defined by nsDrift. We'll do a SpinWait since the usual case
-// will be that we are doing this Spinwait after we've gotten a rough delay
-// using the SleepWait above. If SpinWait completes to the end, it will
-// return true; if it is interrupted by a signal it will return false.
-//
- NS_LOG_INFO ("SpinWait until " << nsCurrent + nsDelay);
- return SpinWait (nsCurrent + nsDelay);
-}
-
-void
-RtiClockSynchronizer::DoSignal (void)
-{
- NS_LOG_FUNCTION_NOARGS ();
-
- m_condition.SetCondition (true);
- m_condition.Signal ();
-}
-
-void
-RtiClockSynchronizer::DoSetCondition (bool cond)
-{
- NS_LOG_FUNCTION_NOARGS ();
- m_condition.SetCondition (cond);
-}
-
-void
-RtiClockSynchronizer::DoEventStart (void)
-{
- NS_LOG_FUNCTION_NOARGS ();
- m_nsEventStart = GetNormalizedRealtime ();
-}
-
-uint64_t
-RtiClockSynchronizer::DoEventEnd (void)
-{
- NS_LOG_FUNCTION_NOARGS ();
- return GetNormalizedRealtime () - m_nsEventStart;
-}
-
-bool
-RtiClockSynchronizer::SpinWait (uint64_t ns)
-{
- NS_LOG_FUNCTION_NOARGS ();
-//
-// Do a busy-wait until the normalized realtime equals the value passed in
-// or the condition variable becomes true. The condition becomes true if
-// an outside entity (a network device receives a packet, sets the condition
-// and signals the scheduler it needs to re-evaluate).
-//
-// We just sit here and spin, wasting CPU cycles until we get to the right
-// time or are told to leave.
-//
- for (;;)
- {
- if (GetNormalizedRealtime () >= ns)
- {
- return true;
- }
- if (m_condition.GetCondition ())
- {
- return false;
- }
- }
-// Quiet compiler
- return true;
-}
-
-bool
-RtiClockSynchronizer::SleepWait (uint64_t ns)
-{
- NS_LOG_FUNCTION_NOARGS ();
-//
-// Put our process to sleep for some number of nanoseconds. Typically this
-// will be some time equal to an integral number of jiffies. We will usually
-// follow a call to SleepWait with a call to SpinWait to get the kind of
-// accuracy we want.
-//
-// We have to have some mechanism to wake up this sleep in case an external
-// event happens that causes a schedule event in the simulator. This newly
-// scheduled event might be before the time we are waiting until, so we have
-// to break out of both the SleepWait and the following SpinWait to go back
-// and reschedule/resynchronize taking the new event into account. The
-// SystemCondition we have saved in m_condition takes care of this for us.
-//
-// This call will return if the timeout expires OR if the condition is
-// set true by a call to WallClockSynchronizer::SetCondition (true) followed
-// by a call to WallClockSynchronizer::Signal(). In either case, we are done
-// waiting. If the timeout happened, we TimedWait returns true; if a Signal
-// happened, false.
-//
- return m_condition.TimedWait (ns);
-}
-
-uint64_t
-RtiClockSynchronizer::DriftCorrect (uint64_t nsNow, uint64_t nsDelay)
-{
- int64_t drift = DoGetDrift (nsNow);
-//
-// If we're running late, drift will be positive and we need to correct by
-// delaying for less time. If we're early for some bizarre reason, we don't
-// do anything since we'll almost instantly self-correct.
-//
- if (drift < 0)
- {
- return nsDelay;
- }
-//
-// If we've drifted out of sync by less than the requested delay, then just
-// subtract the drift from the delay and fix up the drift in one go. If we
-// have more drift than delay, then we just play catch up as fast as possible
-// by not delaying at all.
-//
- uint64_t correction = (uint64_t)drift;
- if (correction <= nsDelay)
- {
- return nsDelay - correction;
- }
- else
- {
- return 0;
- }
-}
-
-uint64_t
-RtiClockSynchronizer::GetRealtime (void)
-{
-
-//NS_LOG_UNCOND("In sync");
- return obj.RTI_CLK*NS_PER_SEC;
-/*
- struct timeval tvNow;
- gettimeofday (&tvNow, NULL);
- return TimevalToNs (&tvNow);*/
-}
-
-uint64_t
-RtiClockSynchronizer::GetNormalizedRealtime (void)
-{
- return GetRealtime () - m_realtimeOriginNano;
-}
-
-void
-RtiClockSynchronizer::NsToTimeval (int64_t ns, struct timeval *tv)
-{
- NS_ASSERT ((ns % US_PER_NS) == 0);
- tv->tv_sec = ns / NS_PER_SEC;
- tv->tv_usec = (ns % NS_PER_SEC) / US_PER_NS;
-}
-
-uint64_t
-RtiClockSynchronizer::TimevalToNs (struct timeval *tv)
-{
- uint64_t nsResult = tv->tv_sec * NS_PER_SEC + tv->tv_usec * US_PER_NS;
- NS_ASSERT ((nsResult % US_PER_NS) == 0);
- return nsResult;
-}
-
-void
-RtiClockSynchronizer::TimevalAdd (
- struct timeval *tv1,
- struct timeval *tv2,
- struct timeval *result)
-{
- result->tv_sec = tv1->tv_sec + tv2->tv_sec;
- result->tv_usec = tv1->tv_usec + tv2->tv_usec;
- if (result->tv_usec > (int64_t)US_PER_SEC)
- {
- ++result->tv_sec;
- result->tv_usec %= US_PER_SEC;
- }
-}
-
-} // namespace ns3
--- a/codeRev/src/hla/model/rti-clock-synchronizer.h Sat Aug 18 15:01:04 2012 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,196 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2008 University of Washington
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef RTI_CLOCK_CLOCK_SYNCHRONIZER_H
-#define RTI_CLOCK_CLOCK_SYNCHRONIZER_H
-
-#include "system-condition.h"
-#include "synchronizer.h"
-
-namespace ns3 {
-
-/**
- * @brief Class used for synchronizing the simulation events to a real-time
- * "wall clock" using Posix Clock functions.
- *
- * Enable this synchronizer using:
- *
- * DefaultValue::Bind ("Synchronizer", "WallClockSynchronizer");
- *
- * before calling any simulator functions.
- *
- * The simulation clock is maintained as a 64-bit integer in a unit specified
- * by the user through the TimeStepPrecision::Set function. This means that
- * it is not possible to specify event expiration times with anything better
- * than this user-specified accuracy.
- *
- * There are a couple of more issues at this level. Posix clocks provide
- * access to several clocks we could use as a wall clock. We don't care about
- * time in the sense of 0430 CEST, we care about some piece of hardware that
- * ticks at some regular period. The most accurate posix clock in this
- * respect is the CLOCK_PROCESS_CPUTIME_ID clock. This is a high-resolution
- * register in the CPU. For example, on Intel machines this corresponds to
- * the timestamp counter (TSC) register. The resolution of this counter will
- * be on the order of nanoseconds.
- *
- * Now, just because we can measure time in nanoseconds doesn't mean we can
- * put our process to sleep to nanosecond resolution. We are eventually going
- * to use the function clock_nanosleep () to sleep until a simulation Time
- * specified by the caller.
- *
- * MORE ON JIFFIES, SLEEP, PROCESSES, etc., as required
- *
- * Nanosleep takes a struct timespec as an input so we have to deal with
- * conversion between Time and struct timespec here. They are both
- * interpreted as elapsed times.
- */
-class RtiClockSynchronizer : public Synchronizer
-{
-public:
- RtiClockSynchronizer ();
- virtual ~RtiClockSynchronizer ();
-
- static const uint64_t US_PER_NS = (uint64_t)1000;
- static const uint64_t US_PER_SEC = (uint64_t)1000000;
- static const uint64_t NS_PER_SEC = (uint64_t)1000000000;
-
-protected:
-/**
- * @brief Return true if this synchronizer is actually synchronizing to a
- * realtime clock. The simulator sometimes needs to know this.
- *
- * @internal
- *
- * Subclasses are expected to implement this method to tell the outside world
- * whether or not they are synchronizing to a realtime clock.
- *
- * @returns True if locked with realtime, false if not.
- */
- virtual bool DoRealtime (void);
-
-/**
- * @brief Retrieve the value of the origin of the underlying normalized wall
- * clock time in nanosecond units.
- *
- * @internal
- *
- * Subclasses are expected to implement this method to do the actual
- * real-time-clock-specific work of getting the current time.
- *
- * @returns The normalized wall clock time (in nanosecond units).
- * @see TimeStepPrecision::Get
- * @see Synchronizer::SetOrigin
- */
- virtual uint64_t DoGetCurrentRealtime (void);
-
-/**
- * @brief Establish a correspondence between a simulation time and a
- * wall-clock (real) time.
- *
- * @internal
- *
- * There are three timelines involved here: the simulation time, the
- * (absolute) wall-clock time and the (relative) synchronizer real time.
- * Calling this method makes a correspondence between the origin of the
- * synchronizer time and the current wall-clock time.
- *
- * This method is expected to be called at the "instant" before simulation
- * begins. At this point, simulation time = 0, and synchronizer time is
- * set = 0 in this method. We then associate this time with the current
- * value of the real time clock that will be used to actually perform the
- * synchronization.
- *
- * Subclasses are expected to implement this method to do the actual
- * real-time-clock-specific work of making the correspondence mentioned above.
- * for example, this is where the differences between Time parameters and
- * parameters to clock_nanosleep would be dealt with.
- *
- * @param ns The simulation time we need to use as the origin (normalized to
- * nanosecond units).
- */
- virtual void DoSetOrigin (uint64_t ns);
-
-/**
- * @brief Declaration of method used to retrieve drift between the real time
- * clock used to synchronize the simulation and the current simulation time.
- *
- * @internal
- *
- * @param ns Simulation timestep from the simulator normalized to nanosecond
- * steps.
- * @returns Drift in nanosecond units.
- * @see TimeStepPrecision::Get
- * @see Synchronizer::SetOrigin
- * @see Synchronizer::GetDrift
- */
- virtual int64_t DoGetDrift (uint64_t ns);
-
-/**
- * @brief Wait until the real time is in sync with the specified simulation
- * time.
- *
- * @internal
- *
- * This is where the real work of synchronization is done. The Time passed
- * in as a parameter is the simulation time. The job of Synchronize is to
- * translate from simulation time to synchronizer time (in a perfect world
- * this is the same time) and then figure out how long in real-time it needs
- * to wait until that synchronizer / simulation time comes around.
- *
- * Subclasses are expected to implement this method to do the actual
- * real-time-clock-specific work of waiting (either busy-waiting or sleeping,
- * or some combination) until the requested simulation time.
- *
- * @param ns The simulation time we need to wait for (normalized to nanosecond
- * units).
- * @see TimeStepPrecision::Get
- */
- virtual bool DoSynchronize (uint64_t nsCurrent, uint64_t nsDelay);
- virtual void DoSignal (void);
- virtual void DoSetCondition (bool cond);
-
- virtual void DoEventStart (void);
- virtual uint64_t DoEventEnd (void);
-
- bool SpinWait (uint64_t);
- bool SleepWait (uint64_t);
-
- uint64_t DriftCorrect (uint64_t nsNow, uint64_t nsDelay);
-
- uint64_t GetRealtime (void);
- uint64_t GetNormalizedRealtime (void);
-
- void NsToTimeval (int64_t ns, struct timeval *tv);
- uint64_t TimevalToNs (struct timeval *tv);
-
- void TimevalAdd (
- struct timeval *tv1,
- struct timeval *tv2,
- struct timeval *result);
-
- uint64_t m_cpuTick;
- uint64_t m_realtimeTick;
- uint64_t m_jiffy;
- uint64_t m_nsEventStart;
-
- SystemCondition m_condition;
-};
-
-} // namespace ns3
-
-#endif /* RTI_CLOCK_SYNCHRONIZER_H */
--- a/codeRev/src/hla/model/rti-simulator-impl.cc Sat Aug 18 15:01:04 2012 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,860 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2008 University of Washington
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "ns3/simulator.h"
-#include "ns3/rti-simulator-impl.h"
-#include "ns3/rti-clock-synchronizer.h"
-#include "ns3/scheduler.h"
-#include "ns3/event-impl.h"
-#include "ns3/synchronizer.h"
-
-#include "ns3/ptr.h"
-#include "ns3/pointer.h"
-#include "ns3/assert.h"
-#include "ns3/fatal-error.h"
-#include "ns3/log.h"
-#include "ns3/system-mutex.h"
-#include "ns3/boolean.h"
-#include "ns3/enum.h"
-
-#include <unistd.h>
-#include <math.h>
-#include <ns3/link_to_rti.h>
-
-NS_LOG_COMPONENT_DEFINE ("RtiSimulatorImpl");
-
-namespace ns3 {
-
-NS_OBJECT_ENSURE_REGISTERED (RtiSimulatorImpl);
-
-link_to_rti o;
-//int link_to_rti::RTI_STOP;
-//void link_to_rti::reqTimeAdv();
-
-TypeId
-RtiSimulatorImpl::GetTypeId (void)
-{
- static TypeId tid = TypeId ("ns3::RtiSimulatorImpl")
- .SetParent<SimulatorImpl> ()
- .AddConstructor<RtiSimulatorImpl> ()
- .AddAttribute ("SynchronizationMode",
- "What to do if the simulation cannot keep up with real time.",
- EnumValue (SYNC_BEST_EFFORT),
- MakeEnumAccessor (&RtiSimulatorImpl::SetSynchronizationMode),
- MakeEnumChecker (SYNC_BEST_EFFORT, "BestEffort",
- SYNC_HARD_LIMIT, "HardLimit"))
- .AddAttribute ("HardLimit",
- "Maximum acceptable real-time jitter (used in conjunction with SynchronizationMode=HardLimit)",
- TimeValue (Seconds (0.1)),
- MakeTimeAccessor (&RtiSimulatorImpl::m_hardLimit),
- MakeTimeChecker ())
- ;
- return tid;
-}
-
-
-RtiSimulatorImpl::RtiSimulatorImpl ()
-{
- NS_LOG_FUNCTION_NOARGS ();
-
- m_stop = false;
- m_running = false;
- // uids are allocated from 4.
- // uid 0 is "invalid" events
- // uid 1 is "now" events
- // uid 2 is "destroy" events
- m_uid = 4;
- // before ::Run is entered, the m_currentUid will be zero
- m_currentUid = 0;
- m_currentTs = 0;
- m_currentContext = 0xffffffff;
- m_unscheduledEvents = 0;
-
- m_main = SystemThread::Self();
-
- // Be very careful not to do anything that would cause a change or assignment
- // of the underlying reference counts of m_synchronizer or you will be sorry.
- m_synchronizer = CreateObject<RtiClockSynchronizer> ();
-}
-
-RtiSimulatorImpl::~RtiSimulatorImpl ()
-{
-}
-
-void
-RtiSimulatorImpl::DoDispose (void)
-{
- NS_LOG_FUNCTION_NOARGS ();
- while (!m_events->IsEmpty ())
- {
- Scheduler::Event next = m_events->RemoveNext ();
- next.impl->Unref ();
- }
- m_events = 0;
- m_synchronizer = 0;
- SimulatorImpl::DoDispose ();
-}
-
-void
-RtiSimulatorImpl::Destroy ()
-{
- NS_LOG_FUNCTION_NOARGS ();
-
- //
- // This function is only called with the private version "disconnected" from
- // the main simulator functions. We rely on the user not calling
- // Simulator::Destroy while there is a chance that a worker thread could be
- // accessing the current instance of the private object. In practice this
- // means shutting down the workers and doing a Join() before calling the
- // Simulator::Destroy().
- //
- while (m_destroyEvents.empty () == false)
- {
- Ptr<EventImpl> ev = m_destroyEvents.front ().PeekEventImpl ();
- m_destroyEvents.pop_front ();
- NS_LOG_LOGIC ("handle destroy " << ev);
- if (ev->IsCancelled () == false)
- {
- ev->Invoke ();
- }
- }
-}
-
-void
-RtiSimulatorImpl::SetScheduler (ObjectFactory schedulerFactory)
-{
- NS_LOG_FUNCTION_NOARGS ();
-
- Ptr<Scheduler> scheduler = schedulerFactory.Create<Scheduler> ();
-
- {
- CriticalSection cs (m_mutex);
-
- if (m_events != 0)
- {
- while (m_events->IsEmpty () == false)
- {
- Scheduler::Event next = m_events->RemoveNext ();
- scheduler->Insert (next);
- }
- }
- m_events = scheduler;
- }
-}
-
-void
-RtiSimulatorImpl::ProcessOneEvent (void)
-{
- NS_LOG_FUNCTION_NOARGS ();
- //
- // The idea here is to wait until the next event comes due. In the case of
- // a realtime simulation, we want real time to be consumed between events.
- // It is the realtime synchronizer that causes real time to be consumed by
- // doing some kind of a wait.
- //
- // We need to be able to have external events (such as a packet reception event)
- // cause us to re-evaluate our state. The way this works is that the synchronizer
- // gets interrupted and returns. So, there is a possibility that things may change
- // out from under us dynamically. In this case, we need to re-evaluate how long to
- // wait in a for-loop until we have waited sucessfully (until a timeout) for the
- // event at the head of the event list.
- //
- // m_synchronizer->Synchronize will return true if the wait was completed without
- // interruption, otherwise it will return false indicating that something has changed
- // out from under us. If we sit in the for-loop trying to synchronize until
- // Synchronize() returns true, we will have successfully synchronized the execution
- // time of the next event with the wall clock time of the synchronizer.
- //
-
- for (;;)
- {
- uint64_t tsDelay = 0;
- uint64_t tsNext = 0;
-
- //
- // It is important to understand that m_currentTs is interpreted only as the
- // timestamp of the last event we executed. Current time can a bit of a
- // slippery concept in realtime mode. What we have here is a discrete event
- // simulator, so the last event is, by defintion, executed entirely at a single
- // discrete time. This is the definition of m_currentTs. It really has
- // nothing to do with the current real time, except that we are trying to arrange
- // that at the instant of the beginning of event execution, the current real time
- // and m_currentTs coincide.
- //
- // We use tsNow as the indication of the current real time.
- //
- uint64_t tsNow;
-
- {
- CriticalSection cs (m_mutex);
- //
- // Since we are in realtime mode, the time to delay has got to be the
- // difference between the current realtime and the timestamp of the next
- // event. Since m_currentTs is actually the timestamp of the last event we
- // executed, it's not particularly meaningful for us here since real time has
- // certainly elapsed since it was last updated.
- //
- // It is possible that the current realtime has drifted past the next event
- // time so we need to be careful about that and not delay in that case.
- //
- NS_ASSERT_MSG (m_synchronizer->Realtime (),
- "RealtimeSimulatorImpl::ProcessOneEvent (): Synchronizer reports not Realtime ()");
-
- //
- // tsNow is set to the normalized current real time. When the simulation was
- // started, the current real time was effectively set to zero; so tsNow is
- // the current "real" simulation time.
- //
- // tsNext is the simulation time of the next event we want to execute.
- //
- tsNow = m_synchronizer->GetCurrentRealtime ();
- tsNext = NextTs ();
-
- //
- // tsDelay is therefore the real time we need to delay in order to bring the
- // real time in sync with the simulation time. If we wait for this amount of
- // real time, we will accomplish moving the simulation time at the same rate
- // as the real time. This is typically called "pacing" the simulation time.
- //
- // We do have to be careful if we are falling behind. If so, tsDelay must be
- // zero. If we're late, don't dawdle.
- //
- if (tsNext <= tsNow)
- {
-NS_LOG_UNCOND("EVENT MISSED TIME LESS RTI TIME");
-NS_LOG_UNCOND("PRESENT TIME (in ns):");
-NS_LOG_UNCOND(tsNow);
- tsDelay = 0;
- }
- else
- {
-NS_LOG_UNCOND("EVENT IN FUTURE TIME");
-NS_LOG_UNCOND("WAITING");
-NS_LOG_UNCOND("PRESENT TIME (in ns):");
-NS_LOG_UNCOND(tsNow);
-o.reqTimeAdv();
- tsDelay = tsNext - tsNow;
- }
-
- //
- // We've figured out how long we need to delay in order to pace the
- // simulation time with the real time. We're going to sleep, but need
- // to work with the synchronizer to make sure we're awakened if something
- // external happens (like a packet is received). This next line resets
- // the synchronizer so that any future event will cause it to interrupt.
- //
- m_synchronizer->SetCondition (false);
- }
-
- //
- // We have a time to delay. This time may actually not be valid anymore
- // since we released the critical section immediately above, and a real-time
- // ScheduleReal or ScheduleRealNow may have snuck in, well, between the
- // closing brace above and this comment so to speak. If this is the case,
- // that schedule operation will have done a synchronizer Signal() that
- // will set the condition variable to true and cause the Synchronize call
- // below to return immediately.
- //
- // It's easiest to understand if you just consider a short tsDelay that only
- // requires a SpinWait down in the synchronizer. What will happen is that
- // whan Synchronize calls SpinWait, SpinWait will look directly at its
- // condition variable. Note that we set this condition variable to false
- // inside the critical section above.
- //
- // SpinWait will go into a forever loop until either the time has expired or
- // until the condition variable becomes true. A true condition indicates that
- // the wait should stop. The condition is set to true by one of the Schedule
- // methods of the simulator; so if we are in a wait down in Synchronize, and
- // a Simulator::ScheduleReal is done, the wait down in Synchronize will exit and
- // Synchronize will return false. This means we have not actually synchronized
- // to the event expiration time. If no real-time schedule operation is done
- // while down in Synchronize, the wait will time out and Synchronize will return
- // true. This indicates that we have synchronized to the event time.
- //
- // So we need to stay in this for loop, looking for the next event timestamp and
- // attempting to sleep until its due. If we've slept until the timestamp is due,
- // Synchronize returns true and we break out of the sync loop. If an external
- // event happens that requires a re-schedule, Synchronize returns false and
- // we re-evaluate our timing by continuing in the loop.
- //
- // It is expected that tsDelay become shorter as external events interrupt our
- // waits.
- //
- if (m_synchronizer->Synchronize (tsNow, tsDelay))
- {
- NS_LOG_LOGIC ("Interrupted ...");
- break;
- }
-
- //
- // If we get to this point, we have been interrupted during a wait by a real-time
- // schedule operation. This means all bets are off regarding tsDelay and we need
- // to re-evaluate what it is we want to do. We'll loop back around in the
- // for-loop and start again from scratch.
- //
- }
-
- //
- // If we break out of the for-loop above, we have waited until the time specified
- // by the event that was at the head of the event list when we started the process.
- // Since there is a bunch of code that was executed outside a critical section (the
- // Synchronize call) we cannot be sure that the event at the head of the event list
- // is the one we think it is. What we can be sure of is that it is time to execute
- // whatever event is at the head of this list if the list is in time order.
- //
- Scheduler::Event next;
-
- {
- CriticalSection cs (m_mutex);
-
- //
- // We do know we're waiting for an event, so there had better be an event on the
- // event queue. Let's pull it off. When we release the critical section, the
- // event we're working on won't be on the list and so subsequent operations won't
- // mess with us.
- //
- NS_ASSERT_MSG (m_events->IsEmpty () == false,
- "RealtimeSimulatorImpl::ProcessOneEvent(): event queue is empty");
- next = m_events->RemoveNext ();
- m_unscheduledEvents--;
-
- //
- // We cannot make any assumption that "next" is the same event we originally waited
- // for. We can only assume that only that it must be due and cannot cause time
- // to move backward.
- //
- NS_ASSERT_MSG (next.key.m_ts >= m_currentTs,
- "RealtimeSimulatorImpl::ProcessOneEvent(): "
- "next.GetTs() earlier than m_currentTs (list order error)");
- NS_LOG_LOGIC ("handle " << next.key.m_ts);
-
- //
- // Update the current simulation time to be the timestamp of the event we're
- // executing. From the rest of the simulation's point of view, simulation time
- // is frozen until the next event is executed.
- //
- m_currentTs = next.key.m_ts;
- m_currentContext = next.key.m_context;
- m_currentUid = next.key.m_uid;
-
- //
- // We're about to run the event and we've done our best to synchronize this
- // event execution time to real time. Now, if we're in SYNC_HARD_LIMIT mode
- // we have to decide if we've done a good enough job and if we haven't, we've
- // been asked to commit ritual suicide.
- //
- // We check the simulation time against the current real time to make this
- // judgement.
- //
- if (m_synchronizationMode == SYNC_HARD_LIMIT)
- {
- uint64_t tsFinal = m_synchronizer->GetCurrentRealtime ();
- uint64_t tsJitter;
-
- if (tsFinal >= m_currentTs)
- {
- tsJitter = tsFinal - m_currentTs;
- }
- else
- {
- tsJitter = m_currentTs - tsFinal;
- }
-
- if (tsJitter > static_cast<uint64_t>(m_hardLimit.GetTimeStep ()))
- {
- NS_FATAL_ERROR ("RealtimeSimulatorImpl::ProcessOneEvent (): "
- "Hard real-time limit exceeded (jitter = " << tsJitter << ")");
- }
- }
- }
-
- //
- // We have got the event we're about to execute completely disentangled from the
- // event list so we can execute it outside a critical section without fear of someone
- // changing things out from under us.
-
- EventImpl *event = next.impl;
- m_synchronizer->EventStart ();
- event->Invoke ();
- m_synchronizer->EventEnd ();
- event->Unref ();
-}
-
-bool
-RtiSimulatorImpl::IsFinished (void) const
-{
- NS_LOG_FUNCTION_NOARGS ();
- bool rc;
- {
- CriticalSection cs (m_mutex);
- rc = m_events->IsEmpty () || m_stop;
- }
-
- return rc;
-}
-
-//
-// Peeks into event list. Should be called with critical section locked.
-//
-uint64_t
-RtiSimulatorImpl::NextTs (void) const
-{
- NS_LOG_FUNCTION_NOARGS ();
- NS_ASSERT_MSG (m_events->IsEmpty () == false,
- "RealtimeSimulatorImpl::NextTs(): event queue is empty");
- Scheduler::Event ev = m_events->PeekNext ();
- return ev.key.m_ts;
-}
-
-void
-RtiSimulatorImpl::Run (void)
-{
- NS_LOG_FUNCTION_NOARGS ();
-
- NS_ASSERT_MSG (m_running == false,
- "RealtimeSimulatorImpl::Run(): Simulator already running");
-
- // Set the current threadId as the main threadId
- m_main = SystemThread::Self();
-
- m_stop = false;
- m_running = true;
- m_synchronizer->SetOrigin (m_currentTs);
-
- // Sleep until signalled
- uint64_t tsNow;
- uint64_t tsDelay = 1000000000; // wait time of 1 second (in nanoseconds)
-
- while (!m_stop)
- {
- if(m_stop)
- {
- NS_LOG_LOGIC("ns3 events over");
- }
- bool process = false;
- {
- CriticalSection cs (m_mutex);
-
- if (!m_events->IsEmpty ())
- {
- process = true;
- }
- else
- {
- // Get current timestamp while holding the critical section
- tsNow = m_synchronizer->GetCurrentRealtime ();
- }
- }
-
- if (!process)
- {
- // Sleep until signalled
- tsNow = m_synchronizer->Synchronize (tsNow, tsDelay);
-
- // Re-check event queue
- continue;
- }
-
- ProcessOneEvent ();
- }
-
- //
- // If the simulator stopped naturally by lack of events, make a
- // consistency test to check that we didn't lose any events along the way.
- //
- {
- CriticalSection cs (m_mutex);
-
- NS_ASSERT_MSG (m_events->IsEmpty () == false || m_unscheduledEvents == 0,
- "RealtimeSimulatorImpl::Run(): Empty queue and unprocessed events");
- }
-
- m_running = false;
-}
-
-bool
-RtiSimulatorImpl::Running (void) const
-{
- NS_LOG_FUNCTION_NOARGS ();
- return m_running;
-}
-
-bool
-RtiSimulatorImpl::Realtime (void) const
-{
- NS_LOG_FUNCTION_NOARGS ();
- return m_synchronizer->Realtime ();
-}
-
-void
-RtiSimulatorImpl::Stop (void)
-{
- NS_LOG_FUNCTION_NOARGS ();
- m_stop = true;
-}
-
-void
-RtiSimulatorImpl::Stop (Time const &time)
-{
- Simulator::Schedule (time, &Simulator::Stop);
-}
-
-//
-// Schedule an event for a _relative_ time in the future.
-//
-EventId
-RtiSimulatorImpl::Schedule (Time const &time, EventImpl *impl)
-{
- NS_LOG_FUNCTION (time << impl);
-
- Scheduler::Event ev;
- {
- CriticalSection cs (m_mutex);
- //
- // This is the reason we had to bring the absolute time calcualtion in from the
- // simulator.h into the implementation. Since the implementations may be
- // multi-threaded, we need this calculation to be atomic. You can see it is
- // here since we are running in a CriticalSection.
- //
- Time tAbsolute = Simulator::Now () + time;
- NS_ASSERT_MSG (tAbsolute.IsPositive (), "RealtimeSimulatorImpl::Schedule(): Negative time");
- NS_ASSERT_MSG (tAbsolute >= TimeStep (m_currentTs), "RealtimeSimulatorImpl::Schedule(): time < m_currentTs");
- ev.impl = impl;
- ev.key.m_ts = (uint64_t) tAbsolute.GetTimeStep ();
- ev.key.m_context = GetContext ();
- ev.key.m_uid = m_uid;
- m_uid++;
- m_unscheduledEvents++;
- m_events->Insert (ev);
- m_synchronizer->Signal ();
- }
-
- return EventId (impl, ev.key.m_ts, ev.key.m_context, ev.key.m_uid);
-}
-
-void
-RtiSimulatorImpl::ScheduleWithContext (uint32_t context, Time const &time, EventImpl *impl)
-{
- NS_LOG_FUNCTION (time << impl);
-
- {
- CriticalSection cs (m_mutex);
- uint64_t ts;
-
- if (SystemThread::Equals (m_main))
- {
- ts = m_currentTs + time.GetTimeStep ();
- }
- else
- {
- //
- // If the simulator is running, we're pacing and have a meaningful
- // realtime clock. If we're not, then m_currentTs is where we stopped.
- //
- ts = m_running ? m_synchronizer->GetCurrentRealtime () : m_currentTs;
- ts += time.GetTimeStep ();
- }
-
- NS_ASSERT_MSG (ts >= m_currentTs, "RealtimeSimulatorImpl::ScheduleRealtime(): schedule for time < m_currentTs");
- Scheduler::Event ev;
- ev.impl = impl;
- ev.key.m_ts = ts;
- ev.key.m_context = context;
- ev.key.m_uid = m_uid;
- m_uid++;
- m_unscheduledEvents++;
- m_events->Insert (ev);
- m_synchronizer->Signal ();
- }
-}
-
-EventId
-RtiSimulatorImpl::ScheduleNow (EventImpl *impl)
-{
- NS_LOG_FUNCTION_NOARGS ();
- Scheduler::Event ev;
- {
- CriticalSection cs (m_mutex);
-
- ev.impl = impl;
- ev.key.m_ts = m_currentTs;
- ev.key.m_context = GetContext ();
- ev.key.m_uid = m_uid;
- m_uid++;
- m_unscheduledEvents++;
- m_events->Insert (ev);
- m_synchronizer->Signal ();
- }
-
- return EventId (impl, ev.key.m_ts, ev.key.m_context, ev.key.m_uid);
-}
-
-Time
-RtiSimulatorImpl::Now (void) const
-{
- return TimeStep (m_currentTs);
-}
-
-//
-// Schedule an event for a _relative_ time in the future.
-//
-void
-RtiSimulatorImpl::ScheduleRealtimeWithContext (uint32_t context, Time const &time, EventImpl *impl)
-{
- NS_LOG_FUNCTION (context << time << impl);
-
- {
- CriticalSection cs (m_mutex);
-
- uint64_t ts = m_synchronizer->GetCurrentRealtime () + time.GetTimeStep ();
- NS_ASSERT_MSG (ts >= m_currentTs, "RealtimeSimulatorImpl::ScheduleRealtime(): schedule for time < m_currentTs");
- Scheduler::Event ev;
- ev.impl = impl;
- ev.key.m_ts = ts;
- ev.key.m_uid = m_uid;
- m_uid++;
- m_unscheduledEvents++;
- m_events->Insert (ev);
- m_synchronizer->Signal ();
- }
-}
-
-void
-RtiSimulatorImpl::ScheduleRealtime (Time const &time, EventImpl *impl)
-{
- NS_LOG_FUNCTION (time << impl);
- ScheduleRealtimeWithContext (GetContext (), time, impl);
-}
-
-void
-RtiSimulatorImpl::ScheduleRealtimeNowWithContext (uint32_t context, EventImpl *impl)
-{
- NS_LOG_FUNCTION (context << impl);
- {
- CriticalSection cs (m_mutex);
-
- //
- // If the simulator is running, we're pacing and have a meaningful
- // realtime clock. If we're not, then m_currentTs is were we stopped.
- //
- uint64_t ts = m_running ? m_synchronizer->GetCurrentRealtime () : m_currentTs;
- NS_ASSERT_MSG (ts >= m_currentTs,
- "RealtimeSimulatorImpl::ScheduleRealtimeNowWithContext(): schedule for time < m_currentTs");
- Scheduler::Event ev;
- ev.impl = impl;
- ev.key.m_ts = ts;
- ev.key.m_uid = m_uid;
- ev.key.m_context = context;
- m_uid++;
- m_unscheduledEvents++;
- m_events->Insert (ev);
- m_synchronizer->Signal ();
- }
-}
-
-void
-RtiSimulatorImpl::ScheduleRealtimeNow (EventImpl *impl)
-{
- NS_LOG_FUNCTION (impl);
- ScheduleRealtimeNowWithContext (GetContext (), impl);
-}
-
-Time
-RtiSimulatorImpl::RealtimeNow (void) const
-{
- return TimeStep (m_synchronizer->GetCurrentRealtime ());
-}
-
-EventId
-RtiSimulatorImpl::ScheduleDestroy (EventImpl *impl)
-{
- NS_LOG_FUNCTION_NOARGS ();
-
- EventId id;
- {
- CriticalSection cs (m_mutex);
-
- //
- // Time doesn't really matter here (especially in realtime mode). It is
- // overridden by the uid of 2 which identifies this as an event to be
- // executed at Simulator::Destroy time.
- //
- id = EventId (Ptr<EventImpl> (impl, false), m_currentTs, 0xffffffff, 2);
- m_destroyEvents.push_back (id);
- m_uid++;
- }
-
- return id;
-}
-
-Time
-RtiSimulatorImpl::GetDelayLeft (const EventId &id) const
-{
- //
- // If the event has expired, there is no delay until it runs. It is not the
- // case that there is a negative time until it runs.
- //
- if (IsExpired (id))
- {
- return TimeStep (0);
- }
-
- return TimeStep (id.GetTs () - m_currentTs);
-}
-
-void
-RtiSimulatorImpl::Remove (const EventId &id)
-{
- if (id.GetUid () == 2)
- {
- // destroy events.
- for (DestroyEvents::iterator i = m_destroyEvents.begin ();
- i != m_destroyEvents.end ();
- i++)
- {
- if (*i == id)
- {
- m_destroyEvents.erase (i);
- break;
- }
- }
- return;
- }
- if (IsExpired (id))
- {
- return;
- }
-
- {
- CriticalSection cs (m_mutex);
-
- Scheduler::Event event;
- event.impl = id.PeekEventImpl ();
- event.key.m_ts = id.GetTs ();
- event.key.m_context = id.GetContext ();
- event.key.m_uid = id.GetUid ();
-
- m_events->Remove (event);
- m_unscheduledEvents--;
- event.impl->Cancel ();
- event.impl->Unref ();
- }
-}
-
-void
-RtiSimulatorImpl::Cancel (const EventId &id)
-{
- if (IsExpired (id) == false)
- {
- id.PeekEventImpl ()->Cancel ();
- }
-}
-
-bool
-RtiSimulatorImpl::IsExpired (const EventId &ev) const
-{
- if (ev.GetUid () == 2)
- {
- if (ev.PeekEventImpl () == 0 ||
- ev.PeekEventImpl ()->IsCancelled ())
- {
- return true;
- }
- // destroy events.
- for (DestroyEvents::const_iterator i = m_destroyEvents.begin ();
- i != m_destroyEvents.end (); i++)
- {
- if (*i == ev)
- {
- return false;
- }
- }
- return true;
- }
-
- //
- // If the time of the event is less than the current timestamp of the
- // simulator, the simulator has gone past the invocation time of the
- // event, so the statement ev.GetTs () < m_currentTs does mean that
- // the event has been fired even in realtime mode.
- //
- // The same is true for the next line involving the m_currentUid.
- //
- if (ev.PeekEventImpl () == 0 ||
- ev.GetTs () < m_currentTs ||
- (ev.GetTs () == m_currentTs && ev.GetUid () <= m_currentUid) ||
- ev.PeekEventImpl ()->IsCancelled ())
- {
- return true;
- }
- else
- {
- return false;
- }
-}
-
-Time
-RtiSimulatorImpl::GetMaximumSimulationTime (void) const
-{
- // XXX: I am fairly certain other compilers use other non-standard
- // post-fixes to indicate 64 bit constants.
- return TimeStep (0x7fffffffffffffffLL);
-}
-
-// System ID for non-distributed simulation is always zero
-uint32_t
-RtiSimulatorImpl::GetSystemId (void) const
-{
- return 0;
-}
-
-uint32_t
-RtiSimulatorImpl::GetContext (void) const
-{
- return m_currentContext;
-}
-
-void
-RtiSimulatorImpl::SetSynchronizationMode (enum SynchronizationMode mode)
-{
- NS_LOG_FUNCTION (mode);
- m_synchronizationMode = mode;
-}
-
-RtiSimulatorImpl::SynchronizationMode
-RtiSimulatorImpl::GetSynchronizationMode (void) const
-{
- NS_LOG_FUNCTION_NOARGS ();
- return m_synchronizationMode;
-}
-
-void
-RtiSimulatorImpl::SetHardLimit (Time limit)
-{
- NS_LOG_FUNCTION (limit);
- m_hardLimit = limit;
-}
-
-Time
-RtiSimulatorImpl::GetHardLimit (void) const
-{
- NS_LOG_FUNCTION_NOARGS ();
- return m_hardLimit;
-}
-
-} // namespace ns3
--- a/codeRev/src/hla/model/rti-simulator-impl.h Sat Aug 18 15:01:04 2012 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,125 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2008 University of Washington
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef RTI_SIMULATOR_IMPL_H
-#define RTI_SIMULATOR_IMPL_H
-
-#include "ns3/simulator-impl.h"
-#include "ns3/system-thread.h"
-
-#include "ns3/scheduler.h"
-#include "ns3/synchronizer.h"
-#include "ns3/event-impl.h"
-
-#include "ns3/ptr.h"
-#include "ns3/assert.h"
-#include "ns3/log.h"
-#include "ns3/system-mutex.h"
-
-#include <list>
-
-namespace ns3 {
-
-class RtiSimulatorImpl : public SimulatorImpl
-{
-public:
- static TypeId GetTypeId (void);
-
- /**
- * Enumeration of the types of packets supported in the class.
- *
- */
- enum SynchronizationMode {
- SYNC_BEST_EFFORT, /** Make a best effort to keep synced to real-time */
- SYNC_HARD_LIMIT, /** Keep to real-time within a tolerance or die trying */
- };
-
- RtiSimulatorImpl ();
- ~RtiSimulatorImpl ();
-
- virtual void Destroy ();
- virtual bool IsFinished (void) const;
- virtual void Stop (void);
- virtual void Stop (Time const &time);
- virtual EventId Schedule (Time const &time, EventImpl *event);
- virtual void ScheduleWithContext (uint32_t context, Time const &time, EventImpl *event);
- virtual EventId ScheduleNow (EventImpl *event);
- virtual EventId ScheduleDestroy (EventImpl *event);
- virtual void Remove (const EventId &ev);
- virtual void Cancel (const EventId &ev);
- virtual bool IsExpired (const EventId &ev) const;
- virtual void Run (void);
- virtual Time Now (void) const;
- virtual Time GetDelayLeft (const EventId &id) const;
- virtual Time GetMaximumSimulationTime (void) const;
- virtual void SetScheduler (ObjectFactory schedulerFactory);
- virtual uint32_t GetSystemId (void) const;
- virtual uint32_t GetContext (void) const;
-
- void ScheduleRealtimeWithContext (uint32_t context, Time const &time, EventImpl *event);
- void ScheduleRealtime (Time const &time, EventImpl *event);
- void ScheduleRealtimeNowWithContext (uint32_t context, EventImpl *event);
- void ScheduleRealtimeNow (EventImpl *event);
- Time RealtimeNow (void) const;
-
- void SetSynchronizationMode (RtiSimulatorImpl::SynchronizationMode mode);
- RtiSimulatorImpl::SynchronizationMode GetSynchronizationMode (void) const;
-
- void SetHardLimit (Time limit);
- Time GetHardLimit (void) const;
-
-private:
- bool Running (void) const;
- bool Realtime (void) const;
- uint64_t NextTs (void) const;
- void ProcessOneEvent (void);
- virtual void DoDispose (void);
-
- typedef std::list<EventId> DestroyEvents;
- DestroyEvents m_destroyEvents;
- bool m_stop;
- bool m_running;
-
- // The following variables are protected using the m_mutex
- Ptr<Scheduler> m_events;
- int m_unscheduledEvents;
- uint32_t m_uid;
- uint32_t m_currentUid;
- uint64_t m_currentTs;
- uint32_t m_currentContext;
-
- mutable SystemMutex m_mutex;
-
- Ptr<Synchronizer> m_synchronizer;
-
- /**
- * The policy to use if the simulation cannot keep synchronized to real-time.
- */
- SynchronizationMode m_synchronizationMode;
-
- /**
- * The maximum allowable drift from real-time in SYNC_HARD_LIMIT mode.
- */
- Time m_hardLimit;
-
- SystemThread::ThreadId m_main;
-};
-
-} // namespace ns3
-
-#endif /* REALTIME_SIMULATOR_IMPL_H */