Merge with ns-3-dev.
--- a/examples/mesh/mesh.cc Mon Nov 02 18:08:16 2009 +0100
+++ b/examples/mesh/mesh.cc Mon Nov 02 18:16:09 2009 +0100
@@ -158,7 +158,16 @@
* mesh point device
*/
mesh = MeshHelper::Default ();
- mesh.SetStackInstaller (m_stack, "Root", Mac48AddressValue (Mac48Address (m_root.c_str ())));
+ if (!Mac48Address (m_root.c_str ()).IsBroadcast ())
+ {
+ mesh.SetStackInstaller (m_stack, "Root", Mac48AddressValue (Mac48Address (m_root.c_str ())));
+ }
+ else
+ {
+ //If root is not set, we do not use "Root" attribute, because it
+ //is specified only for 11s
+ mesh.SetStackInstaller (m_stack);
+ }
if (m_chan)
{
mesh.SetSpreadInterfaceChannels (MeshHelper::SPREAD_CHANNELS);
--- a/src/common/pcap-file-test-suite.cc Mon Nov 02 18:08:16 2009 +0100
+++ b/src/common/pcap-file-test-suite.cc Mon Nov 02 18:16:09 2009 +0100
@@ -12,6 +12,8 @@
* 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: Craig Dowell (craigdo@ee.washington.edu)
*/
#include <iostream>
@@ -948,6 +950,62 @@
return false;
}
+// ===========================================================================
+// Test case to make sure that the Pcap::Diff method works as expected
+// ===========================================================================
+class DiffTestCase : public TestCase
+{
+public:
+ DiffTestCase ();
+
+private:
+ virtual bool DoRun (void);
+};
+
+DiffTestCase::DiffTestCase ()
+ : TestCase ("Check that PcapFile::Diff works as expected")
+{
+}
+
+bool
+DiffTestCase::DoRun (void)
+{
+ //
+ // Check that PcapDiff(file, file) is false
+ //
+ std::string filename = NS_TEST_SOURCEDIR + "known.pcap";
+ uint32_t sec(0), usec(0);
+ bool diff = PcapFile::Diff (filename, filename, sec, usec);
+ NS_TEST_EXPECT_MSG_EQ (diff, false, "PcapDiff(file, file) must always be false");
+
+ //
+ // Create different PCAP file (with the same timestamps, but different packets) and check that it is indeed different
+ //
+ std::string filename2 = "different.pcap";
+ PcapFile f;
+
+ bool err = f.Open (filename2, "w");
+ NS_TEST_ASSERT_MSG_EQ (err, false, "Open (" << filename2 << ", \"w\") returns error");
+ err = f.Init (1, N_PACKET_BYTES);
+ NS_TEST_ASSERT_MSG_EQ (err, false, "Init (1, " << N_PACKET_BYTES << ") returns error");
+
+ for (uint32_t i = 0; i < N_KNOWN_PACKETS; ++i)
+ {
+ PacketEntry const & p = knownPackets[i];
+
+ err = f.Write (p.tsSec, p.tsUsec, (uint8_t const *)p.data, p.origLen);
+ NS_TEST_EXPECT_MSG_EQ (err, false, "Write must not fail");
+ }
+ f.Close ();
+
+ diff = PcapFile::Diff (filename, filename2, sec, usec);
+ NS_TEST_EXPECT_MSG_EQ (diff, true, "PcapDiff(file, file2) must be true");
+ NS_TEST_EXPECT_MSG_EQ (sec, 2, "Files are different from 2.3696 seconds");
+ NS_TEST_EXPECT_MSG_EQ (usec, 3696, "Files are different from 2.3696 seconds");
+
+ return GetErrorStatus();
+}
+
class PcapFileTestSuite : public TestSuite
{
public:
@@ -963,6 +1021,7 @@
AddTestCase (new FileHeaderTestCase);
AddTestCase (new RecordHeaderTestCase);
AddTestCase (new ReadFileTestCase);
+ AddTestCase (new DiffTestCase);
}
PcapFileTestSuite pcapFileTestSuite;
--- a/src/common/pcap-file.cc Mon Nov 02 18:08:16 2009 +0100
+++ b/src/common/pcap-file.cc Mon Nov 02 18:16:09 2009 +0100
@@ -14,14 +14,16 @@
* 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: Craig Dowell (craigdo@ee.washington.edu)
*/
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
+#include <cstring>
#include "pcap-file.h"
-
//
// This file is used as part of the ns-3 test framework, so please refrain from
// adding any ns-3 specific constructs such as Packet to this file.
@@ -516,4 +518,65 @@
return false;
}
+bool
+PcapFile::Diff (std::string const & f1, std::string const & f2,
+ uint32_t & sec, uint32_t & usec,
+ uint32_t snapLen)
+{
+ PcapFile pcap[2];
+ for (int i = 0; i < 2; ++i)
+ {
+ std::string const & file = (i == 0) ? f1 : f2;
+ bool err = pcap[i].Open (file, "r");
+ if (err)
+ {
+ // Can't open file
+ return true;
+ }
+ }
+
+ uint8_t data[2][snapLen];
+ uint32_t tsSec[2], tsUsec[2], inclLen[2], origLen[2], readLen[2];
+ bool err[2];
+ bool diff(false);
+
+ while (1)
+ {
+ for (int i = 0; i < 2; ++i)
+ err[i] = pcap[i].Read (data[i], snapLen, tsSec[i], tsUsec[i], inclLen[i], origLen[i], readLen[i]);
+
+ sec = tsSec[0];
+ usec = tsUsec[0];
+
+ if (err[0] != err[1])
+ {
+ diff = true; // Read status doesn't match
+ break;
+ }
+
+ if (err[0]) break; // nothing left
+
+ if (tsSec[0] != tsSec[1] || tsUsec[0] != tsUsec[1])
+ {
+ diff = true; // Next packet timestamps do not match
+ break;
+ }
+
+ if (readLen[0] != readLen[1])
+ {
+ diff = true; // Packet lengths do not match
+ break;
+ }
+
+ if (std::memcmp(data[0], data[1], readLen[0]) != 0)
+ {
+ diff = true; // Packet data do not match
+ break;
+ }
+ }
+ pcap[0].Close ();
+ pcap[1].Close ();
+ return diff;
+}
+
} //namespace ns3
--- a/src/common/pcap-file.h Mon Nov 02 18:08:16 2009 +0100
+++ b/src/common/pcap-file.h Mon Nov 02 18:16:09 2009 +0100
@@ -14,6 +14,8 @@
* 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: Craig Dowell (craigdo@ee.washington.edu)
*/
#ifndef PCAP_FILE_H
@@ -125,7 +127,7 @@
* time zone from UTC/GMT. For example, Pacific Standard Time in the US is
* GMT-8, so one would enter -8 for that correction. Defaults to 0 (UTC).
*
- * \returns false if the open succeeds, true otherwise.
+ * \return false if the open succeeds, true otherwise.
*
* \warning Calling this method on an existing file will result in the loss
* any existing data.
@@ -135,8 +137,31 @@
int32_t timeZoneCorrection = ZONE_DEFAULT,
bool swapMode = false);
+ /**
+ * \brief Write next packet to file
+ *
+ * \param tsSec Packet timestamp, seconds
+ * \param tsUsec Packet timestamp, microseconds
+ * \param data Data buffer
+ * \param totalLen Total packet length
+ *
+ * \return true on error, false otherwise
+ */
bool Write (uint32_t tsSec, uint32_t tsUsec, uint8_t const * const data, uint32_t totalLen);
+ /**
+ * \brief Read next packet from file
+ *
+ * \param data [out] Data buffer
+ * \param maxBytes Allocated data buffer size
+ * \param tsSec [out] Packet timestamp, seconds
+ * \param tsUsec [out] Packet timestamp, microseconds
+ * \param inclLen [out] Included length
+ * \param origLen [out] Original length
+ * \param readLen [out] Number of bytes read
+ *
+ * \return true if read failed, false otherwise
+ */
bool Read (uint8_t * const data,
uint32_t maxBytes,
uint32_t &tsSec,
@@ -154,6 +179,21 @@
uint32_t GetSigFigs (void);
uint32_t GetSnapLen (void);
uint32_t GetDataLinkType (void);
+
+ /**
+ * \brief Compare two PCAP files packet-by-packet
+ *
+ * \return true if files are different, false otherwise
+ *
+ * \param f1 First PCAP file name
+ * \param f2 Second PCAP file name
+ * \param sec [out] Time stamp of first different packet, seconds. Undefined if files doesn't differ.
+ * \param uses [out] Time stamp of first different packet, microseconds. Undefined if files doesn't differ.
+ * \param snapLen Snap length (if used)
+ */
+ static bool Diff (std::string const & f1, std::string const & f2,
+ uint32_t & sec, uint32_t & usec,
+ uint32_t snapLen = SNAPLEN_DEFAULT);
private:
typedef struct {
--- a/src/core/system-wall-clock-ms.h Mon Nov 02 18:08:16 2009 +0100
+++ b/src/core/system-wall-clock-ms.h Mon Nov 02 18:16:09 2009 +0100
@@ -21,10 +21,13 @@
#ifndef SYSTEM_WALL_CLOCK_MS_H
#define SYSTEM_WALL_CLOCK_MS_H
+#include <stdint.h>
+
namespace ns3 {
/**
- * \brief measure wall-clock time in milliseconds
+ * \brief measure elapsed time in milliseconds
+ *
*/
class SystemWallClockMs {
public:
@@ -36,13 +39,39 @@
*/
void Start (void);
/**
- * \returns the measured elapsed wall clock time since
- * ns3::SystemWallClockMs::start was invoked.
+ * \brief Stop measuring the time since Start() was called.
+ * \returns the measured elapsed wall clock time (in milliseconds) since
+ * ns3::SystemWallClockMs::Start was invoked.
+ *
+ * It is possible to start a new measurement with ns3::SystemWallClockMs::Start
+ * after this method returns.
+ *
+ * Returns int64_t to avoid dependency on clock_t in ns-3 code.
+ */
+ int64_t End (void);
+
+ /**
+ * \returns the measured elapsed wall clock time (in milliseconds) since
+ * ns3::SystemWallClockMs::Start was invoked.
*
- * It is possible to start a new measurement with ns3::SystemWallClockMs::start
- * after this method returns.
+ * Returns int64_t to avoid dependency on clock_t in ns-3 code.
+ */
+ int64_t GetElapsedReal (void) const;
+ /**
+ * \returns the measured elapsed 'user' wall clock time (in milliseconds) since
+ * ns3::SystemWallClockMs::Start was invoked.
+ *
+ * Returns int64_t to avoid dependency on clock_t in ns-3 code.
*/
- unsigned long long End (void);
+ int64_t GetElapsedUser (void) const;
+ /**
+ * \returns the measured elapsed 'system' wall clock time (in milliseconds) since
+ * ns3::SystemWallClockMs::Start was invoked.
+ *
+ * Returns int64_t to avoid dependency on clock_t in ns-3 code.
+ */
+ int64_t GetElapsedSystem (void) const;
+
private:
class SystemWallClockMsPrivate *m_priv;
};
--- a/src/core/test.cc Mon Nov 02 18:08:16 2009 +0100
+++ b/src/core/test.cc Mon Nov 02 18:16:09 2009 +0100
@@ -262,7 +262,7 @@
void
TestCase::DoReportStart (void)
{
- m_startTime = times (&m_startTimes);
+ m_msClock.Start ();
if (m_ofs == 0)
{
@@ -319,26 +319,21 @@
void
TestCase::DoReportEnd (void)
{
- static long ticksPerSecond = sysconf (_SC_CLK_TCK);
+ m_msClock.End ();
if (m_ofs == 0)
{
return;
}
- struct tms endTimes;
- clock_t endTime = times (&endTimes);
-
- clock_t elapsed = endTime - m_startTime;
- clock_t elapsedUsr = endTimes.tms_utime - m_startTimes.tms_utime;
- clock_t elapsedSys = endTimes.tms_stime - m_startTimes.tms_stime;
-
- (*m_ofs).precision (2);
+ (*m_ofs).precision (3);
*m_ofs << std::fixed;
- *m_ofs << " <CaseTime>" << "real " << static_cast<double> (elapsed) / ticksPerSecond
- << " user " << static_cast<double> (elapsedUsr) / ticksPerSecond
- << " system " << static_cast<double> (elapsedSys) / ticksPerSecond
+ const double MS_PER_SEC = 1000.;
+
+ *m_ofs << " <CaseTime>" << "real " << m_msClock.GetElapsedReal () / MS_PER_SEC
+ << " user " << m_msClock.GetElapsedUser () / MS_PER_SEC
+ << " system " << m_msClock.GetElapsedSystem () / MS_PER_SEC
<< "</CaseTime>" << std::endl;
*m_ofs << " </TestCase>" << std::endl;
@@ -523,8 +518,8 @@
void
TestSuite::DoReportStart (void)
{
- m_startTime = times (&m_startTimes);
-
+ m_msClock.Start ();
+
if (m_ofs == 0)
{
return;
@@ -556,25 +551,21 @@
void
TestSuite::DoReportEnd (void)
{
- static long ticksPerSecond = sysconf (_SC_CLK_TCK);
-
+ m_msClock.End ();
+
if (m_ofs == 0)
{
return;
}
- struct tms endTimes;
- clock_t endTime = times (&endTimes);
- clock_t elapsed = endTime - m_startTime;
- clock_t elapsedUsr = endTimes.tms_utime - m_startTimes.tms_utime;
- clock_t elapsedSys = endTimes.tms_stime - m_startTimes.tms_stime;
-
- (*m_ofs).precision (2);
+ (*m_ofs).precision (3);
*m_ofs << std::fixed;
- *m_ofs << " <SuiteTime>" << "real " << static_cast<double> (elapsed) / ticksPerSecond
- << " user " << static_cast<double> (elapsedUsr) / ticksPerSecond
- << " system " << static_cast<double> (elapsedSys) / ticksPerSecond
+ const double MS_PER_SEC = 1000.;
+
+ *m_ofs << " <SuiteTime>" << "real " << m_msClock.GetElapsedReal () / MS_PER_SEC
+ << " user " << m_msClock.GetElapsedUser () / MS_PER_SEC
+ << " system " << m_msClock.GetElapsedSystem () / MS_PER_SEC
<< "</SuiteTime>" << std::endl;
*m_ofs << "</TestSuite>" << std::endl;
--- a/src/core/test.h Mon Nov 02 18:08:16 2009 +0100
+++ b/src/core/test.h Mon Nov 02 18:16:09 2009 +0100
@@ -27,7 +27,10 @@
#include <list>
#include <limits>
#include <stdint.h>
-#include <sys/times.h>
+
+#include "ns3/system-wall-clock-ms.h"
+
+
//
// Note on below macros:
//
@@ -821,6 +824,7 @@
TestCase (TestCase& tc);
TestCase& operator= (TestCase& tc);
+ SystemWallClockMs m_msClock;
std::string m_name;
bool m_verbose;
bool m_continueOnFailure;
@@ -828,8 +832,6 @@
std::string m_basedir;
std::ofstream *m_ofs;
bool m_error;
- clock_t m_startTime;
- struct tms m_startTimes;
};
/**
@@ -1057,6 +1059,7 @@
TestSuite (TestSuite& ts);
TestSuite& operator= (TestSuite& ts);
+ SystemWallClockMs m_msClock;
std::string m_name;
bool m_verbose;
bool m_continueOnFailure;
@@ -1064,10 +1067,7 @@
std::ofstream *m_ofs;
bool m_error;
TestType m_type;
-
- clock_t m_startTime;
- struct tms m_startTimes;
-
+
typedef std::vector<TestCase *> TestCaseVector_t;
TestCaseVector_t m_tests;
};
--- a/src/core/unix-system-wall-clock-ms.cc Mon Nov 02 18:08:16 2009 +0100
+++ b/src/core/unix-system-wall-clock-ms.cc Mon Nov 02 18:16:09 2009 +0100
@@ -19,36 +19,105 @@
*/
#include "system-wall-clock-ms.h"
-#include <sys/time.h>
+#include "abort.h"
+#include <sys/times.h>
namespace ns3 {
class SystemWallClockMsPrivate {
public:
void Start (void);
- unsigned long long End (void);
+ int64_t End (void);
+ int64_t GetElapsedReal (void) const;
+ int64_t GetElapsedUser (void) const;
+ int64_t GetElapsedSystem (void) const;
+
private:
- struct timeval m_startTv;
- struct timeval m_endTv;
+ struct tms m_startTimes;
+ clock_t m_startTime;
+ int64_t m_elapsedReal;
+ int64_t m_elapsedUser;
+ int64_t m_elapsedSystem;
};
void
SystemWallClockMsPrivate::Start (void)
{
- struct timezone tz;
- gettimeofday (&m_startTv, &tz);
+ m_startTime = times (&m_startTimes);
}
-unsigned long long
+int64_t
SystemWallClockMsPrivate::End (void)
{
- struct timezone tz;
- gettimeofday (&m_endTv, &tz);
- unsigned long long end = m_endTv.tv_sec *1000 + m_endTv.tv_usec / 1000;
- unsigned long long start = m_startTv.tv_sec *1000 + m_startTv.tv_usec / 1000;
- return end - start;
+ //
+ // We need to return the number of milliseconds that have elapsed in some
+ // reasonably portable way. The underlying function that we will use returns
+ // a number of elapsed ticks. We can look up the number of ticks per second
+ // from the system configuration.
+ //
+ // Conceptually, we need to find the number of elapsed clock ticks and then
+ // multiply the result by the milliseconds per clock tick (or divide by clock
+ // ticks per millisecond). Integer dividing by clock ticks per millisecond
+ // is bad since this number is fractional on most machines and would result
+ // in divide by zero errors due to integer rounding.
+ //
+ // Multiplying by milliseconds per clock tick works up to a clock resolution
+ // of 1000 ticks per second. If we go past this point, we begin to get zero
+ // elapsed times when millisecondsPerTick becomes fractional and another
+ // rounding error appears.
+ //
+ // So rounding errors using integers can bite you from both direction. Since
+ // all of our targets have math coprocessors, why not just use doubles
+ // internally? Works fine, lasts a long time.
+ //
+ // If millisecondsPerTick becomes fractional, and an elapsed time greater than
+ // a milliscond is measured, the function will work as expected. If an elapsed
+ // time is measured that turns out to be less than a millisecond, we'll just
+ // return zero which would, I think, also will be expected.
+ //
+ static int64_t ticksPerSecond = sysconf (_SC_CLK_TCK);
+ static double millisecondsPerTick = 1000. / ticksPerSecond;
+
+ //
+ // If sysconf () fails, we have no idea how to do the required conversion to ms.
+ //
+ NS_ABORT_MSG_IF (ticksPerSecond == -1, "SystemWallClockMsPrivate(): Cannot sysconf (_SC_CLK_TCK)");
+
+ struct tms endTimes;
+ clock_t endTime = times (&endTimes);
+
+ double tmp;
+
+ tmp = static_cast<double> (endTime - m_startTime) * millisecondsPerTick;
+ m_elapsedReal = static_cast<int64_t> (tmp);
+
+ tmp = static_cast<double> (endTimes.tms_utime - m_startTimes.tms_utime) * millisecondsPerTick;
+ m_elapsedUser = static_cast<int64_t> (tmp);
+
+ tmp = static_cast<double> (endTimes.tms_stime - m_startTimes.tms_stime) * millisecondsPerTick;
+ m_elapsedSystem = static_cast<int64_t> (tmp);
+
+ return m_elapsedReal;
}
+int64_t
+SystemWallClockMsPrivate::GetElapsedReal (void) const
+{
+ return m_elapsedReal;
+}
+
+int64_t
+SystemWallClockMsPrivate::GetElapsedUser (void) const
+{
+ return m_elapsedUser;
+}
+
+int64_t
+SystemWallClockMsPrivate::GetElapsedSystem (void) const
+{
+ return m_elapsedSystem;
+}
+
SystemWallClockMs::SystemWallClockMs ()
: m_priv (new SystemWallClockMsPrivate ())
{}
@@ -64,10 +133,29 @@
{
m_priv->Start ();
}
-unsigned long long
+
+int64_t
SystemWallClockMs::End (void)
{
return m_priv->End ();
}
+int64_t
+SystemWallClockMs::GetElapsedReal (void) const
+{
+ return m_priv->GetElapsedReal ();
+}
+
+int64_t
+SystemWallClockMs::GetElapsedUser (void) const
+{
+ return m_priv->GetElapsedUser ();
+}
+
+int64_t
+SystemWallClockMs::GetElapsedSystem (void) const
+{
+ return m_priv->GetElapsedSystem ();
+}
+
}; // namespace ns3
--- a/src/core/win32-system-wall-clock-ms.cc Mon Nov 02 18:08:16 2009 +0100
+++ b/src/core/win32-system-wall-clock-ms.cc Mon Nov 02 18:16:09 2009 +0100
@@ -20,26 +20,97 @@
#include "system-wall-clock-ms.h"
+#include <time.h>
+
namespace ns3 {
class SystemWallClockMsPrivate {
public:
void Start (void);
- unsigned long long End (void);
+ int64_t End (void);
+ int64_t GetElapsedReal (void) const;
+ int64_t GetElapsedUser (void) const;
+ int64_t GetElapsedSystem (void) const;
+
private:
+ clock_t m_startTime;
+ int64_t m_elapsedReal;
+ int64_t m_elapsedUser;
+ int64_t m_elapsedSystem;
};
void
SystemWallClockMsPrivate::Start (void)
{
+ m_startTime = clock ();
}
-unsigned long long
+int64_t
SystemWallClockMsPrivate::End (void)
{
- return 0;
+ //
+ // We need to return the number of milliseconds that have elapsed in some
+ // reasonably portable way. The underlying function that we will use returns
+ // a number of elapsed ticks. We can look up the number of ticks per second
+ // from the system configuration.
+ //
+ // Conceptually, we need to find the number of elapsed clock ticks and then
+ // multiply the result by the milliseconds per clock tick (or just as easily
+ // divide by clock ticks per millisecond). Integer dividing by clock ticks
+ // per millisecond is bad since this number is fractional on most machines
+ // and would result in divide by zero errors due to integer rounding.
+ //
+ // Multiplying by milliseconds per clock tick works up to a clock resolution
+ // of 1000 ticks per second. If we go past this point, we begin to get zero
+ // elapsed times when millisecondsPerTick becomes fractional and another
+ // rounding error appears.
+ //
+ // So rounding errors using integers can bite you from two direction. Since
+ // all of our targets have math coprocessors, why not just use doubles
+ // internally? Works fine, lasts a long time.
+ //
+ // If millisecondsPerTick becomes fractional, and an elapsed time greater than
+ // a milliscond is measured, the function will work as expected. If an elapsed
+ // time is measured that turns out to be less than a millisecond, we'll just
+ // return zero which would, I think, also will be expected.
+ //
+ static int64_t ticksPerSecond = CLOCKS_PER_SEC;
+ static double millisecondsPerTick = 1000. / ticksPerSecond;
+
+ clock_t endTime = clock ();
+
+ double tmp;
+
+ tmp = static_cast<double> (endTime - m_startTime) * millisecondsPerTick;
+ m_elapsedReal = static_cast<int64_t> (tmp);
+
+ //
+ // Nothing like this in MinGW, for example.
+ //
+ m_elapsedUser = 0;
+ m_elapsedSystem = 0;
+
+ return m_elapsedReal;
}
+int64_t
+SystemWallClockMsPrivate::GetElapsedReal (void) const
+{
+ return m_elapsedReal;
+}
+
+int64_t
+SystemWallClockMsPrivate::GetElapsedUser (void) const
+{
+ return m_elapsedUser;
+}
+
+int64_t
+SystemWallClockMsPrivate::GetElapsedSystem (void) const
+{
+ return m_elapsedSystem;
+}
+
SystemWallClockMs::SystemWallClockMs ()
: m_priv (new SystemWallClockMsPrivate ())
{}
@@ -55,10 +126,29 @@
{
m_priv->Start ();
}
-unsigned long long
+
+int64_t
SystemWallClockMs::End (void)
{
return m_priv->End ();
}
+int64_t
+SystemWallClockMs::GetElapsedReal (void) const
+{
+ return m_priv->GetElapsedReal ();
+}
+
+int64_t
+SystemWallClockMs::GetElapsedUser (void) const
+{
+ return m_priv->GetElapsedUser ();
+}
+
+int64_t
+SystemWallClockMs::GetElapsedSystem (void) const
+{
+ return m_priv->GetElapsedSystem ();
+}
+
}; // namespace ns3
--- a/src/devices/mesh/dot11s/hwmp-protocol.cc Mon Nov 02 18:08:16 2009 +0100
+++ b/src/devices/mesh/dot11s/hwmp-protocol.cc Mon Nov 02 18:16:09 2009 +0100
@@ -320,7 +320,7 @@
{
NS_ASSERT(destination != Mac48Address::GetBroadcast ());
HwmpRtable::LookupResult result = m_rtable->LookupReactive (destination);
- NS_LOG_DEBUG("Requested src = "<<source<<", dst = "<<destination<<", I am "<<GetAddress ()<<", RA = "<<result.retransmitter);
+ NS_LOG_DEBUG ("Requested src = "<<source<<", dst = "<<destination<<", I am "<<GetAddress ()<<", RA = "<<result.retransmitter);
if (result.retransmitter == Mac48Address::GetBroadcast ())
{
result = m_rtable->LookupProactive ();
@@ -477,6 +477,15 @@
preq.GetOriginatorSeqNumber ()
);
ProactivePathResolved ();
+ m_rtable->AddReactivePath (
+ preq.GetOriginatorAddress (),
+ from,
+ interface,
+ preq.GetMetric (),
+ MicroSeconds (preq.GetLifetime () * 1024),
+ preq.GetOriginatorSeqNumber ()
+ );
+ ReactivePathResolved (preq.GetOriginatorAddress ());
}
if (!preq.IsNeedNotPrep ())
{
@@ -611,11 +620,6 @@
}
if (result.retransmitter == Mac48Address::GetBroadcast ())
{
- //try to look for default route
- result = m_rtable->LookupProactive ();
- }
- if (result.retransmitter == Mac48Address::GetBroadcast ())
- {
return;
}
//Forward PREP
@@ -1008,7 +1012,6 @@
Time randomStart = Seconds (coefficient.GetValue ());
m_proactivePreqTimer = Simulator::Schedule (randomStart, &HwmpProtocol::SendProactivePreq, this);
NS_LOG_DEBUG ("ROOT IS: " << m_address);
- SendProactivePreq ();
m_isRoot = true;
}
void
--- a/src/devices/mesh/dot11s/peer-management-protocol.h Mon Nov 02 18:08:16 2009 +0100
+++ b/src/devices/mesh/dot11s/peer-management-protocol.h Mon Nov 02 18:16:09 2009 +0100
@@ -78,6 +78,7 @@
* \param interface the interface where a beacon was received from
* \param peerAddress address of station, which sent a beacon
* \param beaconInterval beacon interval (needed by beacon loss counter)
+ * \param beaconTiming beacon timing element (needed by BCA)
*/
void ReceiveBeacon (uint32_t interface, Mac48Address peerAddress, Time beaconInterval, Ptr<IeBeaconTiming> beaconTiming);
//\}
--- a/src/devices/mesh/flame/flame-protocol-mac.cc Mon Nov 02 18:08:16 2009 +0100
+++ b/src/devices/mesh/flame/flame-protocol-mac.cc Mon Nov 02 18:16:09 2009 +0100
@@ -31,6 +31,8 @@
}
FlameProtocolMac::~FlameProtocolMac ()
{
+ m_protocol = 0;
+ m_parent = 0;
}
void
FlameProtocolMac::SetParent (Ptr<MeshWifiInterfaceMac> parent)
--- a/src/devices/mesh/flame/flame-protocol.cc Mon Nov 02 18:08:16 2009 +0100
+++ b/src/devices/mesh/flame/flame-protocol.cc Mon Nov 02 18:16:09 2009 +0100
@@ -127,7 +127,7 @@
return tid;
}
FlameProtocol::FlameProtocol () :
- m_address (Mac48Address ()), m_broadcastInterval (Seconds (5)), m_lastBroadcast (Simulator::Now ()),
+ m_address (Mac48Address ()), m_broadcastInterval (Seconds (5)), m_lastBroadcast (Seconds (0)),
m_maxCost (32), m_myLastSeqno (1), m_rtable (CreateObject<FlameRtable> ())
{
}
@@ -137,6 +137,9 @@
void
FlameProtocol::DoDispose ()
{
+ m_interfaces.clear ();
+ m_rtable = 0;
+ m_mp = 0;
}
bool
FlameProtocol::RequestRoute (uint32_t sourceIface, const Mac48Address source, const Mac48Address destination,
@@ -224,8 +227,12 @@
m_stats.totalDropped++;
return false;
}
+ tag.receiver = result.retransmitter;
}
- tag.receiver = result.retransmitter;
+ else
+ {
+ tag.receiver = Mac48Address::GetBroadcast ();
+ }
if (result.retransmitter == Mac48Address::GetBroadcast ())
{
m_stats.txBroadcast++;
@@ -262,19 +269,21 @@
}
FlameHeader flameHdr;
packet->RemoveHeader (flameHdr);
- if ((destination == GetAddress ()) && (m_lastBroadcast + m_broadcastInterval < Simulator::Now ()))
- {
- Ptr<Packet> packet = Create<Packet> ();
- m_mp->Send(packet, Mac48Address::GetBroadcast (), 0);
- m_lastBroadcast = Simulator::Now ();
- }
- NS_ASSERT (protocolType == FLAME_PROTOCOL);
- protocolType = flameHdr.GetProtocol ();
- if ((HandleDataFrame (flameHdr.GetSeqno (), source, flameHdr, tag.transmitter, fromIface))
- || packet->GetSize () == 0)
+ if (HandleDataFrame (flameHdr.GetSeqno (), source, flameHdr, tag.transmitter, fromIface))
{
return false;
}
+ // Start PATH_UPDATE procedure if destination is our own address and last broadcast was sent more
+ // than broadcast interval ago or was not sent at all
+ if ((destination == GetAddress ()) && ((m_lastBroadcast + m_broadcastInterval < Simulator::Now ())
+ || (m_lastBroadcast == Seconds (0))))
+ {
+ Ptr<Packet> packet = Create<Packet> ();
+ m_mp->Send (packet, Mac48Address::GetBroadcast (), 0);
+ m_lastBroadcast = Simulator::Now ();
+ }
+ NS_ASSERT (protocolType == FLAME_PROTOCOL);
+ protocolType = flameHdr.GetProtocol ();
return true;
}
bool
--- a/src/helper/qos-wifi-mac-helper.cc Mon Nov 02 18:08:16 2009 +0100
+++ b/src/helper/qos-wifi-mac-helper.cc Mon Nov 02 18:16:09 2009 +0100
@@ -27,14 +27,7 @@
namespace ns3 {
QosWifiMacHelper::QosWifiMacHelper ()
-{
- ObjectFactory defaultAggregator;
- defaultAggregator.SetTypeId ("ns3::MsduStandardAggregator");
- m_aggregators.insert (std::make_pair (AC_VO, defaultAggregator));
- m_aggregators.insert (std::make_pair (AC_VI, defaultAggregator));
- m_aggregators.insert (std::make_pair (AC_BE, defaultAggregator));
- m_aggregators.insert (std::make_pair (AC_BK, defaultAggregator));
-}
+{}
QosWifiMacHelper::~QosWifiMacHelper ()
{}
@@ -77,8 +70,7 @@
std::string n2, const AttributeValue &v2,
std::string n3, const AttributeValue &v3)
{
- std::map<AccessClass, ObjectFactory>::iterator it;
- it = m_aggregators.find (accessClass);
+ std::map<AccessClass, ObjectFactory>::iterator it = m_aggregators.find (accessClass);
if (it != m_aggregators.end ())
{
it->second.SetTypeId (type);
@@ -87,17 +79,32 @@
it->second.Set (n2, v2);
it->second.Set (n3, v3);
}
+ else
+ {
+ ObjectFactory factory;
+ factory.SetTypeId (type);
+ factory.Set (n0, v0);
+ factory.Set (n1, v1);
+ factory.Set (n2, v2);
+ factory.Set (n3, v3);
+ m_aggregators.insert (std::make_pair (accessClass, factory));
+ }
}
void
QosWifiMacHelper::Setup (Ptr<WifiMac> mac, enum AccessClass ac, std::string dcaAttrName) const
{
- ObjectFactory factory = m_aggregators.find (ac)->second;
- PointerValue ptr;
- mac->GetAttribute (dcaAttrName, ptr);
- Ptr<EdcaTxopN> edca = ptr.Get<EdcaTxopN> ();
- Ptr<MsduAggregator> aggregator = factory.Create<MsduAggregator> ();
- edca->SetMsduAggregator (aggregator);
+ std::map<AccessClass, ObjectFactory>::const_iterator it = m_aggregators.find (ac);
+ if (it != m_aggregators.end ())
+ {
+ ObjectFactory factory = it->second;
+
+ PointerValue ptr;
+ mac->GetAttribute (dcaAttrName, ptr);
+ Ptr<EdcaTxopN> edca = ptr.Get<EdcaTxopN> ();
+ Ptr<MsduAggregator> aggregator = factory.Create<MsduAggregator> ();
+ edca->SetMsduAggregator (aggregator);
+ }
}
--- a/src/routing/olsr/olsr-routing-protocol.cc Mon Nov 02 18:08:16 2009 +0100
+++ b/src/routing/olsr/olsr-routing-protocol.cc Mon Nov 02 18:16:09 2009 +0100
@@ -552,7 +552,23 @@
}
}
- NS_LOG_DEBUG ("Size of N2: " << N2.size ());
+#ifdef NS3_LOG_ENABLE
+ {
+ std::ostringstream os;
+ os << "[";
+ for (TwoHopNeighborSet::const_iterator iter = N2.begin ();
+ iter != N2.end (); iter++)
+ {
+ TwoHopNeighborSet::const_iterator next = iter;
+ next++;
+ os << iter->neighborMainAddr << "->" << iter->twoHopNeighborAddr;
+ if (next != N2.end ())
+ os << ", ";
+ }
+ os << "]";
+ NS_LOG_DEBUG ("N2: " << os.str ());
+ }
+#endif //NS3_LOG_ENABLE
// 1. Start with an MPR set made of all members of N with
// N_willingness equal to WILL_ALWAYS
@@ -584,31 +600,38 @@
// 3. Add to the MPR set those nodes in N, which are the *only*
// nodes to provide reachability to a node in N2.
std::set<Ipv4Address> coveredTwoHopNeighbors;
- for (TwoHopNeighborSet::iterator twoHopNeigh = N2.begin (); twoHopNeigh != N2.end (); twoHopNeigh++)
+ for (TwoHopNeighborSet::const_iterator twoHopNeigh = N2.begin (); twoHopNeigh != N2.end (); twoHopNeigh++)
{
- NeighborSet::const_iterator onlyNeighbor = N.end ();
-
- for (NeighborSet::const_iterator neighbor = N.begin ();
- neighbor != N.end (); neighbor++)
+ bool onlyOne = true;
+ // try to find another neighbor that can reach twoHopNeigh->twoHopNeighborAddr
+ for (TwoHopNeighborSet::const_iterator otherTwoHopNeigh = N2.begin (); otherTwoHopNeigh != N2.end (); otherTwoHopNeigh++)
{
- if (neighbor->neighborMainAddr == twoHopNeigh->neighborMainAddr)
+ if (otherTwoHopNeigh->twoHopNeighborAddr == twoHopNeigh->twoHopNeighborAddr
+ && otherTwoHopNeigh->neighborMainAddr != twoHopNeigh->neighborMainAddr)
{
- if (onlyNeighbor == N.end ())
+ onlyOne = false;
+ break;
+ }
+ }
+ if (onlyOne)
+ {
+ NS_LOG_LOGIC ("Neighbor " << twoHopNeigh->neighborMainAddr
+ << " is the only that can reach 2-hop neigh. "
+ << twoHopNeigh->twoHopNeighborAddr
+ << " => select as MPR.");
+
+ mprSet.insert (twoHopNeigh->neighborMainAddr);
+
+ // take note of all the 2-hop neighbors reachable by the newly elected MPR
+ for (TwoHopNeighborSet::const_iterator otherTwoHopNeigh = N2.begin ();
+ otherTwoHopNeigh != N2.end (); otherTwoHopNeigh++)
+ {
+ if (otherTwoHopNeigh->neighborMainAddr == twoHopNeigh->neighborMainAddr)
{
- onlyNeighbor = neighbor;
- }
- else
- {
- onlyNeighbor = N.end ();
- break;
+ coveredTwoHopNeighbors.insert (otherTwoHopNeigh->twoHopNeighborAddr);
}
}
}
- if (onlyNeighbor != N.end ())
- {
- mprSet.insert (onlyNeighbor->neighborMainAddr);
- coveredTwoHopNeighbors.insert (twoHopNeigh->twoHopNeighborAddr);
- }
}
// Remove the nodes from N2 which are now covered by a node in the MPR set.
for (TwoHopNeighborSet::iterator twoHopNeigh = N2.begin ();
@@ -616,6 +639,7 @@
{
if (coveredTwoHopNeighbors.find (twoHopNeigh->twoHopNeighborAddr) != coveredTwoHopNeighbors.end ())
{
+ NS_LOG_LOGIC ("2-hop neigh. " << twoHopNeigh->twoHopNeighborAddr << " is already covered by an MPR.");
twoHopNeigh = N2.erase (twoHopNeigh);
}
else
@@ -628,6 +652,26 @@
// least one node in the MPR set:
while (N2.begin () != N2.end ())
{
+
+#ifdef NS3_LOG_ENABLE
+ {
+ std::ostringstream os;
+ os << "[";
+ for (TwoHopNeighborSet::const_iterator iter = N2.begin ();
+ iter != N2.end (); iter++)
+ {
+ TwoHopNeighborSet::const_iterator next = iter;
+ next++;
+ os << iter->neighborMainAddr << "->" << iter->twoHopNeighborAddr;
+ if (next != N2.end ())
+ os << ", ";
+ }
+ os << "]";
+ NS_LOG_DEBUG ("Step 4 iteration: N2=" << os.str ());
+ }
+#endif //NS3_LOG_ENABLE
+
+
// 4.1. For each node in N, calculate the reachability, i.e., the
// number of nodes in N2 which are not yet covered by at
// least one node in the MPR set, and which are reachable
--- a/test.py Mon Nov 02 18:08:16 2009 +0100
+++ b/test.py Mon Nov 02 18:16:09 2009 +0100
@@ -202,7 +202,8 @@
for example in dom.getElementsByTagName("Example"):
result = get_node_text(example.getElementsByTagName("Result")[0])
name = get_node_text(example.getElementsByTagName("Name")[0])
- output = "%s: Example \"%s\"\n" % (result, name)
+ time = get_node_text(example.getElementsByTagName("ElapsedTime")[0])
+ output = "%s: Example \"%s\" (%s)\n" % (result, name, time)
f.write(output)
f.close()
@@ -408,12 +409,13 @@
#
# The table headings look like,
#
- # +--------+--------------+
- # | Result | Example Name |
- # +--------+--------------+
+ # +--------+--------------+--------------+
+ # | Result | Example Name | Elapsed Time |
+ # +--------+--------------+--------------+
#
f.write("<th> Result </th>\n")
f.write("<th>Example Name</th>\n")
+ f.write("<th>Elapsed Time</th>\n")
#
# Now iterate through all of the examples
@@ -430,6 +432,7 @@
#
result = get_node_text(example.getElementsByTagName("Result")[0])
name = get_node_text(example.getElementsByTagName("Name")[0])
+ time = get_node_text(example.getElementsByTagName("ElapsedTime")[0])
#
# If the example either failed or crashed, print its result status
@@ -448,6 +451,11 @@
f.write("<td>%s</td>\n" % name)
#
+ # Write the elapsed time as a new tag data.
+ #
+ f.write("<td>%s</td>\n" % time)
+
+ #
# That's it for the current example, so terminate the row.
#
f.write("</tr>\n")
@@ -533,37 +541,68 @@
# path -- it is cooked up dynamically, so we do that too.
#
def make_library_path():
- global LIBRARY_PATH
+ have_DYLD_LIBRARY_PATH = False
+ have_LD_LIBRARY_PATH = False
+ have_PATH = False
- LIBRARY_PATH = "LD_LIBRARY_PATH=$LD_LIBRARY_PATH:'"
+ keys = os.environ.keys()
+ for key in keys:
+ if key == "DYLD_LIBRARY_PATH":
+ have_DYLD_LIBRARY_PATH = True
+ if key == "LD_LIBRARY_PATH":
+ have_LD_LIBRARY_PATH = True
+ if key == "PATH":
+ have_PATH = True
if sys.platform == "darwin":
- LIBRARY_PATH = "DYLD_LIBRARY_PATH='"
+ if not have_DYLD_LIBRARY_PATH:
+ os.environ["DYLD_LIBRARY_PATH"] = ""
+ for path in NS3_MODULE_PATH:
+ os.environ["DYLD_LIBRARY_PATH"] += ":" + path
+ if options.verbose:
+ print "os.environ[\"DYLD_LIBRARY_PATH\"] == %s" % os.environ["DYLD_LIBRARY_PATH"]
elif sys.platform == "win32":
- LIBRARY_PATH = "PATH=$PATH:'"
+ if not have_PATH:
+ os.environ["PATH"] = ""
+ for path in NS3_MODULE_PATH:
+ os.environ["PATH"] += ';' + path
+ if options.verbose:
+ print "os.environ[\"PATH\"] == %s" % os.environ["PATH"]
elif sys.platform == "cygwin":
- LIBRARY_PATH = "PATH=$PATH:'"
-
- for path in NS3_MODULE_PATH:
- LIBRARY_PATH = LIBRARY_PATH + path + ":"
-
- LIBRARY_PATH = LIBRARY_PATH + "'"
-
- if options.verbose:
- print "LIBRARY_PATH == %s" % LIBRARY_PATH
+ if not have_PATH:
+ os.environ["PATH"] = ""
+ for path in NS3_MODULE_PATH:
+ os.environ["PATH"] += ":" + path
+ if options.verbose:
+ print "os.environ[\"PATH\"] == %s" % os.environ["PATH"]
+ else:
+ if not have_LD_LIBRARY_PATH:
+ os.environ["LD_LIBRARY_PATH"] = ""
+ for path in NS3_MODULE_PATH:
+ os.environ["LD_LIBRARY_PATH"] += ":" + path
+ if options.verbose:
+ print "os.environ[\"LD_LIBRARY_PATH\"] == %s" % os.environ["LD_LIBRARY_PATH"]
def run_job_synchronously(shell_command, directory, valgrind):
+ path_cmd = os.path.join (NS3_BUILDDIR, NS3_ACTIVE_VARIANT, shell_command)
if valgrind:
- cmd = "%s valgrind --leak-check=full --error-exitcode=2 %s/%s/%s" % (LIBRARY_PATH, NS3_BUILDDIR, NS3_ACTIVE_VARIANT, shell_command)
+ cmd = "valgrind --leak-check=full --error-exitcode=2 %s" % path_cmd
else:
- cmd = "%s %s/%s/%s" % (LIBRARY_PATH, NS3_BUILDDIR, NS3_ACTIVE_VARIANT, shell_command)
+ cmd = path_cmd
if options.verbose:
print "Synchronously execute %s" % cmd
- proc = subprocess.Popen(cmd, shell=True, cwd=directory, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ start_time = time.time()
+ proc = subprocess.Popen(cmd, shell = True, cwd = directory, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout_results, stderr_results = proc.communicate()
- return (proc.returncode, stdout_results, stderr_results)
+ elapsed_time = time.time() - start_time
+
+ if options.verbose:
+ print "Return code = ", proc.returncode
+ print "stderr = ", stderr_results
+
+ return (proc.returncode, stdout_results, stderr_results, elapsed_time)
#
# This class defines a unit of testing work. It will typically refer to
@@ -580,6 +619,7 @@
self.cwd = ""
self.tmp_file_name = ""
self.returncode = False
+ self.elapsed_time = 0
#
# A job is either a standard job or a special job indicating that a worker
@@ -659,6 +699,12 @@
def set_returncode(self, returncode):
self.returncode = returncode
+ #
+ # The elapsed real time for the job execution.
+ #
+ def set_elapsed_time(self, elapsed_time):
+ self.elapsed_time = elapsed_time
+
#
# The worker thread class that handles the actual running of a given test.
# Once spawned, it receives requests for work through its input_queue and
@@ -711,17 +757,19 @@
# If we have an example, the shell command is all we need to
# know. It will be something like "examples/udp-echo"
#
- (job.returncode, standard_out, standard_err) = run_job_synchronously(job.shell_command, job.cwd,
- options.valgrind)
+ (job.returncode, standard_out, standard_err, et) = run_job_synchronously(job.shell_command,
+ job.cwd, options.valgrind)
else:
#
# If we're a test suite, we need to provide a little more info
# to the test runner, specifically the base directory and temp
# file name
#
- (job.returncode, standard_out, standard_err) = run_job_synchronously(job.shell_command +
+ (job.returncode, standard_out, standard_err, et) = run_job_synchronously(job.shell_command +
" --basedir=%s --out=%s" % (job.basedir, job.tmp_file_name), job.cwd, options.valgrind)
+ job.set_elapsed_time(et)
+
if options.verbose:
print "returncode = %d" % job.returncode
print "---------- beign standard out ----------"
@@ -756,11 +804,33 @@
# For example, if the user only wants to run BVT tests, we only have
# to build the test-runner and can ignore all of the examples.
#
+ # If the user only wants to run a single example, then we can just build
+ # that example.
+ #
+ # If there is no constraint, then we have to build everything since the
+ # user wants to run everything.
+ #
if options.kinds or options.list or (len(options.constrain) and options.constrain in core_kinds):
- proc = subprocess.Popen("./waf --target=test-runner", shell=True)
+ if sys.platform == "win32":
+ waf_cmd = "waf --target=test-runner"
+ else:
+ waf_cmd = "./waf --target=test-runner"
+ elif len(options.example):
+ if sys.platform == "win32":
+ waf_cmd = "waf --target=%s" % os.path.basename(options.example)
+ else:
+ waf_cmd = "./waf --target=%s" % os.path.basename(options.example)
+
else:
- proc = subprocess.Popen("./waf", shell=True)
+ if sys.platform == "win32":
+ waf_cmd = "waf"
+ else:
+ waf_cmd = "./waf"
+ if options.verbose:
+ print "Building: %s" % waf_cmd
+
+ proc = subprocess.Popen(waf_cmd, shell = True)
proc.communicate()
#
@@ -779,11 +849,13 @@
# handle them without doing all of the hard work.
#
if options.kinds:
- (rc, standard_out, standard_err) = run_job_synchronously("utils/test-runner --kinds", os.getcwd(), False)
+ path_cmd = os.path.join("utils", "test-runner --kinds")
+ (rc, standard_out, standard_err, et) = run_job_synchronously(path_cmd, os.getcwd(), False)
print standard_out
if options.list:
- (rc, standard_out, standard_err) = run_job_synchronously("utils/test-runner --list", os.getcwd(), False)
+ path_cmd = os.path.join("utils", "test-runner --list")
+ (rc, standard_out, standard_err, et) = run_job_synchronously(path_cmd, os.getcwd(), False)
print standard_out
if options.kinds or options.list:
@@ -854,10 +926,11 @@
suites = options.suite + "\n"
elif len(options.example) == 0:
if len(options.constrain):
- (rc, suites, standard_err) = run_job_synchronously("utils/test-runner --list --constrain=%s" %
- options.constrain, os.getcwd(), False)
+ path_cmd = os.path.join("utils", "test-runner --list --constrain=%s" % options.constrain)
+ (rc, suites, standard_err, et) = run_job_synchronously(path_cmd, os.getcwd(), False)
else:
- (rc, suites, standard_err) = run_job_synchronously("utils/test-runner --list", os.getcwd(), False)
+ path_cmd = os.path.join("utils", "test-runner --list")
+ (rc, suites, standard_err, et) = run_job_synchronously(path_cmd, os.getcwd(), False)
else:
suites = ""
@@ -888,13 +961,14 @@
#
processors = 1
- if 'SC_NPROCESSORS_ONLN'in os.sysconf_names:
- processors = os.sysconf('SC_NPROCESSORS_ONLN')
- else:
- proc = subprocess.Popen("sysctl -n hw.ncpu", shell = True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
- stdout_results, stderr_results = proc.communicate()
- if len(stderr_results) == 0:
- processors = int(stdout_results)
+ if sys.platform != "win32":
+ if 'SC_NPROCESSORS_ONLN'in os.sysconf_names:
+ processors = os.sysconf('SC_NPROCESSORS_ONLN')
+ else:
+ proc = subprocess.Popen("sysctl -n hw.ncpu", shell = True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ stdout_results, stderr_results = proc.communicate()
+ if len(stderr_results) == 0:
+ processors = int(stdout_results)
#
# Now, spin up one thread per processor which will eventually mean one test
@@ -922,6 +996,7 @@
# PASS, FAIL, CRASH and SKIP processing is done in the same place.
#
for test in suite_list:
+ test = test.strip()
if len(test):
job = Job()
job.set_is_example(False)
@@ -934,7 +1009,8 @@
else:
multiple = ""
- job.set_shell_command("utils/test-runner --suite='%s'%s" % (test, multiple))
+ path_cmd = os.path.join("utils", "test-runner --suite=%s%s" % (test, multiple))
+ job.set_shell_command(path_cmd)
if options.valgrind and test in core_valgrind_skip_tests:
job.set_is_skip(True)
@@ -1108,6 +1184,7 @@
else:
f.write(' <Result>CRASH</Result>\n')
+ f.write(' <ElapsedTime>%.3f</ElapsedTime>\n' % job.elapsed_time)
f.write('</Example>\n')
f.close()
@@ -1167,7 +1244,7 @@
else:
if job.returncode == 0 or job.returncode == 1 or job.returncode == 2:
f_to = open(xml_results_file, 'a')
- f_from = open(job.tmp_file_name, 'r')
+ f_from = open(job.tmp_file_name)
f_to.write(f_from.read())
f_to.close()
f_from.close()
--- a/utils/bench-packets.cc Mon Nov 02 18:08:16 2009 +0100
+++ b/utils/bench-packets.cc Mon Nov 02 18:16:09 2009 +0100
@@ -248,7 +248,7 @@
SystemWallClockMs time;
time.Start ();
(*bench) (n);
- unsigned long long deltaMs = time.End ();
+ uint64_t deltaMs = time.End ();
double ps = n;
ps *= 1000;
ps /= deltaMs;
--- a/wscript Mon Nov 02 18:08:16 2009 +0100
+++ b/wscript Mon Nov 02 18:16:09 2009 +0100
@@ -194,8 +194,13 @@
help=('Compile NS-3 statically: works only on linux, without python'),
dest='enable_static', action='store_true',
default=False)
+ opt.add_option('--doxygen-no-build',
+ help=('Run doxygen to generate html documentation from source comments, '
+ 'but do not wait for ns-3 to finish the full build.'),
+ action="store_true", default=False,
+ dest='doxygen_no_build')
- # options provided in a script in a subdirectory named "src"
+ # options provided in subdirectories
opt.sub_options('src')
opt.sub_options('bindings/python')
opt.sub_options('src/internet-stack')
@@ -282,13 +287,14 @@
env.append_value('CXXDEFINES', 'NS3_ASSERT_ENABLE')
env.append_value('CXXDEFINES', 'NS3_LOG_ENABLE')
- if Options.options.build_profile == 'release':
- env.append_value('CXXFLAGS', '-fomit-frame-pointer')
- env.append_value('CXXFLAGS', '-march=native')
-
env['PLATFORM'] = sys.platform
if conf.env['CXX_NAME'] in ['gcc', 'icc']:
+ if Options.options.build_profile == 'release':
+ env.append_value('CXXFLAGS', '-fomit-frame-pointer')
+ if conf.check_compilation_flag('-march=native'):
+ env.append_value('CXXFLAGS', '-march=native')
+
if sys.platform == 'win32':
env.append_value("LINKFLAGS", "-Wl,--enable-runtime-pseudo-reloc")
elif sys.platform == 'cygwin':
@@ -595,6 +601,11 @@
raise Utils.WafError("Cannot run regression tests: building the ns-3 examples is not enabled"
" (regression tests are based on examples)")
+
+ if Options.options.doxygen_no_build:
+ _doxygen(bld)
+ raise SystemExit(0)
+
def shutdown(ctx):
bld = wutils.bld
if wutils.bld is None:
@@ -711,9 +722,7 @@
env = wutils.bld.env
wutils.run_argv([shell], env, {'NS3_MODULE_PATH': os.pathsep.join(env['NS3_MODULE_PATH'])})
-def doxygen(bld):
- """do a full build, generate the introspected doxygen and then the doxygen"""
- Scripting.build(bld)
+def _doxygen(bld):
env = wutils.bld.env
proc_env = wutils.get_proc_env()
@@ -735,6 +744,11 @@
if subprocess.Popen(['doxygen', doxygen_config]).wait():
raise SystemExit(1)
+def doxygen(bld):
+ """do a full build, generate the introspected doxygen and then the doxygen"""
+ Scripting.build(bld)
+ _doxygen(bld)
+
def lcov_report():
env = Build.bld.env
variant_name = env['NS3_ACTIVE_VARIANT']