View | Details | Raw Unified | Return to bug 21
Collapse All | Expand All

(-)a/src/core/random-variable.h (-1 / +1 lines)
 Lines 23-29    Link Here 
23
23
24
#include <vector>
24
#include <vector>
25
#include <algorithm>
25
#include <algorithm>
26
26
#include "ns3/cairo-wideint-private.h"
27
27
28
/**
28
/**
29
 * \defgroup randomvariable Random Variable Distributions
29
 * \defgroup randomvariable Random Variable Distributions
(-)a/src/core/rng-stream.h (+1 lines)
 Lines 20-25    Link Here 
20
#ifndef RNGSTREAM_H
20
#ifndef RNGSTREAM_H
21
#define RNGSTREAM_H
21
#define RNGSTREAM_H
22
#include <string>
22
#include <string>
23
#include "ns3/cairo-wideint-private.h"
23
24
24
namespace ns3{
25
namespace ns3{
25
26
(-)a/src/simulator/event-id.cc (-5 / +5 lines)
 Lines 26-38   namespace ns3 { Link Here 
26
26
27
EventId::EventId ()
27
EventId::EventId ()
28
  : m_eventImpl (0),
28
  : m_eventImpl (0),
29
    m_ns (0),
29
    m_ts (0),
30
    m_uid (0)
30
    m_uid (0)
31
{}
31
{}
32
  
32
  
33
EventId::EventId (EventImpl *impl, uint64_t ns, uint32_t uid)
33
EventId::EventId (EventImpl *impl, uint64_t ts, uint32_t uid)
34
  : m_eventImpl (impl),
34
  : m_eventImpl (impl),
35
    m_ns (ns),
35
    m_ts (ts),
36
    m_uid (uid)
36
    m_uid (uid)
37
{}
37
{}
38
void 
38
void 
 Lines 60-68   EventId::GetEventImpl (void) const Link Here 
60
  return m_eventImpl;
60
  return m_eventImpl;
61
}
61
}
62
uint64_t 
62
uint64_t 
63
EventId::GetNs (void) const
63
EventId::GetTs (void) const
64
{
64
{
65
  return m_ns;
65
  return m_ts;
66
}
66
}
67
uint32_t 
67
uint32_t 
68
EventId::GetUid (void) const
68
EventId::GetUid (void) const
(-)a/src/simulator/event-id.h (-3 / +3 lines)
 Lines 33-39   class EventId { Link Here 
33
class EventId {
33
class EventId {
34
public:
34
public:
35
  EventId ();
35
  EventId ();
36
  EventId (EventImpl *impl, uint64_t ns, uint32_t uid);
36
  EventId (EventImpl *impl, uint64_t ts, uint32_t uid);
37
  /**
37
  /**
38
   * This method is syntactic sugar for the ns3::Simulator::cancel
38
   * This method is syntactic sugar for the ns3::Simulator::cancel
39
   * method.
39
   * method.
 Lines 52-62   public: Link Here 
52
   * subclasses of the Scheduler base class.
52
   * subclasses of the Scheduler base class.
53
   */
53
   */
54
  EventImpl *GetEventImpl (void) const;
54
  EventImpl *GetEventImpl (void) const;
55
  uint64_t GetNs (void) const;
55
  uint64_t GetTs (void) const;
56
  uint32_t GetUid (void) const;
56
  uint32_t GetUid (void) const;
57
private:
57
private:
58
  EventImpl *m_eventImpl;
58
  EventImpl *m_eventImpl;
59
  uint64_t m_ns;
59
  uint64_t m_ts;
60
  uint32_t m_uid;
60
  uint32_t m_uid;
61
};
61
};
62
62
(-)a/src/simulator/scheduler-heap.cc (-4 / +4 lines)
 Lines 138-148   bool Link Here 
