Click
Loading...
Searching...
No Matches
timestamp.hh
Go to the documentation of this file.
1// -*- c-basic-offset: 4; related-file-name: "../../lib/timestamp.cc" -*-
2#ifndef CLICK_TIMESTAMP_HH
3#define CLICK_TIMESTAMP_HH
4#include <click/glue.hh>
6#include <click/integers.hh>
7#if !CLICK_LINUXMODULE && !CLICK_BSDMODULE
8# include <math.h>
9#endif
10CLICK_DECLS
11class String;
12class Timestamp;
14
15// Timestamp has three possible internal representations, selected by #defines.
16// * TIMESTAMP_REP_FLAT64: a 64-bit integer number of nanoseconds
17// * TIMESTAMP_REP_BIG_ENDIAN: 32 bits of seconds plus 32 bits of subseconds
18// * TIMESTAMP_REP_LITTLE_ENDIAN: 32 bits of subseconds plus 32 bits of seconds
19//
20// Rationale: The linuxmodule driver must select the same representation as
21// Linux's sk_buff tstamp member, which may use any of these representations.
22// (Linuxmodule Packet objects are equivalent to sk_buffs, and
23// Packet::timestamp_anno() maps to sk_buff::tstamp. We want to avoid
24// conversion expense when accessing timestamp_anno(). More seriously, it is
25// very convenient to treat timestamp_anno() as a modifiable reference.)
26
27#if !TIMESTAMP_REP_FLAT64 && !TIMESTAMP_REP_BIG_ENDIAN && !TIMESTAMP_REP_LITTLE_ENDIAN
28# if CLICK_LINUXMODULE
29# if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24)
30# define TIMESTAMP_REP_BIG_ENDIAN 1
31# elif BITS_PER_LONG == 64 || defined(CONFIG_KTIME_SCALAR)
32# define TIMESTAMP_REP_FLAT64 1
33# elif defined(__BIG_ENDIAN)
34# define TIMESTAMP_REP_BIG_ENDIAN 1
35# else
36# define TIMESTAMP_REP_LITTLE_ENDIAN 1
37# endif
38# elif HAVE_INT64_TYPES && SIZEOF_LONG == 8
39# define TIMESTAMP_REP_FLAT64 1
40# elif HAVE_INT64_TYPES && CLICK_BYTE_ORDER == CLICK_LITTLE_ENDIAN
41# define TIMESTAMP_REP_LITTLE_ENDIAN 1
42# else
43# define TIMESTAMP_REP_BIG_ENDIAN 1
44# endif
45#endif
46
47
48// Timestamp can use microsecond or nanosecond precision. Nanosecond
49// precision is used if TIMESTAMP_NANOSEC == 1. In the Linux kernel, we
50// choose what Linux uses for sk_buff::tstamp. Elsewhere, we default to
51// microsecond precision (XXX); "./configure --enable-nanotimestamp" selects
52// nanosecond precision.
53
54#ifndef TIMESTAMP_NANOSEC
55# if CLICK_LINUXMODULE
56# if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
57# define TIMESTAMP_NANOSEC 1
58# endif
59# endif
60#endif
61
62
63// Define TIMESTAMP_MATH_FLAT64 if despite a seconds-and-subseconds
64// representation, 64-bit arithmetic should be used for timestamp addition,
65// subtraction, and comparisons. This can be faster than operating on two
66// separate 32-bit integers.
67
68#if HAVE_INT64_TYPES && !TIMESTAMP_REP_FLAT64
69# if (TIMESTAMP_REP_BIG_ENDIAN && CLICK_BYTE_ORDER == CLICK_BIG_ENDIAN) \
70 || (TIMESTAMP_REP_LITTLE_ENDIAN && CLICK_BYTE_ORDER == CLICK_LITTLE_ENDIAN)
71# define TIMESTAMP_MATH_FLAT64 1
72# endif
73#endif
74
75
76// If a Timestamp's internal representation is identical to struct timespec
77// or struct timeval, define TIMESTAMP_PUNS_TIMESPEC or TIMESTAMP_PUNS_TIMEVAL.
78
79#if TIMESTAMP_REP_BIG_ENDIAN
80# if !TIMESTAMP_NANOSEC && SIZEOF_STRUCT_TIMEVAL == 8
81# define TIMESTAMP_PUNS_TIMEVAL 1
82# elif TIMESTAMP_NANOSEC && HAVE_STRUCT_TIMESPEC && SIZEOF_STRUCT_TIMESPEC == 8
83# define TIMESTAMP_PUNS_TIMESPEC 1
84# endif
85#endif
86
87
88// Timestamp::value_type is the type of arguments to, for example,
89// Timestamp::make_msec(), and should be as large as possible. This is
90// int64_t at userlevel. In the linuxmodule driver, int64_t can only be used
91// if the relevant Linux provides 64-bit divide, which is do_div.
92// TIMESTAMP_VALUE_INT64 is defined to 1 if Timestamp::value_type is int64_t.
93
94#if !defined(TIMESTAMP_VALUE_INT64) && HAVE_INT64_TYPES
95# if CLICK_LINUXMODULE && defined(do_div)
96# define TIMESTAMP_VALUE_INT64 1
97# elif !CLICK_LINUXMODULE && !CLICK_BSDMODULE
98# define TIMESTAMP_VALUE_INT64 1
99# endif
100#endif
101
102
103// PRITIMESTAMP is a printf format string for Timestamps. The corresponding
104// printf argument list is Timestamp::sec() and Timestamp::subsec(), in that
105// order.
106
107#if TIMESTAMP_NANOSEC
108# define PRITIMESTAMP "%d.%09d"
109#else
110# define PRITIMESTAMP "%d.%06d"
111#endif
112
113
114// TIMESTAMP_WARPABLE is defined if this Timestamp implementation supports
115// timewarping.
116
117#if !CLICK_LINUXMODULE && !CLICK_BSDMODULE && !CLICK_NS && HAVE_SIMTIME
118# define TIMESTAMP_WARPABLE 1
119#endif
120
121#if HAVE_USER_TIMING
122typedef int64_t (*user_clock_fct)(void* user, bool steady);
123#endif
124
125class Timestamp { public:
126
128 typedef int32_t seconds_type;
130#if TIMESTAMP_VALUE_INT64
131 typedef int64_t value_type;
132#else
133 typedef int32_t value_type;
134#endif
135
136 enum {
137 max_seconds = (seconds_type) 2147483647U,
140 min_seconds = (seconds_type) -2147483648U
143 };
144
145 enum {
146 nsec_per_sec = 1000000000,
147 nsec_per_msec = 1000000,
148 nsec_per_usec = 1000,
149 usec_per_sec = 1000000,
150 usec_per_msec = 1000,
151 msec_per_sec = 1000,
152#if TIMESTAMP_NANOSEC
153 subsec_per_sec = nsec_per_sec,
157#else
158 subsec_per_sec = usec_per_sec,
159#endif
160 subsec_per_msec = subsec_per_sec / msec_per_sec,
161 subsec_per_usec = subsec_per_sec / usec_per_sec
162#if CLICK_NS
163 , schedule_granularity = usec_per_sec
164#endif
165 };
166
167 enum {
168 NSUBSEC = subsec_per_sec
169 };
170
171 typedef uninitialized_type uninitialized_t;
172
173 union rep_t;
174
175
177 inline Timestamp() {
178 assign(0, 0);
179 }
180
190 explicit inline Timestamp(long sec, uint32_t subsec = 0) {
191 assign(sec, subsec);
192 }
194 explicit inline Timestamp(int sec, uint32_t subsec = 0) {
195 assign(sec, subsec);
196 }
198 explicit inline Timestamp(unsigned long sec, uint32_t subsec = 0) {
199 assign(sec, subsec);
200 }
202 explicit inline Timestamp(unsigned sec, uint32_t subsec = 0) {
203 assign(sec, subsec);
204 }
205#if HAVE_FLOAT_TYPES
206 explicit inline Timestamp(double);
207#endif
208
209 inline Timestamp(const struct timeval &tv);
210#if HAVE_STRUCT_TIMESPEC
211 inline Timestamp(const struct timespec &ts);
212#endif
213
215 inline Timestamp(const rep_t &rep)
216 : _t(rep) {
217 }
218
220 inline Timestamp(const uninitialized_t &unused) {
221 (void) unused;
222 }
223
224 typedef seconds_type (Timestamp::*unspecified_bool_type)() const;
225 inline operator unspecified_bool_type() const;
226
228 inline bool is_negative() const {
229#if TIMESTAMP_REP_FLAT64 || TIMESTAMP_MATH_FLAT64
230 return _t.x < 0;
231#else
232 return sec() < 0;
233#endif
234 }
235
236 inline seconds_type sec() const;
237 inline uint32_t subsec() const;
238 inline uint32_t msec() const;
239 inline uint32_t usec() const;
240 inline uint32_t nsec() const;
241
242 inline void set_sec(seconds_type sec);
243 inline void set_subsec(uint32_t subsec);
244
245 inline seconds_type msec1() const CLICK_DEPRECATED;
246 inline seconds_type usec1() const CLICK_DEPRECATED;
247 inline seconds_type nsec1() const CLICK_DEPRECATED;
248
249#if TIMESTAMP_PUNS_TIMEVAL
250 inline const struct timeval &timeval() const;
251 inline const struct timeval &timeval_ceil() const;
252#else
253 inline struct timeval timeval() const;
254 inline struct timeval timeval_ceil() const;
255#endif
256#if HAVE_STRUCT_TIMESPEC
257# if TIMESTAMP_PUNS_TIMESPEC
258 inline const struct timespec &timespec() const;
259# else
260 inline struct timespec timespec() const;
261# endif
262#endif
263
264#if HAVE_INT64_TYPES
265 inline int64_t longval() const;
266 inline void assignlong(int64_t);
267#endif
268
269#if HAVE_FLOAT_TYPES
270 inline double doubleval() const;
271#endif
273 inline value_type msecval() const {
274#if TIMESTAMP_REP_FLAT64
275 return value_div(_t.x, subsec_per_sec / msec_per_sec);
276#else
277 return (value_type) _t.sec * msec_per_sec + subsec_to_msec(_t.subsec);
278#endif
279 }
281 inline value_type usecval() const {
282#if TIMESTAMP_REP_FLAT64
283 return value_div(_t.x, subsec_per_sec / usec_per_sec);
284#else
285 return (value_type) _t.sec * usec_per_sec + subsec_to_usec(_t.subsec);
286#endif
287 }
289 inline value_type nsecval() const {
290#if TIMESTAMP_REP_FLAT64
291 return _t.x * (nsec_per_sec / subsec_per_sec);
292#else
293 return (value_type) _t.sec * nsec_per_sec + subsec_to_nsec(_t.subsec);
294#endif
295 }
296
298 inline Timestamp msec_ceil() const {
299 uint32_t x = subsec() % subsec_per_msec;
300 return (x ? *this + Timestamp(0, subsec_per_msec - x) : *this);
301 }
303 inline Timestamp usec_ceil() const {
304#if TIMESTAMP_NANOSEC
305 uint32_t x = subsec() % subsec_per_usec;
306 return (x ? *this + Timestamp(0, subsec_per_usec - x) : *this);
307#else
308 return *this;
309#endif
310 }
312 inline Timestamp nsec_ceil() const {
313 return *this;
314 }
315
316#if !CLICK_TOOL
318 static inline Timestamp make_jiffies(click_jiffies_t jiffies);
320 static inline Timestamp make_jiffies(click_jiffies_difference_t jiffies);
322 inline click_jiffies_t jiffies() const;
323#endif
324
327 return Timestamp(sec, 0);
328 }
332 static inline Timestamp make_msec(seconds_type sec, uint32_t msec) {
334 }
337 Timestamp t = Timestamp::uninitialized_t();
338#if TIMESTAMP_REP_FLAT64
339 t._t.x = msec * (subsec_per_sec / msec_per_sec);
340#else
341 value_div_mod(t._t.sec, t._t.subsec, msec, msec_per_sec);
342 t._t.subsec *= subsec_per_sec / msec_per_sec;
343#endif
344 return t;
345 }
349 static inline Timestamp make_usec(seconds_type sec, uint32_t usec) {
351 }
354 Timestamp t = Timestamp::uninitialized_t();
355#if TIMESTAMP_REP_FLAT64
356 t._t.x = usec * (subsec_per_sec / usec_per_sec);
357#else
358 value_div_mod(t._t.sec, t._t.subsec, usec, usec_per_sec);
359 t._t.subsec *= subsec_per_sec / usec_per_sec;
360#endif
361 return t;
362 }
366 static inline Timestamp make_nsec(seconds_type sec, uint32_t nsec) {
368 }
371 Timestamp t = Timestamp::uninitialized_t();
372#if TIMESTAMP_REP_FLAT64
373 t._t.x = value_div(nsec, nsec_per_sec / subsec_per_sec);
374#else
375 value_div_mod(t._t.sec, t._t.subsec, nsec, nsec_per_sec);
376 t._t.subsec /= nsec_per_sec / subsec_per_sec;
377#endif
378 return t;
379 }
380
381
383 static inline Timestamp epsilon() {
384 return Timestamp(0, 1);
385 }
386
388 inline void clear() {
389 assign(0, 0);
390 }
391
392
396 inline void assign(seconds_type sec, uint32_t subsec = 0) {
397#if TIMESTAMP_REP_FLAT64
398 _t.x = (int64_t) sec * subsec_per_sec + subsec;
399#else
400 _t.sec = sec;
401 _t.subsec = subsec;
402#endif
403 }
405 inline void assign_usec(seconds_type sec, uint32_t usec) {
407 }
409 inline void assign_nsec(seconds_type sec, uint32_t nsec) {
411 }
412
416 inline void set(seconds_type sec, uint32_t subsec = 0) CLICK_DEPRECATED;
419 inline void set_usec(seconds_type sec, uint32_t usec) CLICK_DEPRECATED;
422 inline void set_nsec(seconds_type sec, uint32_t nsec) CLICK_DEPRECATED;
425 inline void set_now() CLICK_DEPRECATED;
427#if !CLICK_LINUXMODULE && !CLICK_BSDMODULE && !CLICK_MINIOS
428 int set_timeval_ioctl(int fd, int ioctl_selector);
429#endif
430
431
440 static inline Timestamp now();
441
446 inline void assign_now();
447
454 static inline Timestamp recent();
455
460 inline void assign_recent();
461
462
474 static inline Timestamp now_steady();
475
480 inline void assign_now_steady();
481
489 static inline Timestamp recent_steady();
490
495 inline void assign_recent_steady();
496
500 inline void assign_now_nouser(bool steady);
501
502
509 String unparse() const;
510
514 String unparse_interval() const;
515
516
523 inline static uint32_t msec_to_subsec(uint32_t msec) {
524 return msec * (subsec_per_sec / msec_per_sec);
525 }
527 inline static uint32_t usec_to_subsec(uint32_t usec) {
528 return usec * (subsec_per_sec / usec_per_sec);
529 }
531 inline static uint32_t nsec_to_subsec(uint32_t nsec) {
532 return nsec / (nsec_per_sec / subsec_per_sec);
533 }
535 inline static uint32_t subsec_to_msec(uint32_t subsec) {
536 return subsec / (subsec_per_sec / msec_per_sec);
537 }
539 inline static uint32_t subsec_to_usec(uint32_t subsec) {
540 return subsec / (subsec_per_sec / usec_per_sec);
541 }
543 inline static uint32_t subsec_to_nsec(uint32_t subsec) {
544 return subsec * (nsec_per_sec / subsec_per_sec);
545 }
546
547
552 union rep_t {
553#if TIMESTAMP_REP_FLAT64 || TIMESTAMP_MATH_FLAT64
554 int64_t x;
555#endif
556#if TIMESTAMP_REP_BIG_ENDIAN
557 struct {
558 int32_t sec;
559 int32_t subsec;
560 };
561#elif TIMESTAMP_REP_LITTLE_ENDIAN
562 struct {
563 int32_t subsec;
564 int32_t sec;
565 };
566#endif
567#if CLICK_LINUXMODULE
568# if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
569 ktime_t ktime;
570# elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 14)
571 skb_timeval skbtime;
572# endif
573#endif
574#if TIMESTAMP_PUNS_TIMEVAL
575 struct timeval tv;
576#elif TIMESTAMP_PUNS_TIMESPEC
577 struct timespec tspec;
578#endif
579 };
580
581#if TIMESTAMP_WARPABLE
584 enum warp_class_type {
585 warp_none = 0,
586 warp_linear = 1,
587 warp_nowait = 2,
588 // but don't wait for timers.
589 warp_simulation = 3
590 };
591
592
594 static inline int warp_class();
595
601 static inline double warp_speed();
602
603
634 static void warp_set_class(warp_class_type w, double s = 1.0);
635
641 static void warp_set_now(const Timestamp &t_system, const Timestamp &t_steady);
642
643
645 inline Timestamp warp_real_delay() const;
646
648 static inline bool warp_jumping();
649
653 static void warp_jump_steady(const Timestamp &expiry);
654
655
660 static inline Timestamp now_unwarped();
661
666 inline void assign_now_unwarped();
667
672 static inline Timestamp now_steady_unwarped();
673
679 inline void assign_now_steady_unwarped();
681
682
685 static void set_warp_tick(unsigned long tick);
686#endif
687
688#if HAVE_USER_TIMING
689 static bool set_clock(user_clock_fct clock, void* user);
690#endif
691
692 private:
693
694 rep_t _t;
695
696#if HAVE_USER_TIMING
697 static void* _user_data;
698 static user_clock_fct _user_clock;
699#endif
700
701 inline void add_fix() {
702#if TIMESTAMP_REP_FLAT64
703 /* no fix necessary */
704#elif TIMESTAMP_MATH_FLAT64
705 if (_t.subsec >= subsec_per_sec)
706 _t.x += (uint32_t) -subsec_per_sec;
707#else
708 if (_t.subsec >= subsec_per_sec)
709 _t.sec++, _t.subsec -= subsec_per_sec;
710#endif
711 }
712
713 inline void sub_fix() {
714#if TIMESTAMP_REP_FLAT64
715 /* no fix necessary */
716#elif TIMESTAMP_MATH_FLAT64
717 if (_t.subsec < 0)
718 _t.subsec += subsec_per_sec;
719#else
720 if (_t.subsec < 0)
721 _t.sec--, _t.subsec += subsec_per_sec;
722#endif
723 }
724
725 static inline value_type value_div(value_type a, uint32_t b) {
726 return int_divide(a, b);
727 }
728
729 static inline void value_div_mod(int32_t &div, int32_t &rem,
730 value_type a, uint32_t b) {
731 value_type quot;
732 rem = int_remainder(a, b, quot);
733 div = quot;
734 }
735
736 inline void assign_now(bool recent, bool steady, bool unwarped, bool no_user = false);
737
738#if TIMESTAMP_WARPABLE
739 static inline void warp_adjust(bool steady, const Timestamp &t_raw, const Timestamp &t_warped);
740 inline Timestamp warped(bool steady) const;
741 void warp(bool steady, bool from_now);
742#endif
743
744 friend inline bool operator==(const Timestamp &a, const Timestamp &b);
745 friend inline bool operator<(const Timestamp &a, const Timestamp &b);
746 friend inline Timestamp operator-(const Timestamp &b);
747 friend inline Timestamp &operator+=(Timestamp &a, const Timestamp &b);
748 friend inline Timestamp &operator-=(Timestamp &a, const Timestamp &b);
749
750};
751
752class UserClock {public:
753 enum {h_now, h_now_steady};
754 virtual int64_t now(bool steady) = 0;
755};
756
757#if TIMESTAMP_WARPABLE
759class TimestampWarp {
760 static Timestamp::warp_class_type kind;
761 static double speed;
762 static Timestamp flat_offset[2];
763 static double offset[2];
764 friend class Timestamp;
765};
768inline int Timestamp::warp_class() {
769 return TimestampWarp::kind;
770}
771
772inline double Timestamp::warp_speed() {
773 return TimestampWarp::speed;
774}
775
776inline bool Timestamp::warp_jumping() {
777 return TimestampWarp::kind >= warp_nowait;
778}
779
780inline Timestamp Timestamp::warped(bool steady) const {
781 Timestamp t = *this;
782 if (TimestampWarp::kind)
783 t.warp(steady, false);
784 return t;
785}
786#endif
787
788
791inline
793{
794 assign(tv.tv_sec, usec_to_subsec(tv.tv_usec));
795}
796
797#if HAVE_STRUCT_TIMESPEC
800inline
802{
803 assign(ts.tv_sec, nsec_to_subsec(ts.tv_nsec));
804}
805#endif
806
808inline
809Timestamp::operator unspecified_bool_type() const
810{
811#if TIMESTAMP_REP_FLAT64 || TIMESTAMP_MATH_FLAT64
812 return _t.x ? &Timestamp::sec : 0;
813#else
814 return _t.sec || _t.subsec ? &Timestamp::sec : 0;
815#endif
816}
817
818inline void
819Timestamp::assign_now(bool recent, bool steady, bool unwarped, bool nouser)
820{
821 (void) recent, (void) steady, (void) unwarped, (void) nouser;
822
823#if TIMESTAMP_PUNS_TIMESPEC
824# define TIMESTAMP_DECLARE_TSP struct timespec &tsp = _t.tspec
825# define TIMESTAMP_RESOLVE_TSP /* nothing */
826#else
827# define TIMESTAMP_DECLARE_TSP struct timespec ts, &tsp = ts
828# define TIMESTAMP_RESOLVE_TSP assign(tsp.tv_sec, nsec_to_subsec(tsp.tv_nsec))
829#endif
830#if TIMESTAMP_PUNS_TIMEVAL
831# define TIMESTAMP_DECLARE_TVP struct timeval &tvp = _t.tv
832# define TIMESTAMP_RESOLVE_TVP /* nothing */
833#else
834# define TIMESTAMP_DECLARE_TVP struct timeval tv, &tvp = tv
835# define TIMESTAMP_RESOLVE_TVP assign(tvp.tv_sec, usec_to_subsec(tvp.tv_usec))
836#endif
837
838#if HAVE_USER_TIMING
839 if (!nouser && _user_clock != 0) {
840 int64_t current = _user_clock(_user_data,steady);
841 assignlong(current);
842 } else
843#endif
844 {
845#if CLICK_LINUXMODULE
846# if !TIMESTAMP_NANOSEC
847 if (!recent && !steady) {
848 TIMESTAMP_DECLARE_TVP;
849 do_gettimeofday(&tvp);
850 TIMESTAMP_RESOLVE_TVP;
851 return;
852 }
853# endif
854 TIMESTAMP_DECLARE_TSP;
855 if (recent && steady) {
856# if HAVE_LINUX_GET_MONOTONIC_COARSE
857 tsp = get_monotonic_coarse();
858# elif HAVE_LINUX_GETBOOTTIME && HAVE_LINUX_KTIME_MONO_TO_ANY
859 // XXX Is this even worth it????? Would it be faster to just get the
860 // current time?
861 tsp = current_kernel_time();
862 struct timespec delta =
863 ktime_to_timespec(ktime_mono_to_any(ktime_set(0, 0), TK_OFFS_REAL));
864 set_normalized_timespec(&tsp, tsp.tv_sec - delta.tv_sec,
865 tsp.tv_nsec - delta.tv_nsec);
866# elif HAVE_LINUX_GETBOOTTIME
867 tsp = current_kernel_time();
868 struct timespec delta;
869 getboottime(&delta);
870 monotonic_to_bootbased(&delta);
871 set_normalized_timespec(&tsp, tsp.tv_sec - delta.tv_sec,
872 tsp.tv_nsec - delta.tv_nsec);
873# else
874 // older kernels don't export enough information to produce a recent
875 // steady timestamp; produce a current steady timestamp
876 ktime_get_ts(&tsp);
877# endif
878 } else if (recent)
879 tsp = current_kernel_time();
880 else if (steady)
881 ktime_get_ts(&tsp);
882 else
883 getnstimeofday(&tsp);
884 TIMESTAMP_RESOLVE_TSP;
885
886#elif TIMESTAMP_NANOSEC && CLICK_BSDMODULE
887 TIMESTAMP_DECLARE_TSP;
888 if (recent && steady)
889 getnanouptime(&tsp);
890 else if (recent)
891 getnanotime(&tsp);
892 else if (steady)
893 nanouptime(&tsp);
894 else
895 nanotime(&tsp);
896 TIMESTAMP_RESOLVE_TSP;
897
898#elif CLICK_BSDMODULE
899 TIMESTAMP_DECLARE_TVP;
900 if (recent && steady)
901 getmicrouptime(&tvp);
902 else if (recent)
903 getmicrotime(&tvp);
904 else if (steady)
905 microuptime(&tvp);
906 else
907 microtime(&tvp);
908 TIMESTAMP_RESOLVE_TVP;
909
910#elif CLICK_MINIOS
911 TIMESTAMP_DECLARE_TVP;
912 gettimeofday(&tvp, (struct timezone *) 0);
913 TIMESTAMP_RESOLVE_TVP;
914
915#elif CLICK_NS
916 if (schedule_granularity == usec_per_sec) {
917 TIMESTAMP_DECLARE_TVP;
918 simclick_gettimeofday(&tvp);
919 TIMESTAMP_RESOLVE_TVP;
920 } else {
921 assert(0 && "nanosecond precision not available yet");
922 }
923
924#elif HAVE_USE_CLOCK_GETTIME
925 TIMESTAMP_DECLARE_TSP;
926 if (steady)
927 clock_gettime(CLOCK_MONOTONIC, &tsp);
928 else
929 clock_gettime(CLOCK_REALTIME, &tsp);
930 TIMESTAMP_RESOLVE_TSP;
931
932#else
933 TIMESTAMP_DECLARE_TVP;
934 gettimeofday(&tvp, (struct timezone *) 0);
935 TIMESTAMP_RESOLVE_TVP;
936#endif
937
938#undef TIMESTAMP_DECLARE_TSP
939#undef TIMESTAMP_RESOLVE_TSP
940#undef TIMESTAMP_DECLARE_TVP
941#undef TIMESTAMP_RESOLVE_TVP
942
943 }
944#ifdef TIMESTAMP_WARPABLE
945 // timewarping
946 if (!unwarped && TimestampWarp::kind)
947 warp(steady, true);
948#endif
949}
950
951inline void
953{
954 assign_now(false, false, false);
955}
956
957inline Timestamp
959{
960 Timestamp t = Timestamp::uninitialized_t();
961 t.assign_now();
962 return t;
963}
964
965inline void
967{
968 assign_now(true, false, false);
969}
970
971inline Timestamp
973{
974 Timestamp t = Timestamp::uninitialized_t();
975 t.assign_recent();
976 return t;
977}
978
979inline void
981{
982 assign_now(false, true, false);
983}
984
985inline Timestamp
987{
988 Timestamp t = Timestamp::uninitialized_t();
990 return t;
991}
992
993inline void
995{
996 assign_now(true, true, false);
997}
998
999inline Timestamp
1001{
1002 Timestamp t = Timestamp::uninitialized_t();
1004 return t;
1005}
1006
1007inline void
1009{
1010 assign_now(false, steady, false, true);
1011}
1012
1013
1014#if TIMESTAMP_WARPABLE
1015inline void
1016Timestamp::assign_now_unwarped()
1017{
1018 assign_now(false, false, true);
1019}
1020
1021inline Timestamp
1022Timestamp::now_unwarped()
1023{
1024 Timestamp t = Timestamp::uninitialized_t();
1025 t.assign_now_unwarped();
1026 return t;
1027}
1028
1029inline void
1030Timestamp::assign_now_steady_unwarped()
1031{
1032 assign_now(false, true, true);
1033}
1034
1035inline Timestamp
1036Timestamp::now_steady_unwarped()
1037{
1038 Timestamp t = Timestamp::uninitialized_t();
1039 t.assign_now_steady_unwarped();
1040 return t;
1041}
1042#endif
1043
1047inline void
1049{
1050#if TIMESTAMP_REP_FLAT64
1051 uint32_t ss = subsec();
1052 _t.x = (int64_t) sec * subsec_per_sec + ss;
1053#else
1054 _t.sec = sec;
1055#endif
1056}
1057
1062inline void
1064{
1065#if TIMESTAMP_REP_FLAT64
1066 seconds_type s = sec();
1067 _t.x = (int64_t) s * subsec_per_sec + subsec;
1068#else
1069 _t.subsec = subsec;
1070#endif
1071}
1072
1076{
1077#if TIMESTAMP_REP_FLAT64
1078 if (unlikely(_t.x < 0))
1079 return -value_div(-(_t.x + 1), subsec_per_sec) - 1;
1080 else
1081 return value_div(_t.x, subsec_per_sec);
1082#else
1083 return _t.sec;
1084#endif
1085}
1086
1088inline uint32_t
1090{
1091#if TIMESTAMP_REP_FLAT64
1092 return _t.x - (uint32_t) sec() * subsec_per_sec;
1093#else
1094 return _t.subsec;
1095#endif
1096}
1097
1100inline uint32_t
1102{
1103 return subsec_to_msec(subsec());
1104}
1105
1108inline uint32_t
1110{
1111 return subsec_to_usec(subsec());
1112}
1113
1116inline uint32_t
1118{
1119 return subsec_to_nsec(subsec());
1120}
1121
1128{
1129#if TIMESTAMP_REP_FLAT64
1130 return value_div(_t.x, subsec_per_sec / msec_per_sec);
1131#else
1132 return _t.sec * msec_per_sec + subsec_to_msec(_t.subsec);
1133#endif
1134}
1135
1142{
1143#if TIMESTAMP_REP_FLAT64
1144 return value_div(_t.x, subsec_per_sec / usec_per_sec);
1145#else
1146 return _t.sec * usec_per_sec + subsec_to_usec(_t.subsec);
1147#endif
1148}
1149
1156{
1157#if TIMESTAMP_REP_FLAT64
1158 return _t.x * (nsec_per_sec / subsec_per_sec);
1159#else
1160 return _t.sec * nsec_per_sec + subsec_to_nsec(_t.subsec);
1161#endif
1162}
1163
1164#if !CLICK_TOOL
1165inline click_jiffies_t
1167{
1168# if TIMESTAMP_REP_FLAT64
1169 // This is not very precise when CLICK_HZ doesn't divide NSUBSEC evenly.
1170 return value_div(_t.x, subsec_per_sec / CLICK_HZ);
1171# else
1172 click_jiffies_t j = ((click_jiffies_t) sec()) * CLICK_HZ;
1173# if CLICK_HZ == 100 || CLICK_HZ == 1000 || CLICK_HZ == 10000 || CLICK_HZ == 100000 || CLICK_HZ == 1000000
1174 return j + ((click_jiffies_t) subsec()) / (subsec_per_sec / CLICK_HZ);
1175# else
1176 // This is not very precise when CLICK_HZ doesn't divide NSUBSEC evenly.
1177 return j + ((click_jiffies_t) subsec()) / (subsec_per_sec / CLICK_HZ);
1178# endif
1179# endif
1180}
1181
1182inline Timestamp
1183Timestamp::make_jiffies(click_jiffies_t jiffies)
1184{
1185 // Not very precise when CLICK_HZ doesn't evenly divide subsec_per_sec.
1186 Timestamp t = Timestamp::uninitialized_t();
1187# if TIMESTAMP_REP_FLAT64
1188 t._t.x = (int64_t) jiffies * (subsec_per_sec / CLICK_HZ);
1189# else
1190 t._t.sec = jiffies / CLICK_HZ;
1191 t._t.subsec = (jiffies - t._t.sec * CLICK_HZ) * (subsec_per_sec / CLICK_HZ);
1192# endif
1193 return t;
1194}
1195
1196inline Timestamp
1197Timestamp::make_jiffies(click_jiffies_difference_t jiffies)
1198{
1199 // Not very precise when CLICK_HZ doesn't evenly divide subsec_per_sec.
1200 Timestamp t = Timestamp::uninitialized_t();
1201# if TIMESTAMP_REP_FLAT64
1202 t._t.x = (int64_t) jiffies * (subsec_per_sec / CLICK_HZ);
1203# else
1204 if (jiffies < 0)
1205 t._t.sec = -(-(jiffies + 1) / CLICK_HZ) - 1;
1206 else
1207 t._t.sec = jiffies / CLICK_HZ;
1208 t._t.subsec = (jiffies - t._t.sec * CLICK_HZ) * (subsec_per_sec / CLICK_HZ);
1209# endif
1210 return t;
1211}
1212#endif
1213
1215inline void Timestamp::set_now() {
1216 assign_now(false, false, false);
1217}
1218
1219inline void Timestamp::set(seconds_type sec, uint32_t subsec) {
1220 assign(sec, subsec);
1221}
1222
1223inline void Timestamp::set_usec(seconds_type sec, uint32_t usec) {
1225}
1226
1227inline void Timestamp::set_nsec(seconds_type sec, uint32_t nsec) {
1229}
1237inline bool
1238operator==(const Timestamp &a, const Timestamp &b)
1239{
1240#if TIMESTAMP_REP_FLAT64 || TIMESTAMP_MATH_FLAT64
1241 return a._t.x == b._t.x;
1242#else
1243 return a.sec() == b.sec() && a.subsec() == b.subsec();
1244#endif
1245}
1246
1251inline bool
1252operator!=(const Timestamp &a, const Timestamp &b)
1253{
1254 return !(a == b);
1255}
1256
1262inline bool
1263operator<(const Timestamp &a, const Timestamp &b)
1264{
1265#if TIMESTAMP_REP_FLAT64 || TIMESTAMP_MATH_FLAT64
1266 return a._t.x < b._t.x;
1267#else
1268 return a.sec() < b.sec() || (a.sec() == b.sec() && a.subsec() < b.subsec());
1269#endif
1270}
1271
1273inline bool
1274operator<(const Timestamp &a, int b)
1275{
1276 return a < Timestamp(b);
1277}
1278
1284inline bool
1285operator<=(const Timestamp &a, const Timestamp &b)
1286{
1287 return !(b < a);
1288}
1289
1291inline bool
1292operator<=(const Timestamp &a, int b)
1293{
1294 return a <= Timestamp(b);
1295}
1296
1302inline bool
1303operator>=(const Timestamp &a, const Timestamp &b)
1304{
1305 return !(a < b);
1306}
1307
1309inline bool
1310operator>=(const Timestamp &a, int b)
1311{
1312 return a >= Timestamp(b);
1313}
1314
1320inline bool
1321operator>(const Timestamp &a, const Timestamp &b)
1322{
1323 return b < a;
1324}
1325
1327inline bool
1328operator>(const Timestamp &a, int b)
1329{
1330 return a > Timestamp(b);
1331}
1332
1336inline Timestamp &
1338{
1339#if TIMESTAMP_REP_FLAT64 || TIMESTAMP_MATH_FLAT64
1340 a._t.x += b._t.x;
1341#else
1342 a._t.sec += b._t.sec;
1343 a._t.subsec += b._t.subsec;
1344#endif
1345 a.add_fix();
1346 return a;
1347}
1348
1352inline Timestamp &
1354{
1355#if TIMESTAMP_REP_FLAT64 || TIMESTAMP_MATH_FLAT64
1356 a._t.x -= b._t.x;
1357#else
1358 a._t.sec -= b._t.sec;
1359 a._t.subsec -= b._t.subsec;
1360#endif
1361 a.sub_fix();
1362 return a;
1363}
1364
1366inline Timestamp
1368{
1369 a += b;
1370 return a;
1371}
1372
1374inline Timestamp
1376{
1377 a -= b;
1378 return a;
1379}
1380
1382inline Timestamp
1384{
1385#if TIMESTAMP_REP_FLAT64
1386 Timestamp t = Timestamp::uninitialized_t();
1387 t._t.x = -a._t.x;
1388 return t;
1389#else
1390 if (a.subsec())
1391 return Timestamp(-(a.sec() + 1), Timestamp::subsec_per_sec - a.subsec());
1392 else
1393 return Timestamp(-a.sec(), 0);
1394#endif
1395}
1396
1397#if HAVE_INT64_TYPES
1399inline int64_t
1401{
1402#if TIMESTAMP_REP_FLAT64
1403 return _t.x;
1404#else
1405 return _t.sec * subsec_per_sec + _t.subsec;
1406#endif
1407}
1408
1409inline void Timestamp::assignlong(int64_t i) {
1410#if TIMESTAMP_REP_FLAT64
1411 _t.x = i;
1412#else
1413 _t.sec = i / subsec_per_sec;
1414 _t.subsec = i % subsec_per_sec;
1415#endif
1416}
1417#endif
1418
1419#if HAVE_FLOAT_TYPES
1421inline double
1423{
1424# if TIMESTAMP_REP_FLAT64
1425 return _t.x / (double) subsec_per_sec;
1426# else
1427 return _t.sec + (_t.subsec / (double) subsec_per_sec);
1428# endif
1429}
1430
1432inline
1434{
1435# if TIMESTAMP_REP_FLAT64
1436 _t.x = (int64_t) floor(d * subsec_per_sec + 0.5);
1437# else
1438 double dfloor = floor(d);
1439 _t.sec = (seconds_type) dfloor;
1440 _t.subsec = (uint32_t) ((d - dfloor) * subsec_per_sec + 0.5);
1441 add_fix();
1442# endif
1443}
1444
1446inline Timestamp
1447operator*(const Timestamp &a, double b)
1448{
1449 return Timestamp(a.doubleval() * b);
1450}
1451
1452inline Timestamp
1453operator*(const Timestamp &a, int b)
1454{
1455 return Timestamp(a.doubleval() * b);
1456}
1457
1458inline Timestamp
1459operator*(const Timestamp &a, unsigned b)
1460{
1461 return Timestamp(a.doubleval() * b);
1462}
1463
1464inline Timestamp
1465operator*(double a, const Timestamp &b)
1466{
1467 return Timestamp(b.doubleval() * a);
1468}
1469
1470inline Timestamp
1471operator*(int a, const Timestamp &b)
1472{
1473 return Timestamp(b.doubleval() * a);
1474}
1475
1476inline Timestamp
1477operator*(unsigned a, const Timestamp &b)
1478{
1479 return Timestamp(b.doubleval() * a);
1480}
1481
1483inline Timestamp
1484operator/(const Timestamp &a, double b)
1485{
1486 return Timestamp(a.doubleval() / b);
1487}
1488
1489inline Timestamp
1490operator/(const Timestamp &a, int b)
1491{
1492 return Timestamp(a.doubleval() / b);
1493}
1494
1495inline Timestamp
1496operator/(const Timestamp &a, unsigned b)
1497{
1498 return Timestamp(a.doubleval() / b);
1499}
1500
1502inline double
1503operator/(const Timestamp &a, const Timestamp &b)
1504{
1505 return a.doubleval() / b.doubleval();
1506}
1507#endif /* HAVE_FLOAT_TYPES */
1508
1509StringAccum& operator<<(StringAccum&, const Timestamp&);
1510
1511#if TIMESTAMP_WARPABLE
1512inline Timestamp
1513Timestamp::warp_real_delay() const
1514{
1515 if (likely(!TimestampWarp::kind) || TimestampWarp::speed == 1.0)
1516 return *this;
1517 else
1518 return *this / TimestampWarp::speed;
1519}
1520#endif
1521
1522#if TIMESTAMP_PUNS_TIMEVAL
1523inline const struct timeval &
1524Timestamp::timeval() const
1525{
1526 return _t.tv;
1527}
1528
1529inline const struct timeval &
1531{
1532 return _t.tv;
1533}
1534#else
1541inline struct timeval
1542Timestamp::timeval() const
1543{
1544 struct timeval tv;
1545 tv.tv_sec = sec();
1546 tv.tv_usec = usec();
1547 return tv;
1548}
1549
1555inline struct timeval
1556Timestamp::timeval_ceil() const
1557{
1558 return (*this + Timestamp(0, subsec_per_usec - 1)).timeval();
1559}
1560#endif
1561
1562#if HAVE_STRUCT_TIMESPEC
1563# if TIMESTAMP_PUNS_TIMESPEC
1564inline const struct timespec &
1565Timestamp::timespec() const
1566{
1567 return _t.tspec;
1568}
1569# else
1575inline struct timespec
1576Timestamp::timespec() const
1577{
1578 struct timespec ts;
1579 ts.tv_sec = sec();
1580 ts.tv_nsec = nsec();
1581 return ts;
1582}
1583# endif
1584#endif
1585
1586
1587class ArgContext;
1588extern const ArgContext blank_args;
1589bool cp_time(const String &str, Timestamp *result, bool allow_negative);
1590
1593class TimestampArg { public:
1594 TimestampArg(bool is_signed = false)
1595 : is_signed(is_signed) {
1596 }
1597 bool parse(const String &str, Timestamp &value, const ArgContext &args = blank_args) {
1598 (void) args;
1599 return cp_time(str, &value, is_signed);
1600 }
1601 bool is_signed;
1602};
1603
1604template<> struct DefaultArg<Timestamp> : public TimestampArg {};
1605template<> struct has_trivial_copy<Timestamp> : public true_type {};
1606
1607CLICK_ENDDECLS
1608#endif
Argument context class.
Definition args.hh:31
Efficiently build up Strings from pieces.
Definition straccum.hh:28
A string of characters.
Definition string.hh:22
Parser class for timestamps.
Definition timestamp.hh:1593
Represents a moment or interval in time.
Definition timestamp.hh:125
static Timestamp make_jiffies(click_jiffies_t jiffies)
Return a timestamp representing an interval of jiffies.
Definition timestamp.hh:1183
static Timestamp epsilon()
Return the smallest nonzero timestamp, Timestamp(0, 1).
Definition timestamp.hh:383
@ max_seconds
Definition timestamp.hh:137
@ min_seconds
Definition timestamp.hh:140
static uint32_t nsec_to_subsec(uint32_t nsec)
Convert nanoseconds to subseconds.
Definition timestamp.hh:531
static Timestamp make_msec(value_type msec)
Return a timestamp representing msec milliseconds.
Definition timestamp.hh:336
static Timestamp now_steady()
Return the current steady-clock time.
Definition timestamp.hh:986
@ subsec_per_sec
Definition timestamp.hh:153
void assign_recent_steady()
Set this timestamp to a recent steady-clock time.
Definition timestamp.hh:994
uint32_t nsec() const
Return this timestamp's subseconds component, converted to nanoseconds.
Definition timestamp.hh:1117
void assign(seconds_type sec, uint32_t subsec=0)
Definition timestamp.hh:396
static Timestamp now()
Return the current system time.
Definition timestamp.hh:958
int32_t value_type
Return type for msecval(), usecval(), and nsecval().
Definition timestamp.hh:133
int64_t longval() const
Return this timestamp's value in subseconds.
Definition timestamp.hh:1400
Timestamp(const uninitialized_t &unused)
Construct an uninitialized timestamp.
Definition timestamp.hh:220
static uint32_t subsec_to_usec(uint32_t subsec)
Convert subseconds to microseconds.
Definition timestamp.hh:539
bool operator>(const Timestamp &a, const Timestamp &b)
Compare two timestamps.
Definition timestamp.hh:1321
static Timestamp recent_steady()
Return a recent steady-clock time.
Definition timestamp.hh:1000
Timestamp nsec_ceil() const
Return the next nanosecond-valued timestamp no smaller than *this.
Definition timestamp.hh:312
Timestamp()
Construct a zero-valued Timestamp.
Definition timestamp.hh:177
String unparse() const
Unparse this timestamp into a String.
Definition timestamp.cc:240
struct timespec timespec() const
Return a struct timespec with the same value as this timestamp.
Definition timestamp.hh:1576
static Timestamp make_usec(value_type usec)
Return a timestamp representing usec microseconds.
Definition timestamp.hh:353
void set_subsec(uint32_t subsec)
Set this timestamp's subseconds component.
Definition timestamp.hh:1063
seconds_type usec1() const
Return this timestamp's interval length, converted to microseconds.
Definition timestamp.hh:1141
String unparse_interval() const
Unparse this timestamp into a String as an interval.
Definition timestamp.cc:248
bool is_negative() const
Test if this Timestamp is negative (< Timestamp(0, 0)).
Definition timestamp.hh:228
value_type nsecval() const
Return this timestamp's interval length in nanoseconds.
Definition timestamp.hh:289
Timestamp(long sec, uint32_t subsec=0)
Construct a Timestamp of sec seconds plus subsec subseconds.
Definition timestamp.hh:190
double doubleval() const
Return this timestamp's value, converted to a real number.
Definition timestamp.hh:1422
void assign_nsec(seconds_type sec, uint32_t nsec)
Definition timestamp.hh:409
value_type msecval() const
Return this timestamp's interval length in milliseconds.
Definition timestamp.hh:273
Timestamp(int sec, uint32_t subsec=0)
Definition timestamp.hh:194
Timestamp(unsigned long sec, uint32_t subsec=0)
Definition timestamp.hh:198
friend Timestamp & operator+=(Timestamp &a, const Timestamp &b)
Add b to a.
Definition timestamp.hh:1337
uint32_t msec() const
Return this timestamp's subseconds component, converted to milliseconds.
Definition timestamp.hh:1101
seconds_type msec1() const
Return this timestamp's interval length, converted to milliseconds.
Definition timestamp.hh:1127
static Timestamp make_usec(seconds_type sec, uint32_t usec)
Return a timestamp representing sec seconds plus usec microseconds.
Definition timestamp.hh:349
bool operator!=(const Timestamp &a, const Timestamp &b)
Compare two timestamps for inequality.
Definition timestamp.hh:1252
seconds_type nsec1() const
Return this timestamp's interval length, converted to nanoseconds.
Definition timestamp.hh:1155
friend bool operator==(const Timestamp &a, const Timestamp &b)
Compare two timestamps for equality.
Definition timestamp.hh:1238
friend bool operator<(const Timestamp &a, const Timestamp &b)
Compare two timestamps.
Definition timestamp.hh:1263
static uint32_t subsec_to_nsec(uint32_t subsec)
Convert subseconds to nanoseconds.
Definition timestamp.hh:543
static Timestamp make_msec(seconds_type sec, uint32_t msec)
Return a timestamp representing sec seconds plus msec milliseconds.
Definition timestamp.hh:332
int32_t seconds_type
Type represents a number of seconds.
Definition timestamp.hh:128
void assign_now_steady()
Set this timestamp to the current steady-clock time.
Definition timestamp.hh:980
friend Timestamp operator-(const Timestamp &b)
Negate a and return the result.
Definition timestamp.hh:1383
void assign_recent()
Set this timestamp to a recent system time.
Definition timestamp.hh:966
void clear()
Clear this timestamp.
Definition timestamp.hh:388
static Timestamp make_nsec(seconds_type sec, uint32_t nsec)
Return a timestamp representing sec seconds plus nsec nanoseconds.
Definition timestamp.hh:366
uint32_t usec() const
Return this timestamp's subseconds component, converted to microseconds.
Definition timestamp.hh:1109
seconds_type sec() const
Return this timestamp's seconds component.
Definition timestamp.hh:1075
void assign_now()
Set this timestamp to the current system time.
Definition timestamp.hh:952
static Timestamp make_nsec(value_type nsec)
Return a timestamp representing nsec nanoseconds.
Definition timestamp.hh:370
static uint32_t msec_to_subsec(uint32_t msec)
Convert milliseconds to subseconds.
Definition timestamp.hh:523
void set_sec(seconds_type sec)
Set this timestamp's seconds component.
Definition timestamp.hh:1048
static Timestamp make_sec(seconds_type sec)
Return a timestamp representing sec seconds.
Definition timestamp.hh:326
uint32_t subsec() const
Return this timestamp's subseconds component.
Definition timestamp.hh:1089
Timestamp(const rep_t &rep)
Construct a Timestamp from its internal representation.
Definition timestamp.hh:215
Timestamp usec_ceil() const
Return the next microsecond-valued timestamp no smaller than *this.
Definition timestamp.hh:303
static Timestamp recent()
Return a recent system time.
Definition timestamp.hh:972
friend Timestamp & operator-=(Timestamp &a, const Timestamp &b)
Subtract b from a.
Definition timestamp.hh:1353
void assign_now_nouser(bool steady)
Set this timestamp to the current clock time without calling the user clock if one is set.
Definition timestamp.hh:1008
click_jiffies_t jiffies() const
Return the number of jiffies represented by this timestamp.
Definition timestamp.hh:1166
value_type usecval() const
Return this timestamp's interval length in microseconds.
Definition timestamp.hh:281
struct timeval timeval() const
Return a struct timeval that approximates this timestamp.
Definition timestamp.hh:1542
Timestamp(unsigned sec, uint32_t subsec=0)
Definition timestamp.hh:202
bool operator>=(const Timestamp &a, const Timestamp &b)
Compare two timestamps.
Definition timestamp.hh:1303
static uint32_t usec_to_subsec(uint32_t usec)
Convert microseconds to subseconds.
Definition timestamp.hh:527
static uint32_t subsec_to_msec(uint32_t subsec)
Convert subseconds to milliseconds.
Definition timestamp.hh:535
struct timeval timeval_ceil() const
Return the minimum struct timeval >= this timestamp.
Definition timestamp.hh:1556
Timestamp msec_ceil() const
Return the next millisecond-valued timestamp no smaller than *this.
Definition timestamp.hh:298
void assign_usec(seconds_type sec, uint32_t usec)
Definition timestamp.hh:405
Type wrapper for the constant true.
Functions for manipulating integers.
uint32_t int_divide(uint32_t a, uint32_t b)
Return a / b.
Definition integers.hh:354
uint32_t int_remainder(uint32_t a, uint32_t b, uint32_t &quot)
Divide a / b, placing quotient in quot and returning remainder.
Definition integers.hh:445
Template determining whether T may be copied by memcpy.
Definition type_traits.hh:66
bool operator>=(const Timestamp &a, int b)
Definition timestamp.hh:1310
Timestamp & operator+=(Timestamp &a, const Timestamp &b)
Add b to a.
Definition timestamp.hh:1337
bool cp_time(const String &str, Timestamp *result, bool allow_negative)
Parse a timestamp from str.
Definition confparse.cc:1526
bool operator>(const Timestamp &a, int b)
Definition timestamp.hh:1328
Timestamp operator+(Timestamp, const Timestamp &)
Add the two operands and return the result.
Definition timestamp.hh:1367
Timestamp operator/(const Timestamp &a, double b)
Scale a down by a factor of b and return the result.
Definition timestamp.hh:1484
Timestamp operator*(const Timestamp &a, double b)
Scale a by a factor of b and return the result.
Definition timestamp.hh:1447
Timestamp operator-(Timestamp a, const Timestamp &b)
Subtract b from a and return the result.
Definition timestamp.hh:1375
bool operator<(const Timestamp &a, int b)
Definition timestamp.hh:1274
Timestamp & operator-=(Timestamp &a, const Timestamp &b)
Subtract b from a.
Definition timestamp.hh:1353
bool operator<=(const Timestamp &a, int b)
Definition timestamp.hh:1292
Type traits structures.
Type of a Timestamp representation.
Definition timestamp.hh:552