new Time implementation

This commit is contained in:
Mathieu Lacage
2006-10-28 21:21:34 +02:00
parent ab50c87bf2
commit 4449e8b51d
6 changed files with 214 additions and 165 deletions

View File

@@ -15,22 +15,22 @@ private:
void
MyModel::Start (void)
{
Simulator::Schedule (Time::RelS (10.0),
Simulator::Schedule (Now () + Seconds (10.0),
&MyModel::DealWithEvent,
this, Simulator::Now ().S ());
this, Simulator::Now ().ApproximateToSeconds ());
}
void
MyModel::DealWithEvent (double value)
{
std::cout << "Member method received event at " << Simulator::Now ().S () <<
"s started at " << value << "s" << std::endl;
std::cout << "Member method received event at " << Simulator::Now ().ApproximateToSeconds ()
<< "s started at " << value << "s" << std::endl;
}
static void
random_function (MyModel *model)
{
std::cout << "random function received event at " <<
Simulator::Now ().S () << "s" << std::endl;
Simulator::Now ().ApproximateToSeconds () << "s" << std::endl;
model->Start ();
}
@@ -39,7 +39,7 @@ int main (int argc, char *argv[])
{
MyModel model;
Simulator::Schedule (Time::AbsS (10.0), &random_function, &model);
Simulator::Schedule (Now () + Seconds (10.0), &random_function, &model);
Simulator::Run ();

View File

@@ -69,7 +69,7 @@ PcapWriter::WritePacket (Packet const packet)
{
if (m_writer != 0)
{
uint64_t current = Simulator::Now ().Us ();
uint64_t current = Simulator::Now ().ApproximateToMicroSeconds ();
uint64_t s = current / 1000000;
uint64_t us = current % 1000000;
Write32 (s & 0xffffffff);

View File

@@ -32,78 +32,68 @@ namespace ns3 {
* is expected to expire (see ns3::Simulator::schedule).
*/
class Time {
public:
public:
Time (Time const &o);
Time &operator = (Time const &o);
/**
* \returns the time stored in this
* instance as seconds.
*/
double S (void) const;
/**
* \returns the time stored in this
* instance as microseconds.
*/
uint64_t Us (void) const;
/**
* \returns the time stored in this
* instance as nanoseconds.
*/
uint64_t Ns (void) const;
/**
* \returns true if this instance represents
* the "destroy" time.
*/
bool IsDestroy (void) const;
/**
* \param s absolute time in seconds
* \returns a constructed Time object
*/
static Time AbsS (double s);
/**
* \param us absolute time in microseconds
* \returns a constructed Time object
*/
static Time AbsUs (uint64_t us);
/**
* \param ns absolute time in nanoseconds
* \returns a constructed Time object
*/
static Time AbsNs (uint64_t ns);
/**
* \param s relative time in seconds
* \returns a constructed Time object
*/
static Time RelS (double s);
/**
* \param us relative time in microseconds
* \returns a constructed Time object
*/
static Time RelUs (uint64_t us);
/**
* \param ns relative time in nanoseconds
* \returns a constructed Time object
*/
static Time RelNs (uint64_t ns);
/**
* \returns a constructed Time object which represents
* the current simulation time
*/
static Time Now (void);
/**
* \returns a constructed Time object which represents
* the current "destroy" simulation time, that
* is, the time when Simulator::destroy is
* invoked by the user.
*/
static Time Destroy (void);
private:
Time (uint64_t ns);
bool IsNegative (void) const;
bool IsPositive (void) const;
bool IsStrictlyNegative (void) const;
bool IsStrictlyPositive (void) const;
bool IsZero (void) const;
Time operator += (Time const &o);
Time operator -= (Time const &o);
double ApproximateToSeconds (void) const;
uint64_t ApproximateToMilliSeconds (void) const;
uint64_t ApproximateToMicroSeconds (void) const;
uint64_t ApproximateToNanoSeconds (void) const;
/* semi-public method. */
uint64_t Get (void) const;
protected:
Time (int64_t ns);
private:
Time ();
uint64_t m_ns;
bool m_isDestroy;
int64_t m_ns;
};
Time operator + (Time const &lhs, Time const &rhs);
Time operator - (Time const &lhs, Time const &rhs);
bool operator == (Time const &lhs, Time const &rhs);
bool operator != (Time const &lhs, Time const &rhs);
bool operator < (Time const &lhs, Time const &rhs);
bool operator <= (Time const &lhs, Time const &rhs);
bool operator > (Time const &lhs, Time const &rhs);
bool operator >= (Time const &lhs, Time const &rhs);
class Now : public Time {
public:
Now ();
};
class Seconds : public Time
{
public:
Seconds (double s);
};
class MilliSeconds : public Time
{
public:
MilliSeconds (int32_t ms);
};
class MicroSeconds : public Time
{
public:
MicroSeconds (int32_t us);
};
class NanoSeconds : public Time
{
public:
NanoSeconds (int64_t ns);
};
}; // namespace ns3

View File

@@ -67,6 +67,7 @@ public:
private:
void ProcessOneEvent (void);
uint64_t NextNs (void) const;
typedef std::list<std::pair<EventImpl *,uint32_t> > Events;
Events m_destroy;
@@ -138,20 +139,26 @@ SimulatorPrivate::IsFinished (void) const
{
return m_events->IsEmpty ();
}
Time
SimulatorPrivate::Next (void) const
uint64_t
SimulatorPrivate::NextNs (void) const
{
assert (!m_events->IsEmpty ());
Scheduler::EventKey nextKey = m_events->PeekNextKey ();
return Time::AbsNs (nextKey.m_ns);
return nextKey.m_ns;
}
Time
SimulatorPrivate::Next (void) const
{
return NanoSeconds (NextNs ());
}
void
SimulatorPrivate::Run (void)
{
while (!m_events->IsEmpty () && !m_stop &&
(m_stopAt == 0 || m_stopAt > Next ().Ns ()))
(m_stopAt == 0 || m_stopAt > NextNs ()))
{
ProcessOneEvent ();
}
@@ -167,29 +174,17 @@ SimulatorPrivate::Stop (void)
void
SimulatorPrivate::StopAt (Time const &at)
{
m_stopAt = at.Ns ();
m_stopAt = at.ApproximateToNanoSeconds ();
}
EventId
SimulatorPrivate::Schedule (Time const &time, EventImpl *event)
{
if (time.IsDestroy ())
{
m_destroy.push_back (std::make_pair (event, m_uid));
if (m_logEnable)
{
m_log << "id " << m_currentUid << " " << Now ().Ns () << " "
<< m_uid << std::endl;
}
m_uid++;
//XXX
return EventId ();
}
assert (time.Ns () >= Now ().Ns ());
Scheduler::EventKey key = {time.Ns (), m_uid};
assert (time.ApproximateToNanoSeconds () >= m_currentNs);
Scheduler::EventKey key = {time.ApproximateToNanoSeconds (), m_uid};
if (m_logEnable)
{
m_log << "i "<<m_currentUid<<" "<<Now ().Ns ()<<" "
<<m_uid<<" "<<time.Ns () << std::endl;
m_log << "i "<<m_currentUid<<" "<<m_currentNs<<" "
<<m_uid<<" "<<time.ApproximateToNanoSeconds () << std::endl;
}
m_uid++;
return m_events->Insert (event, key);
@@ -197,7 +192,7 @@ SimulatorPrivate::Schedule (Time const &time, EventImpl *event)
Time
SimulatorPrivate::Now (void) const
{
return Time::AbsNs (m_currentNs);
return NanoSeconds (m_currentNs);
}
void
@@ -208,7 +203,7 @@ SimulatorPrivate::Remove (EventId ev)
delete impl;
if (m_logEnable)
{
m_log << "r " << m_currentUid << " " << Now ().Ns () << " "
m_log << "r " << m_currentUid << " " << m_currentNs << " "
<< key.m_uid << " " << key.m_ns << std::endl;
}
}
@@ -225,7 +220,7 @@ bool
SimulatorPrivate::IsExpired (EventId ev)
{
if (ev.GetEventImpl () != 0 &&
ev.GetNs () <= Now ().Ns () &&
ev.GetNs () <= m_currentNs &&
ev.GetUid () < m_currentUid)
{
return false;
@@ -405,6 +400,7 @@ public:
virtual ~SimulatorTests ();
virtual bool RunTests (void);
private:
uint64_t NowUs ();
bool RunOneTest (void);
void A (int a);
void B (int b);
@@ -422,6 +418,12 @@ SimulatorTests::SimulatorTests ()
{}
SimulatorTests::~SimulatorTests ()
{}
uint64_t
SimulatorTests::NowUs (void)
{
uint64_t ns = Now ().ApproximateToNanoSeconds ();
return ns / 1000;
}
void
SimulatorTests::A (int a)
{
@@ -430,7 +432,7 @@ SimulatorTests::A (int a)
void
SimulatorTests::B (int b)
{
if (b != 2 || Simulator::Now ().Us () != 11)
if (b != 2 || NowUs () != 11)
{
m_b = false;
}
@@ -439,7 +441,7 @@ SimulatorTests::B (int b)
m_b = true;
}
Simulator::Remove (m_idC);
Simulator::Schedule (Time::RelUs (10), &SimulatorTests::D, this, 4);
Simulator::Schedule (Now () + MicroSeconds (10), &SimulatorTests::D, this, 4);
}
void
SimulatorTests::C (int c)
@@ -449,7 +451,7 @@ SimulatorTests::C (int c)
void
SimulatorTests::D (int d)
{
if (d != 4 || Simulator::Now ().Us () != (11+10))
if (d != 4 || NowUs () != (11+10))
{
m_d = false;
}
@@ -467,9 +469,9 @@ SimulatorTests::RunOneTest (void)
m_c = true;
m_d = false;
EventId a = Simulator::Schedule (Time::AbsUs (10), &SimulatorTests::A, this, 1);
Simulator::Schedule (Time::AbsUs (11), &SimulatorTests::B, this, 2);
m_idC = Simulator::Schedule (Time::AbsUs (12), &SimulatorTests::C, this, 3);
EventId a = Simulator::Schedule (Now () + MicroSeconds (10), &SimulatorTests::A, this, 1);
Simulator::Schedule (Now () + MicroSeconds (11), &SimulatorTests::B, this, 2);
m_idC = Simulator::Schedule (Now () + MicroSeconds (12), &SimulatorTests::C, this, 3);
Simulator::Cancel (a);
Simulator::Run ();

View File

@@ -24,94 +24,151 @@
namespace ns3 {
Time::Time ()
: m_ns (0),
m_isDestroy (true)
: m_ns (0)
{}
Time::Time (Time const &o)
: m_ns (o.m_ns),
m_isDestroy (o.m_isDestroy)
: m_ns (o.m_ns)
{}
Time &
Time::operator = (Time const &o)
{
m_ns = o.m_ns;
m_isDestroy = o.m_isDestroy;
return *this;
m_ns = o.m_ns;
return *this;
}
Time::Time (uint64_t ns)
: m_ns (ns),
m_isDestroy (false)
Time::Time (int64_t ns)
: m_ns (ns)
{}
bool
Time::IsNegative (void) const
{
return m_ns <= 0;
}
bool
Time::IsPositive (void) const
{
return m_ns >= 0;
}
bool
Time::IsStrictlyNegative (void) const
{
return m_ns < 0;
}
bool
Time::IsStrictlyPositive (void) const
{
return m_ns > 0;
}
bool
Time::IsZero (void) const
{
return m_ns == 0;
}
Time
Time::operator += (Time const &o)
{
m_ns += o.m_ns;
return *this;
}
Time
Time::operator -= (Time const &o)
{
m_ns -= o.m_ns;
return *this;
}
double
Time::S (void) const
Time::ApproximateToSeconds (void) const
{
double ns = m_ns;
ns /= 1000000000;
return ns;
double s = m_ns;
s /= 1000000000;
return s;
}
uint64_t
Time::Us (void) const
Time::ApproximateToMilliSeconds (void) const
{
uint64_t us = m_ns / 1000;
return us;
uint64_t ms = m_ns;
ms /= 1000000;
return ms;
}
uint64_t
Time::Ns (void) const
Time::ApproximateToMicroSeconds (void) const
{
return m_ns;
uint64_t us = m_ns;
us /= 1000;
return us;
}
uint64_t
Time::ApproximateToNanoSeconds (void) const
{
return m_ns;
}
bool
Time::IsDestroy (void) const
/* To decrease the number of keystrokes
*/
static uint64_t
GetNs (Time const &time)
{
return m_isDestroy;
return time.ApproximateToNanoSeconds ();
}
Time
Time::AbsS (double s)
Time operator + (Time const &lhs, Time const &rhs)
{
int64_t ns = (int64_t)(s * 1000000000.0);
return Time (ns);
return NanoSeconds (GetNs (lhs) + GetNs (rhs));
}
Time operator - (Time const &lhs, Time const &rhs)
{
return NanoSeconds (GetNs (lhs) - GetNs (rhs));
}
Time
Time::AbsUs (uint64_t us)
bool operator == (Time const &lhs, Time const &rhs)
{
int64_t ns = us * 1000;
return Time (ns);
}
Time
Time::AbsNs (uint64_t ns)
{
return Time (ns);
}
Time
Time::RelS (double s)
{
int64_t ns = (int64_t)(s * 1000000000.0);
return Time (Simulator::Now ().Ns () + ns);
}
Time
Time::RelUs (uint64_t us)
{
return Time (Simulator::Now ().Ns () + us * 1000);
}
Time
Time::RelNs (uint64_t ns)
{
return Time (Simulator::Now ().Ns () + ns);
return GetNs (lhs) == GetNs (rhs);
}
Time
Time::Now (void)
bool operator != (Time const &lhs, Time const &rhs)
{
return Time (Simulator::Now ().Ns ());
return GetNs (lhs) != GetNs (rhs);
}
Time
Time::Destroy (void)
bool operator < (Time const &lhs, Time const &rhs)
{
return Time ();
return GetNs (lhs) < GetNs (rhs);
}
bool operator <= (Time const &lhs, Time const &rhs)
{
return GetNs (lhs) <= GetNs (rhs);
}
bool operator > (Time const &lhs, Time const &rhs)
{
return GetNs (lhs) > GetNs (rhs);
}
bool operator >= (Time const &lhs, Time const &rhs)
{
return GetNs (lhs) >= GetNs (rhs);
}
Now::Now ()
: Time (Simulator::Now ())
{}
Seconds::Seconds (double s)
: Time ((int64_t)(s * 1000000000))
{}
MilliSeconds::MilliSeconds (int32_t ms)
: Time ((int64_t)(ms * 1000000))
{}
MicroSeconds::MicroSeconds (int32_t us)
: Time ((int64_t)(us * 1000))
{}
NanoSeconds::NanoSeconds (int64_t ns)
: Time (ns)
{}
}; // namespace ns3

View File

@@ -73,7 +73,7 @@ Bench::RunBench (void)
time.Start ();
for (std::vector<uint64_t>::const_iterator i = m_distribution.begin ();
i != m_distribution.end (); i++) {
Simulator::Schedule (Time::AbsNs (*i), &Bench::Cb, this);
Simulator::Schedule (Now () + NanoSeconds (*i), &Bench::Cb, this);
}
init = time.End ();
@@ -103,9 +103,9 @@ Bench::Cb (void)
m_current = m_distribution.begin ();
}
if (gDebug) {
std::cerr << "event at " << Simulator::Now ().S () << "s" << std::endl;
std::cerr << "event at " << Simulator::Now ().ApproximateToSeconds () << "s" << std::endl;
}
Simulator::Schedule (Time::AbsNs (*m_current), &Bench::Cb, this);
Simulator::Schedule (Now () + NanoSeconds (*m_current), &Bench::Cb, this);
m_current++;
m_n++;
}