A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
nstime.h
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2005,2006 INRIA
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
19  */
20 #ifndef TIME_H
21 #define TIME_H
22 
23 #include "assert.h"
24 #include "attribute.h"
25 #include "attribute-helper.h"
26 #include "int64x64.h"
27 #include "unused.h"
28 #include <stdint.h>
29 #include <limits>
30 #include <cmath>
31 #include <ostream>
32 #include <set>
33 
34 namespace ns3 {
35 
103 class Time
104 {
105 public:
109  enum Unit
110  {
111  S = 0,
112  MS = 1,
113  US = 2,
114  NS = 3,
115  PS = 4,
116  FS = 5,
117  LAST = 6
118  };
119 
120  inline Time &operator = (const Time &o)
121  {
122  m_data = o.m_data;
123  return *this;
124  }
125  inline Time ()
126  : m_data ()
127  {
128  if (g_markingTimes)
129  {
130  Mark (this);
131  }
132  }
133  inline Time(const Time &o)
134  : m_data (o.m_data)
135  {
136  if (g_markingTimes)
137  {
138  Mark (this);
139  }
140  }
141  explicit inline Time (double v)
142  : m_data (lround (v))
143  {
144  if (g_markingTimes)
145  {
146  Mark (this);
147  }
148  }
149  explicit inline Time (int v)
150  : m_data (v)
151  {
152  if (g_markingTimes)
153  {
154  Mark (this);
155  }
156  }
157  explicit inline Time (long int v)
158  : m_data (v)
159  {
160  if (g_markingTimes)
161  {
162  Mark (this);
163  }
164  }
165  explicit inline Time (long long int v)
166  : m_data (v)
167  {
168  if (g_markingTimes)
169  {
170  Mark (this);
171  }
172  }
173  explicit inline Time (unsigned int v)
174  : m_data (v)
175  {
176  if (g_markingTimes)
177  {
178  Mark (this);
179  }
180  }
181  explicit inline Time (unsigned long int v)
182  : m_data (v)
183  {
184  if (g_markingTimes)
185  {
186  Mark (this);
187  }
188  }
189  explicit inline Time (unsigned long long int v)
190  : m_data (v)
191  {
192  if (g_markingTimes)
193  {
194  Mark (this);
195  }
196  }
213  explicit Time (const std::string & s);
214 
218  static Time Min ()
219  {
220  return Time (std::numeric_limits<int64_t>::min ());
221  }
225  static Time Max ()
226  {
227  return Time (std::numeric_limits<int64_t>::max ());
228  }
229 
233  ~Time ()
234  {
235  if (g_markingTimes)
236  {
237  Clear (this);
238  }
239  }
240 
244  inline bool IsZero (void) const
245  {
246  return m_data == 0;
247  }
251  inline bool IsNegative (void) const
252  {
253  return m_data <= 0;
254  }
258  inline bool IsPositive (void) const
259  {
260  return m_data >= 0;
261  }
265  inline bool IsStrictlyNegative (void) const
266  {
267  return m_data < 0;
268  }
272  inline bool IsStrictlyPositive (void) const
273  {
274  return m_data > 0;
275  }
279  inline int Compare (const Time &o) const
280  {
281  return (m_data < o.m_data) ? -1 : (m_data == o.m_data) ? 0 : 1;
282  }
283 
288  inline double GetSeconds (void) const
289  {
290  return ToDouble (Time::S);
291  }
292 
297  inline int64_t GetMilliSeconds (void) const
298  {
299  return ToInteger (Time::MS);
300  }
305  inline int64_t GetMicroSeconds (void) const
306  {
307  return ToInteger (Time::US);
308  }
313  inline int64_t GetNanoSeconds (void) const
314  {
315  return ToInteger (Time::NS);
316  }
321  inline int64_t GetPicoSeconds (void) const
322  {
323  return ToInteger (Time::PS);
324  }
329  inline int64_t GetFemtoSeconds (void) const
330  {
331  return ToInteger (Time::FS);
332  }
336  inline int64_t GetTimeStep (void) const
337  {
338  return m_data;
339  }
340  inline double GetDouble (void) const
341  {
342  return m_data;
343  }
344  inline int64_t GetInteger (void) const
345  {
346  return GetTimeStep ();
347  }
348 
349 
357  static void SetResolution (enum Unit resolution);
361  static enum Unit GetResolution (void);
372  inline static Time FromInteger (uint64_t value, enum Unit timeUnit)
373  {
374  struct Information *info = PeekInformation (timeUnit);
375  if (info->fromMul)
376  {
377  value *= info->factor;
378  }
379  else
380  {
381  value /= info->factor;
382  }
383  return Time (value);
384  }
392  inline int64_t ToInteger (enum Unit timeUnit) const
393  {
394  struct Information *info = PeekInformation (timeUnit);
395  int64_t v = m_data;
396  if (info->toMul)
397  {
398  v *= info->factor;
399  }
400  else
401  {
402  v /= info->factor;
403  }
404  return v;
405  }
413  inline static Time FromDouble (double value, enum Unit timeUnit)
414  {
415  return From (int64x64_t (value), timeUnit);
416  }
424  inline double ToDouble (enum Unit timeUnit) const
425  {
426  return To (timeUnit).GetDouble ();
427  }
428  static inline Time From (const int64x64_t &from, enum Unit timeUnit)
429  {
430  struct Information *info = PeekInformation (timeUnit);
431  // DO NOT REMOVE this temporary variable. It's here
432  // to work around a compiler bug in gcc 3.4
433  int64x64_t retval = from;
434  if (info->fromMul)
435  {
436  retval *= info->timeFrom;
437  }
438  else
439  {
440  retval.MulByInvert (info->timeFrom);
441  }
442  return Time (retval);
443  }
444  inline int64x64_t To (enum Unit timeUnit) const
445  {
446  struct Information *info = PeekInformation (timeUnit);
447  int64x64_t retval = int64x64_t (m_data);
448  if (info->toMul)
449  {
450  retval *= info->timeTo;
451  }
452  else
453  {
454  retval.MulByInvert (info->timeTo);
455  }
456  return retval;
457  }
458  inline operator int64x64_t () const
459  {
460  return int64x64_t (m_data);
461  }
462  explicit inline Time (const int64x64_t &value)
463  : m_data (value.GetHigh ())
464  {
465  if (g_markingTimes)
466  {
467  Mark (this);
468  }
469  }
470  inline static Time From (const int64x64_t &value)
471  {
472  return Time (value);
473  }
474 
475 private:
479  struct Information
480  {
481  bool toMul;
482  bool fromMul;
483  int64_t factor;
484  int64x64_t timeTo;
485  int64x64_t timeFrom;
486  };
490  struct Resolution
491  {
494  };
495 
496  static inline struct Resolution *PeekResolution (void)
497  {
498  static struct Time::Resolution resolution = SetDefaultNsResolution ();
499  return &resolution;
500  }
501  static inline struct Information *PeekInformation (enum Unit timeUnit)
502  {
503  return &(PeekResolution ()->info[timeUnit]);
504  }
505 
506  static struct Resolution SetDefaultNsResolution (void);
507  static void SetResolution (enum Unit unit, struct Resolution *resolution,
508  const bool convert = true);
509 
529  typedef std::set< Time * > MarkedTimes;
545 public:
549  static bool StaticInit ();
550 private:
551 
552  /* Friend the Simulator class so it can call the private function
553  ClearMarkedTimes ()
554  */
555  friend class Simulator;
562  static void ClearMarkedTimes ();
566  static void Mark (Time * const time);
570  static void Clear (Time * const time);
574  static void ConvertTimes (const enum Unit unit);
575 
576  friend bool operator == (const Time &lhs, const Time &rhs);
577  friend bool operator != (const Time &lhs, const Time &rhs);
578  friend bool operator <= (const Time &lhs, const Time &rhs);
579  friend bool operator >= (const Time &lhs, const Time &rhs);
580  friend bool operator < (const Time &lhs, const Time &rhs);
581  friend bool operator > (const Time &lhs, const Time &rhs);
582  friend Time operator + (const Time &lhs, const Time &rhs);
583  friend Time operator - (const Time &lhs, const Time &rhs);
584  friend Time &operator += (Time &lhs, const Time &rhs);
585  friend Time &operator -= (Time &lhs, const Time &rhs);
586  friend Time Abs (const Time &time);
587  friend Time Max (const Time &ta, const Time &tb);
588  friend Time Min (const Time &ta, const Time &tb);
589 
590 
591  int64_t m_data;
592 
593 }; // class Time
594 
595 
596 // Force static initialization of Time
597 static bool NS_UNUSED_GLOBAL (g_TimeStaticInit) = Time::StaticInit ();
598 
599 inline bool
600 operator == (const Time &lhs, const Time &rhs)
601 {
602  return lhs.m_data == rhs.m_data;
603 }
604 inline bool
605 operator != (const Time &lhs, const Time &rhs)
606 {
607  return lhs.m_data != rhs.m_data;
608 }
609 inline bool
610 operator <= (const Time &lhs, const Time &rhs)
611 {
612  return lhs.m_data <= rhs.m_data;
613 }
614 inline bool
615 operator >= (const Time &lhs, const Time &rhs)
616 {
617  return lhs.m_data >= rhs.m_data;
618 }
619 inline bool
620 operator < (const Time &lhs, const Time &rhs)
621 {
622  return lhs.m_data < rhs.m_data;
623 }
624 inline bool
625 operator > (const Time &lhs, const Time &rhs)
626 {
627  return lhs.m_data > rhs.m_data;
628 }
629 inline Time operator + (const Time &lhs, const Time &rhs)
630 {
631  return Time (lhs.m_data + rhs.m_data);
632 }
633 inline Time operator - (const Time &lhs, const Time &rhs)
634 {
635  return Time (lhs.m_data - rhs.m_data);
636 }
637 inline Time &operator += (Time &lhs, const Time &rhs)
638 {
639  lhs.m_data += rhs.m_data;
640  return lhs;
641 }
642 inline Time &operator -= (Time &lhs, const Time &rhs)
643 {
644  lhs.m_data -= rhs.m_data;
645  return lhs;
646 }
647 
655 inline Time Abs (const Time &time)
656 {
657  return Time ((time.m_data < 0) ? -time.m_data : time.m_data);
658 }
666 inline Time Max (const Time &ta, const Time &tb)
667 {
668  return Time ((ta.m_data < tb.m_data) ? tb : ta);
669 }
675 inline Time Min (const Time &ta, const Time &tb)
676 {
677  return Time ((ta.m_data > tb.m_data) ? tb : ta);
678 }
679 
680 
687 std::ostream& operator<< (std::ostream& os, const Time & time);
694 std::istream& operator>> (std::istream& is, Time & time);
695 
707 inline Time Seconds (double seconds)
708 {
709  return Time::FromDouble (seconds, Time::S);
710 }
711 
723 inline Time MilliSeconds (uint64_t ms)
724 {
725  return Time::FromInteger (ms, Time::MS);
726 }
738 inline Time MicroSeconds (uint64_t us)
739 {
740  return Time::FromInteger (us, Time::US);
741 }
753 inline Time NanoSeconds (uint64_t ns)
754 {
755  return Time::FromInteger (ns, Time::NS);
756 }
768 inline Time PicoSeconds (uint64_t ps)
769 {
770  return Time::FromInteger (ps, Time::PS);
771 }
783 inline Time FemtoSeconds (uint64_t fs)
784 {
785  return Time::FromInteger (fs, Time::FS);
786 }
787 
788 
793 inline Time Seconds (int64x64_t seconds)
794 {
795  return Time::From (seconds, Time::S);
796 }
801 inline Time MilliSeconds (int64x64_t ms)
802 {
803  return Time::From (ms, Time::MS);
804 }
809 inline Time MicroSeconds (int64x64_t us)
810 {
811  return Time::From (us, Time::US);
812 }
817 inline Time NanoSeconds (int64x64_t ns)
818 {
819  return Time::From (ns, Time::NS);
820 }
825 inline Time PicoSeconds (int64x64_t ps)
826 {
827  return Time::From (ps, Time::PS);
828 }
833 inline Time FemtoSeconds (int64x64_t fs)
834 {
835  return Time::From (fs, Time::FS);
836 }
837 
838 // internal function not publicly documented
839 inline Time TimeStep (uint64_t ts)
840 {
841  return Time (ts);
842 }
843 
852 
860 
866 inline
868 {
869  return MakeTimeChecker (Time::Min (), Time::Max ());
870 }
871 
877 inline
879 {
880  return MakeTimeChecker (min, Time::Max ());
881 }
882 
883 
884 } // namespace ns3
885 
886 #endif /* TIME_H */