138
bool
138
bool
139
SchedulerHeap::IsLowerStrictly (Scheduler::EventKey const*a, Scheduler::EventKey const*b) const
139
SchedulerHeap::IsLowerStrictly (Scheduler::EventKey const*a, Scheduler::EventKey const*b) const
140
{
140
{
141
  if (a->m_ns < b->m_ns)
141
  if (a->m_ts < b->m_ts)
142
    {
142
    {
143
      return true;
143
      return true;
144
    }
144
    }
145
  else if (a->m_ns > b->m_ns)
145
  else if (a->m_ts > b->m_ts)
146
    {
146
    {
147
      return false;
147
      return false;
148
    } 
148
    } 
 Lines 226-232   SchedulerHeap::RealInsert (EventImpl *ev Link Here 
226
{
226
{
227
  m_heap.push_back (std::make_pair (event, key));
227
  m_heap.push_back (std::make_pair (event, key));
228
  BottomUp ();
228
  BottomUp ();
229
  return EventId (event, key.m_ns, key.m_uid);
229
  return EventId (event, key.m_ts, key.m_uid);
230
}
230
}
231
231
232
EventImpl *
232
EventImpl *
 Lines 251-257   EventImpl * Link Here 
251
EventImpl *
251
EventImpl *
252
SchedulerHeap::RealRemove (EventId id, Scheduler::EventKey *key)
252
SchedulerHeap::RealRemove (EventId id, Scheduler::EventKey *key)
253
{
253
{
254
  key->m_ns = id.GetNs ();
254
  key->m_ts = id.GetTs ();
255
  key->m_uid = id.GetUid ();
255
  key->m_uid = id.GetUid ();
256
  for (uint32_t i = 1; i < m_heap.size (); i++)
256
  for (uint32_t i = 1; i < m_heap.size (); i++)
257
    {
257
    {
(-)a/src/simulator/scheduler-list.cc (-5 / +5 lines)
 Lines 50-60   bool Link Here 
50
bool 
50
bool 
51
SchedulerList::IsLower (Scheduler::EventKey const*a, Scheduler::EventKey const*b) const
51
SchedulerList::IsLower (Scheduler::EventKey const*a, Scheduler::EventKey const*b) const
52
{
52
{
53
  if (a->m_ns < b->m_ns)
53
  if (a->m_ts < b->m_ts)
54
    {
54
    {
55
      return true;
55
      return true;
56
    }
56
    }
57
  else if (a->m_ns == b->m_ns &&
57
  else if (a->m_ts == b->m_ts &&
58
           a->m_uid < b->m_uid)
58
           a->m_uid < b->m_uid)
59
    {
59
    {
60
      return true;
60
      return true;
 Lines 73-83   SchedulerList::RealInsert (EventImpl *ev Link Here 
73
      if (IsLower (&key, &i->second))
73
      if (IsLower (&key, &i->second))
74
        {
74
        {
75
          m_events.insert (i, std::make_pair (event, key));
75
          m_events.insert (i, std::make_pair (event, key));
76
          return EventId (event, key.m_ns, key.m_uid);
76
          return EventId (event, key.m_ts, key.m_uid);
77
        }
77
        }
78
    }
78
    }
79
  m_events.push_back (std::make_pair (event, key));
79
  m_events.push_back (std::make_pair (event, key));
80
  return EventId (event, key.m_ns, key.m_uid);
80
  return EventId (event, key.m_ts, key.m_uid);
81
}
81
}
82
bool 
82
bool 
83
SchedulerList::RealIsEmpty (void) const
83
SchedulerList::RealIsEmpty (void) const
 Lines 110-116   SchedulerList::RealRemove (EventId id, S Link Here 
110
        {
110
        {
111
          EventImpl *retval = i->first;
111
          EventImpl *retval = i->first;
112
          NS_ASSERT (id.GetEventImpl () == retval);
112
          NS_ASSERT (id.GetEventImpl () == retval);
113
          key->m_ns = id.GetNs ();
113
          key->m_ts = id.GetTs ();
114
          key->m_uid = id.GetUid ();
114
          key->m_uid = id.GetUid ();
115
          m_events.erase (i);
115
          m_events.erase (i);
116
          return retval;
116
          return retval;
(-)a/src/simulator/scheduler-map.cc (-4 / +4 lines)
 Lines 66-76   bool Link Here 
66
bool
66
bool
67
SchedulerMap::EventKeyCompare::operator () (struct EventKey const&a, struct EventKey const&b)
67
SchedulerMap::EventKeyCompare::operator () (struct EventKey const&a, struct EventKey const&b)
68
{
68
{
69
  if (a.m_ns < b.m_ns) 
69
  if (a.m_ts < b.m_ts) 
70
    {
70
    {
71
      return true;
71
      return true;
72
    } 
72
    } 
73
  else if (a.m_ns > b.m_ns)
73
  else if (a.m_ts > b.m_ts)
74
    {
74
    {
75
      return false;
75
      return false;
76
    } 
76
    } 
 Lines 92-98   SchedulerMap::RealInsert (EventImpl *eve Link Here 
92
  std::pair<EventMapI,bool> result;
92
  std::pair<EventMapI,bool> result;
93
  result = m_list.insert (std::make_pair (key, event));
93
  result = m_list.insert (std::make_pair (key, event));
94
  NS_ASSERT (result.second);
94
  NS_ASSERT (result.second);
95
  return EventId (event, key.m_ns, key.m_uid);
95
  return EventId (event, key.m_ts, key.m_uid);
96
}
96
}
97
97
98
bool
98
bool
 Lines 124-130   EventImpl * Link Here 
124
EventImpl *
124
EventImpl *
125
SchedulerMap::RealRemove (EventId id, Scheduler::EventKey *key)
125
SchedulerMap::RealRemove (EventId id, Scheduler::EventKey *key)
126
{
126
{
127
  key->m_ns = id.GetNs ();
127
  key->m_ts = id.GetTs ();
128
  key->m_uid = id.GetUid ();
128
  key->m_uid = id.GetUid ();
129
  EventMapI i = m_list.find (*key);
129
  EventMapI i = m_list.find (*key);
130
  EventImpl *retval = i->second;
130
  EventImpl *retval = i->second;
(-)a/src/simulator/scheduler.h (-1 / +1 lines)
 Lines 55-61   class Scheduler { Link Here 
55
class Scheduler {
55
class Scheduler {
56
 public:
56
 public:
57
  struct EventKey {
57
  struct EventKey {
58
      uint64_t m_ns;
58
      uint64_t m_ts;
59
      uint32_t m_uid;
59
      uint32_t m_uid;
60
  };
60
  };
61
61
(-)a/src/simulator/simulator.cc (-28 / +27 lines)
 Lines 72-78   public: Link Here 
72
72
73
private:
73
private:
74
  void ProcessOneEvent (void);
74
  void ProcessOneEvent (void);
75
  uint64_t NextNs (void) const;
75
  uint64_t NextTs (void) const;
76
76
77
  typedef std::list<std::pair<EventImpl *,uint32_t> > Events;
77
  typedef std::list<std::pair<EventImpl *,uint32_t> > Events;
78
  Events m_destroy;
78
  Events m_destroy;
 Lines 81-87   private: Link Here 
81
  Scheduler *m_events;
81
  Scheduler *m_events;
82
  uint32_t m_uid;
82
  uint32_t m_uid;
83
  uint32_t m_currentUid;
83
  uint32_t m_currentUid;
84
  uint64_t m_currentNs;
84
  uint64_t m_currentTs;
85
  std::ofstream m_log;
85
  std::ofstream m_log;
86
  std::ifstream m_inputLog;
86
  std::ifstream m_inputLog;
87
  bool m_logEnable;
87
  bool m_logEnable;
 Lines 103-109   SimulatorPrivate::SimulatorPrivate (Sche Link Here 
103
  // before ::Run is entered, the m_currentUid will be zero
103
  // before ::Run is entered, the m_currentUid will be zero
104
  m_currentUid = 0;
104
  m_currentUid = 0;
105
  m_logEnable = false;
105
  m_logEnable = false;
106
  m_currentNs = 0;
106
  m_currentTs = 0;
107
  m_unscheduledEvents = 0;
107
  m_unscheduledEvents = 0;
108
}
108
}
109
109
 Lines 136-150   SimulatorPrivate::ProcessOneEvent (void) Link Here 
136
  Scheduler::EventKey nextKey = m_events->PeekNextKey ();
136
  Scheduler::EventKey nextKey = m_events->PeekNextKey ();
137
  m_events->RemoveNext ();
137
  m_events->RemoveNext ();
138
138
139
  NS_ASSERT (nextKey.m_ns >= m_currentNs);
139
  NS_ASSERT (nextKey.m_ts >= m_currentTs);
140
  --m_unscheduledEvents;
140
  --m_unscheduledEvents;
141
141
142
  TRACE ("handle " << nextEv);
142
  TRACE ("handle " << nextEv);
143
  m_currentNs = nextKey.m_ns;
143
  m_currentTs = nextKey.m_ts;
144
  m_currentUid = nextKey.m_uid;
144
  m_currentUid = nextKey.m_uid;
145
  if (m_logEnable) 
145
  if (m_logEnable) 
146
    {
146
    {
147
      m_log << "e "<<nextKey.m_uid << " " << nextKey.m_ns << std::endl;
147
      m_log << "e "<<nextKey.m_uid << " " << nextKey.m_ts << std::endl;
148
    }
148
    }
149
  nextEv->Invoke ();
149
  nextEv->Invoke ();
150
  delete nextEv;
150
  delete nextEv;
 Lines 156-180   SimulatorPrivate::IsFinished (void) cons Link Here 
156
  return m_events->IsEmpty ();
156
  return m_events->IsEmpty ();
157
}
157
}
158
uint64_t
158
uint64_t
159
SimulatorPrivate::NextNs (void) const
159
SimulatorPrivate::NextTs (void) const
160
{
160
{
161
  NS_ASSERT (!m_events->IsEmpty ());
161
  NS_ASSERT (!m_events->IsEmpty ());
162
  Scheduler::EventKey nextKey = m_events->PeekNextKey ();
162
  Scheduler::EventKey nextKey = m_events->PeekNextKey ();
163
  return nextKey.m_ns;
163
  return nextKey.m_ts;
164
}
164
}
165
Time
165
Time
166
SimulatorPrivate::Next (void) const
166
SimulatorPrivate::Next (void) const
167
{
167
{
168
  return NanoSeconds (NextNs ());
168
  return TimeStep (NextTs ());
169
}
169
}
170
171
170
172
void
171
void
173
SimulatorPrivate::Run (void)
172
SimulatorPrivate::Run (void)
174
{
173
{
175
174
176
  while (!m_events->IsEmpty () && !m_stop && 
175
  while (!m_events->IsEmpty () && !m_stop && 
177
         (m_stopAt == 0 || m_stopAt > NextNs ())) 
176
         (m_stopAt == 0 || m_stopAt > NextTs ())) 
178
    {
177
    {
179
      ProcessOneEvent ();
178
      ProcessOneEvent ();
180
    }
179
    }
 Lines 196-214   SimulatorPrivate::StopAt (Time const &at Link Here 
196
SimulatorPrivate::StopAt (Time const &at)
195
SimulatorPrivate::StopAt (Time const &at)
197
{
196
{
198
  NS_ASSERT (at.IsPositive ());
197
  NS_ASSERT (at.IsPositive ());
199
  m_stopAt = at.GetNanoSeconds ();
198
  m_stopAt = at.GetTimeStep ();
200
}
199
}
201
EventId
200
EventId
202
SimulatorPrivate::Schedule (Time const &time, EventImpl *event)
201
SimulatorPrivate::Schedule (Time const &time, EventImpl *event)
203
{
202
{
204
  NS_ASSERT (time.IsPositive ());
203
  NS_ASSERT (time.IsPositive ());
205
  NS_ASSERT (time >= NanoSeconds (m_currentNs));
204
  NS_ASSERT (time >= TimeStep (m_currentTs));
206
  uint64_t ns = (uint64_t) time.GetNanoSeconds ();
205
  uint64_t ts = (uint64_t) time.GetTimeStep ();
207
  Scheduler::EventKey key = {ns, m_uid};
206
  Scheduler::EventKey key = {ts, m_uid};
208
  if (m_logEnable) 
207
  if (m_logEnable) 
209
    {
208
    {
210
      m_log << "i "<<m_currentUid<<" "<<m_currentNs<<" "
209
      m_log << "i "<<m_currentUid<<" "<<m_currentTs<<" "
211
            <<m_uid<<" "<<time.GetNanoSeconds () << std::endl;
210
            <<m_uid<<" "<<time.GetTimeStep () << std::endl;
212
    }
211
    }
213
  m_uid++;
212
  m_uid++;
214
  ++m_unscheduledEvents;
213
  ++m_unscheduledEvents;
 Lines 217-228   void Link Here 
217
void 
216
void 
218
SimulatorPrivate::ScheduleNow (EventImpl *event)
217
SimulatorPrivate::ScheduleNow (EventImpl *event)
219
{
218
{
220
  uint64_t ns = m_currentNs;
219
  uint64_t ts = m_currentTs;
221
  Scheduler::EventKey key = {ns, m_uid};
220
  Scheduler::EventKey key = {ts, m_uid};
222
  if (m_logEnable) 
221
  if (m_logEnable) 
223
    {
222
    {
224
      m_log << "i "<<m_currentUid<<" "<<m_currentNs<<" "
223
      m_log << "i "<<m_currentUid<<" "<<m_currentTs<<" "
225
            <<m_uid<<" "<<ns << std::endl;
224
            <<m_uid<<" "<<ts << std::endl;
226
    }
225
    }
227
  m_uid++;
226
  m_uid++;
228
  ++m_unscheduledEvents;
227
  ++m_unscheduledEvents;
 Lines 234-240   SimulatorPrivate::ScheduleDestroy (Event Link Here 
234
  m_destroy.push_back (std::make_pair (event, m_uid));  
233
  m_destroy.push_back (std::make_pair (event, m_uid));  
235
  if (m_logEnable) 
234
  if (m_logEnable) 
236
  {
235
  {
237
    m_log << "id " << m_currentUid << " " << Now ().GetNanoSeconds () << " "
236
    m_log << "id " << m_currentUid << " " << Now ().GetTimeStep () << " "
238
          << m_uid << std::endl;
237
          << m_uid << std::endl;
239
  }
238
  }
240
  m_uid++;
239
  m_uid++;
 Lines 243-249   Time Link Here 
243
Time
242
Time
244
SimulatorPrivate::Now (void) const
243
SimulatorPrivate::Now (void) const
245
{
244
{
246
  return NanoSeconds (m_currentNs);
245
  return TimeStep (m_currentTs);
247
}
246
}
248
247
249
void
248
void
 Lines 254-261   SimulatorPrivate::Remove (EventId ev) Link Here 
254
  delete impl;
253
  delete impl;
255
  if (m_logEnable) 
254
  if (m_logEnable) 
256
    {
255
    {
257
      m_log << "r " << m_currentUid << " " << m_currentNs << " "
256
      m_log << "r " << m_currentUid << " " << m_currentTs << " "
258
            << key.m_uid << " " << key.m_ns << std::endl;
257
            << key.m_uid << " " << key.m_ts << std::endl;
259
    }
258
    }
260
  --m_unscheduledEvents;
259
  --m_unscheduledEvents;
261
}
260
}
 Lines 270-277   SimulatorPrivate::IsExpired (EventId ev) Link Here 
270
SimulatorPrivate::IsExpired (EventId ev)
269
SimulatorPrivate::IsExpired (EventId ev)
271
{
270
{
272
  if (ev.GetEventImpl () == 0 ||
271
  if (ev.GetEventImpl () == 0 ||
273
      ev.GetNs () < m_currentNs ||
272
      ev.GetTs () < m_currentTs ||
274
      (ev.GetNs () == m_currentNs &&
273
      (ev.GetTs () == m_currentTs &&
275
       ev.GetUid () <= m_currentUid) ||
274
       ev.GetUid () <= m_currentUid) ||
276
      ev.GetEventImpl ()->IsCancelled ()) 
275
      ev.GetEventImpl ()->IsCancelled ()) 
277
    {
276
    {
(-)a/src/simulator/nstime.h (-3 / +87 lines)
 Lines 22-30    Link Here 
22
#define TIME_H
22
#define TIME_H
23
23
24
#include <stdint.h>
24
#include <stdint.h>
25
#include <math.h>
25
#include "ns3/assert.h"
26
#include "ns3/assert.h"
26
#include <ostream>
27
#include <ostream>
27
#include "high-precision.h"
28
#include "high-precision.h"
29
#include "cairo-wideint-private.h"
28
30
29
namespace ns3 {
31
namespace ns3 {
30
32
 Lines 73-78   namespace ns3 { Link Here 
73
 *  - \ref ns3-Time-Max ns3::Max
75
 *  - \ref ns3-Time-Max ns3::Max
74
 *  - \ref ns3-Time-Min ns3::Min
76
 *  - \ref ns3-Time-Min ns3::Min
75
 */
77
 */
78
  
79
typedef uint8_t ts_precision_t;
80
  /**
81
   * Determines the base unit to store time values. If the
82
   * SetTsPrecision function is called, it must be set before any
83
   * TimeValue objects are created. All TimeUnit objects will use the
84
   * same time precision value.  The actual time can be
85
   * extracted as follows: m_data*10^(-m_tsPrecision) seconds.
86
   * m_tsPrecision == 0 : m_data stored in sec
87
   * m_tsPrecision == 3 : m_data stored in ms
88
   * m_tsPrecision == 6 : m_data stored in us
89
   * m_tsPrecision == 9 : m_data stored in ns
90
   * m_tsPrecision == 12 : m_data stored in ps
91
   * The default timestep precision units are ns.
92
   */
93
enum PrecisionType {
94
  SEC = 0,
95
  MS = 3,
96
  US = 6,
97
  NS = 9,
98
  PS = 12,
99
  FS = 15
100
};
101
static ts_precision_t m_tsPrecision = NS;
102
static int64_t m_tsPrecisionFactor = (int64_t)pow(10,m_tsPrecision);
103
  // static void SetTsPrecision(ts_precision_t tsPrecision);
104
  // static ts_precision_t GetTsPrecision();
105
76
template <int N>
106
template <int N>
77
class TimeUnit
107
class TimeUnit
78
{
108
{
 Lines 235-240   TimeUnit<N1+N2> operator * (TimeUnit<N1> Link Here 
235
{
265
{
236
  HighPrecision retval = lhs.GetHighPrecision ();
266
  HighPrecision retval = lhs.GetHighPrecision ();
237
  retval.Mul (rhs.GetHighPrecision ());
267
  retval.Mul (rhs.GetHighPrecision ());
268
  //    std::cout << lhs.GetHighPrecision().GetInteger() << " * " 
269
  //              << rhs.GetHighPrecision().GetInteger() 
270
  //              << " = " << retval.GetInteger() << std::endl;
238
  return TimeUnit<N1+N2> (retval);
271
  return TimeUnit<N1+N2> (retval);
239
}
272
}
240
template <int N1, int N2>
273
template <int N1, int N2>
 Lines 316-321   public: Link Here 
316
   * - ms (milliseconds)
349
   * - ms (milliseconds)
317
   * - us (microseconds)
350
   * - us (microseconds)
318
   * - ns (nanoseconds)
351
   * - ns (nanoseconds)
352
   * - ps (picoseconds)
353
   * - fs (femtoseconds)
319
   *
354
   *
320
   * There can be no white space between the numerical portion
355
   * There can be no white space between the numerical portion
321
   * and the units.  Any otherwise malformed string causes a fatal error to
356
   * and the units.  Any otherwise malformed string causes a fatal error to
 Lines 332-338   public: Link Here 
332
   * \returns an approximation in milliseconds of the time stored in this
367
   * \returns an approximation in milliseconds of the time stored in this
333
   *          instance.
368
   *          instance.
334
   */
369
   */
335
  int32_t GetMilliSeconds (void) const;
370
  int64_t GetMilliSeconds (void) const;
336
  /**
371
  /**
337
   * \returns an approximation in microseconds of the time stored in this
372
   * \returns an approximation in microseconds of the time stored in this
338
   *          instance.
373
   *          instance.
 Lines 343-348   public: Link Here 
343
   *          instance.
378
   *          instance.
344
   */
379
   */
345
  int64_t GetNanoSeconds (void) const;
380
  int64_t GetNanoSeconds (void) const;
381
  /**
382
   * \returns an approximation in picoseconds of the time stored in this
383
   *          instance.
384
   */
385
  int64_t GetPicoSeconds (void) const;
386
  /**
387
   * \returns an approximation in femtoseconds of the time stored in this
388
   *          instance.
389
   */
390
  int64_t GetFemtoSeconds (void) const;
391
  /**
392
   * \returns an approximation of the time stored in this
393
   *          instance in the units specified in m_tsPrecision.
394
   */
395
  int64_t GetTimeStep (void) const;
346
396
347
  // -*- The rest is the the same as in the generic template class -*-
397
  // -*- The rest is the the same as in the generic template class -*-
348
public:
398
public:
 Lines 378-383   public: Link Here 
378
  HighPrecision *PeekHighPrecision (void) {
428
  HighPrecision *PeekHighPrecision (void) {
379
    return &m_data;
429
    return &m_data;
380
  }
430
  }
431
381
private:
432
private:
382
  HighPrecision m_data;
433
  HighPrecision m_data;
383
};
434
};
 Lines 394-399   private: Link Here 
394
 *  - ns3::MilliSeconds
445
 *  - ns3::MilliSeconds
395
 *  - ns3::MicroSeconds
446
 *  - ns3::MicroSeconds
396
 *  - ns3::NanoSeconds
447
 *  - ns3::NanoSeconds
448
 *  - ns3::PicoSeconds
449
 *  - ns3::FemtoSeconds
397
 *  - ns3::Now
450
 *  - ns3::Now
398
 *
451
 *
399
 * Time instances can be added, substracted, multipled and divided using
452
 * Time instances can be added, substracted, multipled and divided using
 Lines 417-423   private: Link Here 
417
 *          instance.
470
 *          instance.
418
 *
471
 *
419
 * \code
472
 * \code
420
 * int32_t GetMilliSeconds (void) const;
473
 * int64_t GetMilliSeconds (void) const;
421
 * \endcode
474
 * \endcode
422
 * returns an approximation in milliseconds of the time stored in this
475
 * returns an approximation in milliseconds of the time stored in this
423
 *          instance.
476
 *          instance.
 Lines 459-465   Time Seconds (double seconds); Link Here 
459
 * Simulator::Schedule (MilliSeconds (5), ...);
512
 * Simulator::Schedule (MilliSeconds (5), ...);
460
 * \endcode
513
 * \endcode
461
 */
514
 */
462
Time MilliSeconds (uint32_t ms);
515
Time MilliSeconds (uint64_t ms);
463
/**
516
/**
464
 * \brief create ns3::Time instances in units of microseconds.
517
 * \brief create ns3::Time instances in units of microseconds.
465
 *
518
 *
 Lines 480-485   Time MicroSeconds (uint64_t us); Link Here 
480
 * \endcode
533
 * \endcode
481
 */
534
 */
482
Time NanoSeconds (uint64_t ns);
535
Time NanoSeconds (uint64_t ns);
536
/**
537
 * \brief create ns3::Time instances in units of picoseconds.
538
 *
539
 * For example:
540
 * \code
541
 * Time t = PicoSeconds (2);
542
 * Simulator::Schedule (PicoSeconds (5), ...);
543
 * \endcode
544
 */
545
Time PicoSeconds (uint64_t ps);
546
/**
547
 * \brief create ns3::Time instances in units of femtoseconds.
548
 *
549
 * For example:
550
 * \code
551
 * Time t = FemtoSeconds (2);
552
 * Simulator::Schedule (FemtoSeconds (5), ...);
553
 * \endcode
554
 */
555
Time FemtoSeconds (uint64_t fs);
556
/**
557
 * \brief create ns3::Time instances in units of m_tsPrecision.
558
 *
559
 * For example:
560
 * \code
561
 * Time t = TimeStep (2);
562
 * Simulator::Schedule (TimeStep (5), ...);
563
 * \endcode
564
 */
565
Time TimeStep (uint64_t ts);
483
566
484
/**
567
/**
485
 * \brief create an ns3::Time instance which contains the
568
 * \brief create an ns3::Time instance which contains the
 Lines 539-544   public: Link Here 
539
  HighPrecision *PeekHighPrecision (void) {
622
  HighPrecision *PeekHighPrecision (void) {
540
    return &m_data;
623
    return &m_data;
541
  }
624
  }
625
542
private:
626
private:
543
  HighPrecision m_data;
627
  HighPrecision m_data;
544
};
628
};
(-)a/src/simulator/time.cc (-69 / +506 lines)
 Lines 24-29    Link Here 
24
24
25
namespace ns3 {
25
namespace ns3 {
26
26
27
static ts_precision_t
28
GetTsPrecision (void)
29
{
30
  return m_tsPrecision;
31
}
32
33
static void 
34
SetTsPrecision (ts_precision_t tsPrecision)
35
{
36
  m_tsPrecision = tsPrecision;
37
  m_tsPrecisionFactor = (int64_t)pow(10, m_tsPrecision);
38
}
39
27
TimeUnit<1>::TimeUnit(const std::string& s)
40
TimeUnit<1>::TimeUnit(const std::string& s)
28
{
41
{
29
  std::string::size_type n = s.find_first_not_of("0123456789.");
42
  std::string::size_type n = s.find_first_not_of("0123456789.");
 Lines 33-110   TimeUnit<1>::TimeUnit(const std::string& Link Here 
33
    std::string trailer = s.substr(n, std::string::npos);
46
    std::string trailer = s.substr(n, std::string::npos);
34
    if (trailer == std::string("s"))
47
    if (trailer == std::string("s"))
35
    {
48
    {
36
      m_data = HighPrecision (r * 1000000000.0);
49
      m_data = HighPrecision (r * m_tsPrecisionFactor);
37
      return;
50
      return;
38
    }
51
    }
39
    if (trailer == std::string("ms"))
52
    if (trailer == std::string("ms"))
40
    {
53
    {
41
      m_data = HighPrecision ((int64_t)(r * 1000000), false);
54
      m_data = HighPrecision ((int64_t)(r * (m_tsPrecisionFactor/pow(10,3))), 
55
                              false);
42
      return;
56
      return;
43
    }
57
    }
44
    if (trailer == std::string("us"))
58
    if (trailer == std::string("us"))
45
    {
59
    {
46
      m_data = HighPrecision ((int64_t)(r * 1000), false);
60
      m_data = HighPrecision ((int64_t)(r * (m_tsPrecisionFactor/pow(10,6))), 
61
                              false);
47
      return;
62
      return;
48
    }
63
    }
49
    if (trailer == std::string("ns"))
64
    if (trailer == std::string("ns"))
50
    {
65
    {
51
      m_data = HighPrecision ((int64_t)r, false);
66
      m_data = HighPrecision ((int64_t)(r * (m_tsPrecisionFactor/pow(10,9))), 
67
                              false);
68
      return;
69
    }
70
    if (trailer == std::string("ps"))
71
    {
72
      m_data = HighPrecision ((int64_t)(r * (m_tsPrecisionFactor/pow(10,12))), 
73
                              false);
74
      return;
75
    }
76
    if (trailer == std::string("fs"))
77
    {
78
      m_data = HighPrecision ((int64_t)(r * (m_tsPrecisionFactor/pow(10,15))), 
79
                              false);
52
      return;
80
      return;
53
    }
81
    }
54
    NS_FATAL_ERROR("Can't Parse Time "<<s);
82
    NS_FATAL_ERROR("Can't Parse Time "<<s);
55
  }
83
  }
56
  //else
84
  //else
57
  //they didn't provide units, assume seconds
85
  //they didn't provide units, assume seconds
58
  m_data = HighPrecision (atof(s.c_str()) * 1000000000.0);
86
  m_data = HighPrecision (atof(s.c_str()) * m_tsPrecisionFactor);
59
}
87
}
88
60
double 
89
double 
61
TimeUnit<1>::GetSeconds (void) const
90
TimeUnit<1>::GetSeconds (void) const
62
{
91
{
63
  double ns = GetHighPrecision ().GetDouble ();
92
  double time_value = GetHighPrecision ().GetDouble ();
64
  return ns/1000000000.0;
93
  return time_value/m_tsPrecisionFactor;
65
}
94
}
66
int32_t 
95
int64_t 
67
TimeUnit<1>::GetMilliSeconds (void) const
96
TimeUnit<1>::GetMilliSeconds (void) const
68
{
97
{
69
  int64_t ns = GetHighPrecision ().GetInteger ();
98
  int64_t time_value = GetHighPrecision ().GetInteger ();
70
  ns /= 1000000;
99
  time_value = (int64_t)(time_value / (m_tsPrecisionFactor / pow(10,3)));
71
  return ns;
100
  return time_value;
72
}
101
}
73
int64_t 
102
int64_t 
74
TimeUnit<1>::GetMicroSeconds (void) const
103
TimeUnit<1>::GetMicroSeconds (void) const
75
{
104
{
76
  int64_t ns = GetHighPrecision ().GetInteger ();
105
  int64_t time_value = GetHighPrecision ().GetInteger ();
77
  return ns/1000;
106
  time_value = (int64_t)(time_value / (m_tsPrecisionFactor / pow(10,6)));
107
  return time_value;
78
}
108
}
79
int64_t 
109
int64_t 
80
TimeUnit<1>::GetNanoSeconds (void) const
110
TimeUnit<1>::GetNanoSeconds (void) const
81
{
111
{
82
  return GetHighPrecision ().GetInteger ();
112
  int64_t time_value = GetHighPrecision ().GetInteger ();
83
}
113
  time_value = (int64_t)(time_value / (m_tsPrecisionFactor / pow(10,9)));
114
  return time_value;
115
}
116
int64_t 
117
TimeUnit<1>::GetPicoSeconds (void) const
118
{
119
  int64_t time_value = GetHighPrecision ().GetInteger ();
120
  time_value = (int64_t)(time_value / (m_tsPrecisionFactor / pow(10,12)));
121
  return time_value;
122
}
123
int64_t 
124
TimeUnit<1>::GetFemtoSeconds (void) const
125
{
126
  int64_t time_value = GetHighPrecision ().GetInteger ();
127
  time_value = (int64_t)(time_value / (m_tsPrecisionFactor / pow(10,15)));
128
  return time_value;
129
}
130
131
/**
132
 * This returns the value with the precision defined in m_tsPrecision
133
 */
134
int64_t
135
TimeUnit<1>::GetTimeStep (void) const
136
{
137
  int64_t time_value = GetHighPrecision ().GetInteger ();
138
  return time_value;
139
}
140
84
141
85
std::ostream& 
142
std::ostream& 
86
operator<< (std::ostream& os, Time const& time)
143
operator<< (std::ostream& os, Time const& time)
87
{
144
{
88
  os << time.GetNanoSeconds () << "ns";
145
  os << time.GetTimeStep () << "ts";
89
  return os;
146
  return os;
90
}
147
}
91
148
92
Time Seconds (double seconds)
149
Time Seconds (double seconds)
93
{
150
{
94
  return Time (HighPrecision (seconds * 1000000000.0));
151
  double d_sec = seconds * m_tsPrecisionFactor;
95
}
152
  return Time (HighPrecision (d_sec));
96
Time MilliSeconds (uint32_t ms)
153
  //  return Time (HighPrecision ((int64_t)d_sec, false));
97
{
154
}
98
  return Time (HighPrecision (ms * 1000000, false));
155
99
}
156
Time MilliSeconds (uint64_t ms)
157
{
158
  double d_ms = ms * (m_tsPrecisionFactor/pow(10,3));
159
  return Time (HighPrecision ((uint64_t)d_ms, false));
160
}
161
100
Time MicroSeconds (uint64_t us)
162
Time MicroSeconds (uint64_t us)
101
{
163
{
102
  return Time (HighPrecision (us * 1000, false));
164
  double d_us = us * (m_tsPrecisionFactor/pow(10,6));
103
}
165
  return Time (HighPrecision ((uint64_t)d_us, false));
166
}
167
104
Time NanoSeconds (uint64_t ns)
168
Time NanoSeconds (uint64_t ns)
105
{
169
{
106
  return Time (HighPrecision (ns, false));
170
  double d_ns = ns * (m_tsPrecisionFactor/pow(10,9));
107
}
171
  return Time (HighPrecision ((uint64_t)d_ns, false));
172
}
173
Time PicoSeconds (uint64_t ps)
174
{
175
  double d_ps = ps * (m_tsPrecisionFactor/pow(10,12));
176
  return Time (HighPrecision ((uint64_t)d_ps, false));
177
}
178
Time FemtoSeconds (uint64_t fs)
179
{
180
  double d_fs = fs * (m_tsPrecisionFactor/pow(10,15));
181
  return Time (HighPrecision ((uint64_t)d_fs, false));
182
}
183
184
/**
185
 * The timestep value passed to this function must be of the precision of m_tsPrecision
186
 */
187
Time TimeStep (uint64_t ts)
188
{
189
  return Time (HighPrecision (ts, false));
190
}
191
108
Time Now (void)
192
Time Now (void)
109
{
193
{
110
  return Time (Simulator::Now ());
194
  return Time (Simulator::Now ());
 Lines 136-141   public: Link Here 
136
  TimeTests ();
220
  TimeTests ();
137
  virtual ~TimeTests ();
221
  virtual ~TimeTests ();
138
  virtual bool RunTests (void);
222
  virtual bool RunTests (void);
223
224
  /**
225
   * Verifies that a calculated time value is as expected using
226
   * doubles since GetSeconds() returns a double
227
   */ 
228
  void CheckTimeSec(std::string test_id, double actual, double expected, 
229
                    bool *flag, double precMultFactor = 1, 
230
                    bool verbose = false);
231
232
  /**
233
   * Verifies that a calculated time value is as expected.
234
   */ 
235
  void CheckTime(std::string test_id, int64_t actual, int64_t expected, 
236
                 bool *flag, double precMultFactor = 1, 
237
                 bool verbose = false);
238
239
  /**
240
   * Verifies the +, -, * and / operations for the TimeUnit<1> or Time class
241
   */
242
  void CheckOperations(Time t0, Time t1, bool *ok, bool verbose = false);
243
244
  /**
245
   * Verifies that the TimeUnit class stores values with the precision
246
   * set in the variable m_tsPrecision
247
   * Checks that overflow and underflow occur at expected numbers
248
   */
249
  void CheckPrecision(PrecisionType prec, uint64_t val, bool *ok,
250
                      bool verbose = false);
251
252
  /**
253
   * Verifies that the conversion between units in the class
254
   * TimeUnit<1> or Time is done correctly. This is verified both when
255
   * setting and retrieving a Time value
256
   */
257
  void CheckConversions(uint64_t tval, bool *ok, bool verbose = false);
258
259
  /**
260
   * These are the old tests that used to be run
261
   */
262
  void CheckOld(bool *ok);
139
};
263
};
140
264
141
TimeTests::TimeTests ()
265
TimeTests::TimeTests ()
 Lines 143-163   TimeTests::TimeTests () Link Here 
143
{}
267
{}
144
TimeTests::~TimeTests ()
268
TimeTests::~TimeTests ()
145
{}
269
{}
270
146
bool TimeTests::RunTests (void)
271
bool TimeTests::RunTests (void)
147
{
272
{
148
  bool ok = true;
273
  bool ok = true;
149
274
275
  Time t0, t1;
276
277
  CheckOld(&ok);
278
279
  t0 = MilliSeconds ((uint64_t)10.0);
280
  t1 = MilliSeconds ((uint64_t)11.0);
281
282
  CheckOperations(t0, t1, &ok);
283
284
  //  t0 = Seconds ((uint64_t)10.0);
285
  //  t1 = Seconds ((uint64_t)11.0);
286
287
  //  CheckOperations(t0, t1, &ok);
288
289
  CheckConversions((uint64_t)5, &ok);
290
  CheckConversions((uint64_t)0, &ok);
291
  CheckConversions((uint64_t)783, &ok);
292
  CheckConversions((uint64_t)1132, &ok);
293
  CheckConversions((uint64_t)3341039, &ok);
294
295
  // Now vary the precision and check the conversions
296
  if (GetTsPrecision() != NS) {
297
    ok = false;
298
  }
299
300
  CheckPrecision(US, 7, &ok);
301
302
  CheckConversions((uint64_t)7, &ok);
303
  CheckConversions((uint64_t)546, &ok);
304
  CheckConversions((uint64_t)6231, &ok);
305
  CheckConversions((uint64_t)1234639, &ok);
306
307
  CheckPrecision(MS, 3, &ok);
308
309
  CheckConversions((uint64_t)3, &ok);
310
  CheckConversions((uint64_t)134, &ok);
311
  CheckConversions((uint64_t)2341, &ok);
312
  CheckConversions((uint64_t)8956239, &ok);
313
314
  CheckPrecision(PS, 21, &ok);
315
316
  CheckConversions((uint64_t)4, &ok);
317
  CheckConversions((uint64_t)342, &ok);
318
  CheckConversions((uint64_t)1327, &ok);
319
  CheckConversions((uint64_t)5439627, &ok);
320
321
  CheckPrecision(NS, 12, &ok);
322
  CheckConversions((uint64_t)12, &ok);
323
324
  CheckPrecision(SEC, 7, &ok);
325
  CheckConversions((uint64_t)7, &ok);
326
327
  CheckPrecision(FS, 5, &ok);
328
  CheckConversions((uint64_t)5, &ok);
329
330
  return ok;
331
}
332
333
void TimeTests::CheckOld (bool *ok)
334
{
335
  double dt0, dt1, dt2;
336
  int64_t it0, it1;
337
150
  Time t0 = Seconds (10.0);
338
  Time t0 = Seconds (10.0);
151
  //std::cout << "t0="<<t0.GetSeconds ()<<" (expected 10.0)"<<std::endl;
339
  CheckTimeSec("old 1", t0.GetSeconds(), 10.0, ok);
340
152
  Time t1 = Seconds (11.0);
341
  Time t1 = Seconds (11.0);
153
  //std::cout << "t1="<<t1.GetSeconds ()<<" (expected 11.0)"<<std::endl;
342
  CheckTimeSec("old 2", t1.GetSeconds(), 11.0, ok);
343
154
  t0 = Seconds (1.5);
344
  t0 = Seconds (1.5);
155
  //std::cout << "t0="<<t0.GetSeconds ()<<" (expected +1.5)"<<std::endl;
345
  CheckTimeSec("old 3", t0.GetSeconds(), 1.5, ok);
346
156
  t0 = Seconds (-1.5);
347
  t0 = Seconds (-1.5);
157
  //std::cout << "t0="<<t0.GetSeconds ()<<" (expected -1.5)"<<std::endl;
348
  CheckTimeSec("old 4", t0.GetSeconds(), -1.5, ok);
158
349
159
  t0 = Seconds (10.0);
350
  t0 = MilliSeconds ((uint64_t)10.0);
160
  t1 = Seconds (11.0);
351
  dt0 = t0.GetSeconds();
352
  CheckTimeSec("old 5", dt0, 0.01, ok);
353
354
  t1 = MilliSeconds ((uint64_t)11.0);
355
  dt1 = t1.GetSeconds();
356
  CheckTimeSec("old 6", dt1, 0.011, ok);
161
357
162
  Time t2, t3;
358
  Time t2, t3;
163
359
 Lines 166-209   bool TimeTests::RunTests (void) Link Here 
166
    {
362
    {
167
      ok = false;
363
      ok = false;
168
    }
364
    }
365
  dt2 = t2.GetSeconds();
366
  CheckTimeSec("old 7", dt2, dt1-dt0, ok);
367
169
  t2 = t1 - t1;
368
  t2 = t1 - t1;
170
  if (!t2.IsZero ())
369
  if (!t2.IsZero ())
171
    {
370
    {
172
      ok = false;
371
      ok = false;
173
    }
372
    }
373
  dt2 = t2.GetSeconds();
374
  CheckTimeSec("old 8", dt2, dt1-dt1, ok);
375
174
  t2 = t0 - t1;
376
  t2 = t0 - t1;
175
  if (!t2.IsStrictlyNegative ())
377
  if (!t2.IsStrictlyNegative ())
176
    {
378
    {
177
      ok = false;
379
      ok = false;
178
    }
380
    }
179
381
  dt2 = t2.GetSeconds();
180
  t2 = t0 - t1;
382
  CheckTimeSec("old 9", dt2, dt0-dt1, ok);
181
  t3 = t2 * t0 / t1;
383
182
  t3 = t0 * t2 / t1;
384
  t1 = NanoSeconds(15);
183
  t3 = t0 * t1 / t2;
385
  it0 = t0.GetNanoSeconds();
184
  t3 = t0 * (t1 / t2);
386
  it1 = t1.GetNanoSeconds();
185
  t3 = (t0 * t1) / t2;
387
  TimeUnit<-2> tu4 = t0 / (t1 * t1 * t1);
186
  t3 = t0 / t1 * t2;
388
  CheckTime("old 10", tu4.GetHighPrecision().GetInteger(), it0 / (it1*it1*it1), 
187
  t3 = (t0 / t1) * t2;
389
            ok, 1e9);
188
  TimeInvert ti0;
189
  ti0 = t0 / (t1 * t2);
190
  t3 = t0 * Scalar (10.0);
191
  t3 = Scalar (10.0) * t0;
192
  t3 = Scalar (10.0) * t0 / t2 * t1;
193
  t3 = (Scalar (10.0) * t0 ) / t2 * t1;
194
  Scalar s0 = t0 / t1;
195
  Scalar s1;
196
  s1 = t0 * t1 / (t2 * t0);
197
  TimeUnit<0> tu0;
198
  tu0 = s0;
199
  TimeUnit<1> tu1;
200
  tu1 = t0;
201
  TimeUnit<2> tu2;
202
  tu2 = t0 * t1;
203
  TimeUnit<3> tu3;
204
  tu3 = t0 * tu2;
205
  TimeUnit<-2> tu4;
206
  tu4 = t0 / tu3;
207
390
208
  Time tmp = MilliSeconds (0);
391
  Time tmp = MilliSeconds (0);
209
  if ((tmp != NanoSeconds (0)) ||
392
  if ((tmp != NanoSeconds (0)) ||
 Lines 215-233   bool TimeTests::RunTests (void) Link Here 
215
398
216
  Time t4;
399
  Time t4;
217
  t4 = Seconds (10.0) * Scalar (1.5);
400
  t4 = Seconds (10.0) * Scalar (1.5);
218
  //std::cout << "10.0s * 1.5 = " << t4.GetSeconds () << "s" << std::endl;
401
  CheckTimeSec("old 11", t4.GetSeconds(), 10, ok);
402
219
  Time t5;
403
  Time t5;
220
  t5 = NanoSeconds (10) * Scalar (1.5);
404
  t5 = NanoSeconds (10) * Scalar (1.5);
221
  //std::cout << "10ns * 1.5 = " << t5.GetNanoSeconds () << "ns" <<
405
  CheckTime("old 12", t5.GetNanoSeconds(), 10, ok);
222
  //std::endl;
406
407
  t4 = Seconds (10.0) * Scalar (15) / Scalar (10);
408
  CheckTimeSec("old 13", t4.GetSeconds(), 15, ok);
409
410
  t5 = NanoSeconds (10) * Scalar (15) / Scalar (10);
411
  CheckTime("old 14", t5.GetNanoSeconds(), 15, ok);
412
223
413
224
  double foo = (t1 + t2).GetSeconds ();
414
  double foo = (t1 + t2).GetSeconds ();
415
  dt1 = t1.GetSeconds();
416
  dt2 = t2.GetSeconds();
417
  CheckTimeSec("old 15", foo, dt1+dt2, ok);
418
225
  foo += (t4 == t5)? 1 : 0;
419
  foo += (t4 == t5)? 1 : 0;
420
  CheckTimeSec("old 16", foo, dt1+dt2, ok);
226
421
227
  foo = (t1/t2).GetDouble ();
422
  foo = (t1/t2).GetDouble ();
228
423
  CheckTimeSec("old 17", foo, dt1/dt2, ok);
229
  return ok;
424
}
230
}
425
426
427
void TimeTests::CheckOperations(Time t0, Time t1, bool *ok, bool verbose) 
428
{
429
430
  if (verbose) 
431
    std::cout << std::endl << "Check operations: " 
432
              << t0 << " " << t1 << std::endl;
433
434
  Time t2, t3;
435
  double it0, it1, it2, it3, itu2, itu3;
436
  int64_t iti0;
437
438
  it0 = t0.GetSeconds();
439
  it1 = t1.GetSeconds();
440
441
  t2 = t0 - t1;
442
  it2 = t2.GetSeconds();
443
  CheckTimeSec("ops 1", it2, it0-it1, ok);
444
445
  t3 = t2 * t0 / t0;
446
  it3 = t3.GetSeconds();
447
  CheckTimeSec("ops 2a", it3, it2*it0/it0, ok);
448
449
  t3 = t2 * t0 / t1;
450
  it3 = t3.GetSeconds();
451
  CheckTimeSec("ops 2", it3, it2*it0/it1, ok);
452
453
  t3 = t0 * t2 / t1;
454
  it3 = t3.GetSeconds();
455
  CheckTimeSec("ops 3", it3, it0*it2/it1, ok);
456
457
  t3 = t0 * t1 / t2;
458
  it3 = t3.GetSeconds();
459
  CheckTimeSec("ops 4", it3, it0*it1/it2, ok);
460
461
  t3 = t0 * (t1 / t2);
462
  it3 = t3.GetSeconds();
463
  CheckTimeSec("ops 5", it3, it0*(it1/it2), ok);
464
465
  t3 = (t0 * t1) / t2;
466
  it3 = t3.GetSeconds();
467
  CheckTimeSec("ops 6", it3, (it0*it1)/it2, ok);
468
469
  t3 = t0 / t1 * t2;
470
  it3 = t3.GetSeconds();
471
  CheckTimeSec("ops 7", it3, it0/it1*it2, ok);
472
473
  t3 = (t0 / t1) * t2;
474
  it3 = t3.GetSeconds();
475
  CheckTimeSec("ops 8", it3, (it0/it1)*it2, ok);
476
477
  t3 = t0 * Scalar (10.0);
478
  it3 = t3.GetSeconds();
479
  CheckTimeSec("ops 9", it3, it0*10, ok);
480
481
  t3 = Scalar (10.0) * t0;
482
  it3 = t3.GetSeconds();
483
  CheckTimeSec("ops 10", it3, 10 * it0, ok);
484
485
  t3 = Scalar (10.0) * t0 / t2 * t1;
486
  it3 = t3.GetSeconds();
487
  CheckTimeSec("ops 11", it3, 10 * it0 / it2 * it1, ok);
488
489
  t3 = (Scalar (10.0) * t0 ) / t2 * t1;
490
  it3 = t3.GetSeconds();
491
  CheckTimeSec("ops 12", it3, (10 * it0) / it2 * it1, ok);
492
493
  TimeInvert ti0;
494
  ti0 = t0 / (t1 * t2);
495
  iti0 = ti0.GetHighPrecision().GetInteger();
496
  // This check is not quite working yet.
497
  //  CheckTime("ops 13", iti0, (int64_t)(it0/(it1*it2)), ok);
498
499
  Scalar s0 = t0 / t1;
500
  CheckTimeSec("ops 14", s0.GetDouble(), it0/it1, ok);
501
502
  Scalar s1;
503
  s1 = t0 * t1 / (t2 * t0);
504
  CheckTimeSec("ops 15", s1.GetDouble(), it0*it1/(it2*it0), ok);
505
506
  TimeUnit<0> tu0;
507
  tu0 = s0;
508
  CheckTimeSec("ops 16", tu0.GetDouble(), s0.GetDouble(), ok);
509
510
  TimeUnit<1> tu1;
511
  tu1 = t0;
512
  CheckTimeSec("ops 17", tu1.GetSeconds(), it0, ok);
513
514
  TimeUnit<2> tu2;
515
  tu2 = t0 * t1;
516
  CheckTimeSec("ops 18", tu2.GetHighPrecision().GetInteger()/(1e18), 
517
               it0 * it1, ok);
518
  itu2 = tu2.GetHighPrecision().GetInteger()/(1e18);
519
  
520
  TimeUnit<3> tu3;
521
  tu3 = t0 / Scalar(10e6) * tu2;
522
  CheckTimeSec("ops 19", tu3.GetHighPrecision().GetInteger()/(1e27), 
523
               it0 / 1000000 * itu2, ok);
524
  itu3 = tu3.GetHighPrecision().GetInteger()/(1e27);
525
}
526
527
void TimeTests::CheckConversions(uint64_t tval, bool *ok, bool verbose) {
528
  Time t_sec, t_ms, t_us, t_ns, t_ps, t_fs;
529
530
  if (verbose) 
531
    std::cout << std::endl << "Check conversions: " << tval << std::endl;
532
533
  // First check the seconds
534
  t_sec = Seconds((double)tval);
535
  CheckTimeSec("conv sec sec", t_sec.GetSeconds(), (double)tval, ok);
536
  CheckTime("conv sec ms", t_sec.GetMilliSeconds(), (int64_t)(tval*1e3), ok, 1e3);
537
  CheckTime("conv sec us", t_sec.GetMicroSeconds(), (int64_t)(tval*1e6), ok, 1e6);
538
  CheckTime("conv sec ns", t_sec.GetNanoSeconds(), (int64_t)(tval*1e9), ok, 1e9);
539
  CheckTime("conv sec ps", t_sec.GetPicoSeconds(), 
540
            (int64_t)(tval*1e12), ok, 1e12);
541
  CheckTime("conv sec fs", t_sec.GetFemtoSeconds(), 
542
            (int64_t)(tval*1e15), ok, 1e15);
543
544
  // Then check the milliseconds
545
  t_ms = MilliSeconds(tval);
546
  CheckTimeSec("conv ms sec", t_ms.GetSeconds(), (double)tval/1e3, ok);
547
  CheckTime("conv ms ms", t_ms.GetMilliSeconds(), (int64_t)(tval), ok, 1e3);
548
  CheckTime("conv ms us", t_ms.GetMicroSeconds(), (int64_t)(tval*1e3), ok, 1e6);
549
  CheckTime("conv ms ns", t_ms.GetNanoSeconds(), (int64_t)(tval*1e6), ok, 1e9);
550
  CheckTime("conv ms ps", t_ms.GetPicoSeconds(), (int64_t)(tval*1e9), ok, 1e12);
551
  CheckTime("conv ms fs", t_ms.GetFemtoSeconds(), (int64_t)(tval*1e12), ok, 1e15);
552
553
  // Then check the microseconds
554
  t_us = MicroSeconds(tval);
555
  CheckTimeSec("conv us sec", t_us.GetSeconds(), (double)tval/1e6, ok);
556
  CheckTime("conv us ms", t_us.GetMilliSeconds(), (int64_t)(tval/1e3), ok, 1e3);
557
  CheckTime("conv us us", t_us.GetMicroSeconds(), (int64_t)(tval), ok, 1e6);
558
  CheckTime("conv us ns", t_us.GetNanoSeconds(), (int64_t)(tval*1e3), ok, 1e9);
559
  CheckTime("conv us ps", t_us.GetPicoSeconds(), (int64_t)(tval*1e6), ok, 1e12);
560
  CheckTime("conv us fs", t_us.GetFemtoSeconds(), (int64_t)(tval*1e9), ok, 1e15);
561
  
562
  // Then check the nanoseconds
563
  t_ns = NanoSeconds(tval);
564
  CheckTimeSec("conv ns sec", t_ns.GetSeconds(), (double)tval/1e9, ok);
565
  CheckTime("conv ns ms", t_ns.GetMilliSeconds(), (int64_t)(tval/1e6), ok, 1e3);
566
  CheckTime("conv ns us", t_ns.GetMicroSeconds(), (int64_t)(tval/1e3), ok, 1e6);
567
  CheckTime("conv ns ns", t_ns.GetNanoSeconds(), (int64_t)(tval), ok, 1e9);
568
  CheckTime("conv ns ps", t_ns.GetPicoSeconds(), (int64_t)(tval*1e3), ok, 1e12);
569
  CheckTime("conv ns fs", t_ns.GetFemtoSeconds(), (int64_t)(tval*1e6), ok, 1e15);
570
  
571
  // Then check the picoseconds
572
  t_ps = PicoSeconds(tval);
573
  CheckTimeSec("conv ps sec", t_ps.GetSeconds(), (double)tval/1e12, ok);
574
  CheckTime("conv ps ms", t_ps.GetMilliSeconds(), (int64_t)(tval/1e9), ok, 1e3);
575
  CheckTime("conv ps us", t_ps.GetMicroSeconds(), (int64_t)(tval/1e6), ok, 1e6);
576
  CheckTime("conv ps ns", t_ps.GetNanoSeconds(), (int64_t)(tval/1e3), ok, 1e9);
577
  CheckTime("conv ps ps", t_ps.GetPicoSeconds(), (int64_t)(tval), ok, 1e12);
578
  CheckTime("conv ps fs", t_ps.GetFemtoSeconds(), (int64_t)(tval*1e3), ok, 1e15);
579
  
580
  // Then check the femtoseconds
581
  t_fs = FemtoSeconds(tval);
582
  CheckTimeSec("conv fs sec", t_fs.GetSeconds(), (double)tval/1e15, ok);
583
  CheckTime("conv fs ms", t_fs.GetMilliSeconds(), (int64_t)(tval/1e12), ok, 1e3);
584
  CheckTime("conv fs us", t_fs.GetMicroSeconds(), (int64_t)(tval/1e9), ok, 1e6);
585
  CheckTime("conv fs ns", t_fs.GetNanoSeconds(), (int64_t)(tval/1e6), ok, 1e9);
586
  CheckTime("conv fs ps", t_fs.GetPicoSeconds(), (int64_t)(tval/1e3), ok, 1e12);
587
  CheckTime("conv fs fs", t_fs.GetFemtoSeconds(), (int64_t)(tval), ok, 1e15);
588
589
  
590
}
591
592
void TimeTests::CheckPrecision(PrecisionType prec, uint64_t val, bool *ok, 
593
                               bool verbose) {
594
  if (verbose) {
595
    std::cout << "check precision 10^-" << prec << std::endl;
596
  }
597
598
  SetTsPrecision(prec);
599
  if (GetTsPrecision() != prec) {
600
    ok = false;
601
  }
602
603
  /* These still need to be fixed.
604
  // The smallest value that can be stored is 1x10^(-prec)
605
  Time smallest = Seconds(pow(10,-prec));
606
  CheckTimeSec("Prec small:     ", smallest.GetSeconds(), pow(10,-prec), ok, 0.1, 
607
               true);
608
  
609
  double d_ts = pow(10,-prec) - pow(10, -(prec+3));
610
  Time too_small = Seconds(d_ts);
611
  CheckTimeSec("Prec too small: ", too_small.GetSeconds(), 0, ok, 0.1, true);
612
613
  double d_la = 0xFFFFFFFF*pow(10,-prec);
614
  Time largest = Seconds(d_la);
615
  CheckTimeSec("Prec large:     ", largest.GetSeconds(), d_la, ok, 0.1, true);
616
617
  double d_tl = (0xFFFFFFFF*pow(10,-prec)) + 1;
618
  Time too_large = Seconds(d_tl);
619
  if ((largest.GetSeconds() + 1) == too_large.GetSeconds())
620
    std::cout << "Overflow did not occur." << std::endl;
621
622
  NS_ASSERT(d_la+1 == d_tl);
623
  */  
624
}
625
626
void TimeTests::CheckTimeSec (std::string test_id, double actual, 
627
                              double expected, bool *flag, double precMultFactor,
628
                              bool verbose)
629
{
630
  double prec = pow(10,-ns3::m_tsPrecision) * precMultFactor;
631
  if ((actual < (expected-prec)) || (actual > (expected+prec))) {
632
    std::cout << "FAIL " << test_id 
633
              << " Expected:" << expected 
634
              << " Actual: " << actual
635
              << " Precision: " << prec << std::endl;
636
    *flag = false;
637
  } else {
638
    if (verbose) {
639
      std::cout << "PASS " << test_id 
640
                << " Expected:" << expected 
641
                << " Actual: " << actual
642
                << " Precision: " << prec << std::endl;
643
    }
644
  }
645
}
646
647
void TimeTests::CheckTime (std::string test_id, int64_t actual, 
648
                           int64_t expected, bool *flag, double precMultFactor,
649
                           bool verbose)
650
{
651
  double prec = pow(10,-ns3::m_tsPrecision) * precMultFactor;
652
  if ((actual < (expected-prec)) || (actual > (expected+prec))) {
653
    std::cout << "FAIL " << test_id 
654
              << " Expected:" << expected 
655
              << " Actual: " << actual
656
              << " Precision: " << prec << std::endl;
657
    *flag = false;
658
  } else {
659
    if (verbose) {
660
      std::cout << "PASS " << test_id 
661
                << " Expected:" << expected 
662
                << " Actual: " << actual 
663
                << " Precision: " << prec << std::endl;
664
    }
665
  }
666
}
667
231
668
232
static TimeTests g_time_tests;
669
static TimeTests g_time_tests;
233
  
670
  

Return to bug 21