Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / ceph / src / common / ceph_time.h
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
3 /*
4  * Ceph - scalable distributed file system
5  *
6  * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
7  *
8  * This is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License version 2.1, as published by the Free Software
11  * Foundation.  See file COPYING.
12  *
13  */
14
15 #ifndef COMMON_CEPH_TIME_H
16 #define COMMON_CEPH_TIME_H
17
18 #include <chrono>
19
20 #include "include/encoding.h"
21
22 #if defined(DARWIN)
23 #include <sys/_types/_timespec.h>
24 #include <mach/mach.h>
25 #include <mach/clock.h>
26
27 #define CLOCK_REALTIME CALENDAR_CLOCK
28 #define CLOCK_MONOTONIC SYSTEM_CLOCK
29 #define CLOCK_REALTIME_COARSE CLOCK_REALTIME
30 #define CLOCK_MONOTONIC_COARSE CLOCK_MONOTONIC
31
32 int clock_gettime(int clk_id, struct timespec *tp);
33 #endif
34
35 struct ceph_timespec;
36
37 namespace ceph {
38   namespace time_detail {
39     using std::chrono::duration_cast;
40     using std::chrono::seconds;
41     using std::chrono::microseconds;
42     using std::chrono::nanoseconds;
43     // Currently we use a 64-bit count of nanoseconds.
44
45     // We could, if we wished, use a struct holding a uint64_t count
46     // of seconds and a uint32_t count of nanoseconds.
47
48     // At least this way we can change it to something else if we
49     // want.
50     typedef uint64_t rep;
51
52     // A concrete duration, unsigned. The timespan Ceph thinks in.
53     typedef std::chrono::duration<rep, std::nano> timespan;
54
55
56     // Like the above but signed.
57     typedef int64_t signed_rep;
58
59     typedef std::chrono::duration<signed_rep, std::nano> signedspan;
60
61     // We define our own clocks so we can have our choice of all time
62     // sources supported by the operating system. With the standard
63     // library the resolution and cost are unspecified. (For example,
64     // the libc++ system_clock class gives only microsecond
65     // resolution.)
66
67     // One potential issue is that we should accept system_clock
68     // timepoints in user-facing APIs alongside (or instead of)
69     // ceph::real_clock times.
70     class real_clock {
71     public:
72       typedef timespan duration;
73       typedef duration::rep rep;
74       typedef duration::period period;
75       // The second template parameter defaults to the clock's duration
76       // type.
77       typedef std::chrono::time_point<real_clock> time_point;
78       static constexpr const bool is_steady = false;
79
80       static time_point now() noexcept {
81         struct timespec ts;
82         clock_gettime(CLOCK_REALTIME, &ts);
83         return from_timespec(ts);
84       }
85
86       static bool is_zero(const time_point& t) {
87         return (t == time_point::min());
88       }
89
90       // Allow conversion to/from any clock with the same interface as
91       // std::chrono::system_clock)
92       template<typename Clock, typename Duration>
93       static time_point to_system_time_point(
94         const std::chrono::time_point<Clock, Duration>& t) {
95         return time_point(seconds(Clock::to_time_t(t)) +
96                           duration_cast<duration>(t.time_since_epoch() %
97                                                   seconds(1)));
98       }
99       template<typename Clock, typename Duration>
100       static std::chrono::time_point<Clock, Duration> to_system_time_point(
101         const time_point& t) {
102         return (Clock::from_time_t(to_time_t(t)) +
103                 duration_cast<Duration>(t.time_since_epoch() % seconds(1)));
104       }
105
106       static time_t to_time_t(const time_point& t) noexcept {
107         return duration_cast<seconds>(t.time_since_epoch()).count();
108       }
109       static time_point from_time_t(const time_t& t) noexcept {
110         return time_point(seconds(t));
111       }
112
113       static void to_timespec(const time_point& t, struct timespec& ts) {
114         ts.tv_sec = to_time_t(t);
115         ts.tv_nsec = (t.time_since_epoch() % seconds(1)).count();
116       }
117       static struct timespec to_timespec(const time_point& t) {
118         struct timespec ts;
119         to_timespec(t, ts);
120         return ts;
121       }
122       static time_point from_timespec(const struct timespec& ts) {
123         return time_point(seconds(ts.tv_sec) + nanoseconds(ts.tv_nsec));
124       }
125
126       static void to_ceph_timespec(const time_point& t,
127                                    struct ceph_timespec& ts);
128       static struct ceph_timespec to_ceph_timespec(const time_point& t);
129       static time_point from_ceph_timespec(const struct ceph_timespec& ts);
130
131       static void to_timeval(const time_point& t, struct timeval& tv) {
132         tv.tv_sec = to_time_t(t);
133         tv.tv_usec = duration_cast<microseconds>(t.time_since_epoch() %
134                                                  seconds(1)).count();
135       }
136       static struct timeval to_timeval(const time_point& t) {
137         struct timeval tv;
138         to_timeval(t, tv);
139         return tv;
140       }
141       static time_point from_timeval(const struct timeval& tv) {
142         return time_point(seconds(tv.tv_sec) + microseconds(tv.tv_usec));
143       }
144
145       static double to_double(const time_point& t) {
146         return std::chrono::duration<double>(t.time_since_epoch()).count();
147       }
148       static time_point from_double(const double d) {
149         return time_point(duration_cast<duration>(
150                             std::chrono::duration<double>(d)));
151       }
152     };
153
154     class coarse_real_clock {
155     public:
156       typedef timespan duration;
157       typedef duration::rep rep;
158       typedef duration::period period;
159       // The second template parameter defaults to the clock's duration
160       // type.
161       typedef std::chrono::time_point<coarse_real_clock> time_point;
162       static constexpr const bool is_steady = false;
163
164       static time_point now() noexcept {
165         struct timespec ts;
166 #if defined(CLOCK_REALTIME_COARSE)
167         // Linux systems have _COARSE clocks.
168         clock_gettime(CLOCK_REALTIME_COARSE, &ts);
169 #elif defined(CLOCK_REALTIME_FAST)
170         // BSD systems have _FAST clocks.
171         clock_gettime(CLOCK_REALTIME_FAST, &ts);
172 #else
173         // And if we find neither, you may wish to consult your system's
174         // documentation.
175 #warning Falling back to CLOCK_REALTIME, may be slow.
176         clock_gettime(CLOCK_REALTIME, &ts);
177 #endif
178         return from_timespec(ts);
179       }
180
181       static time_t to_time_t(const time_point& t) noexcept {
182         return duration_cast<seconds>(t.time_since_epoch()).count();
183       }
184       static time_point from_time_t(const time_t t) noexcept {
185         return time_point(seconds(t));
186       }
187
188       static void to_timespec(const time_point& t, struct timespec& ts) {
189         ts.tv_sec = to_time_t(t);
190         ts.tv_nsec = (t.time_since_epoch() % seconds(1)).count();
191       }
192       static struct timespec to_timespec(const time_point& t) {
193         struct timespec ts;
194         to_timespec(t, ts);
195         return ts;
196       }
197       static time_point from_timespec(const struct timespec& ts) {
198         return time_point(seconds(ts.tv_sec) + nanoseconds(ts.tv_nsec));
199       }
200
201       static void to_ceph_timespec(const time_point& t,
202                                    struct ceph_timespec& ts);
203       static struct ceph_timespec to_ceph_timespec(const time_point& t);
204       static time_point from_ceph_timespec(const struct ceph_timespec& ts);
205
206       static void to_timeval(const time_point& t, struct timeval& tv) {
207         tv.tv_sec = to_time_t(t);
208         tv.tv_usec = duration_cast<microseconds>(t.time_since_epoch() %
209                                                  seconds(1)).count();
210       }
211       static struct timeval to_timeval(const time_point& t) {
212         struct timeval tv;
213         to_timeval(t, tv);
214         return tv;
215       }
216       static time_point from_timeval(const struct timeval& tv) {
217         return time_point(seconds(tv.tv_sec) + microseconds(tv.tv_usec));
218       }
219
220       static double to_double(const time_point& t) {
221         return std::chrono::duration<double>(t.time_since_epoch()).count();
222       }
223       static time_point from_double(const double d) {
224         return time_point(duration_cast<duration>(
225                             std::chrono::duration<double>(d)));
226       }
227     };
228
229     class mono_clock {
230     public:
231       typedef timespan duration;
232       typedef duration::rep rep;
233       typedef duration::period period;
234       typedef std::chrono::time_point<mono_clock> time_point;
235       static constexpr const bool is_steady = true;
236
237       static time_point now() noexcept {
238         struct timespec ts;
239         clock_gettime(CLOCK_MONOTONIC, &ts);
240         return time_point(seconds(ts.tv_sec) + nanoseconds(ts.tv_nsec));
241       }
242
243       // A monotonic clock's timepoints are only meaningful to the
244       // computer on which they were generated. Thus having an
245       // optional skew is meaningless.
246     };
247
248     class coarse_mono_clock {
249     public:
250       typedef timespan duration;
251       typedef duration::rep rep;
252       typedef duration::period period;
253       typedef std::chrono::time_point<coarse_mono_clock> time_point;
254       static constexpr const bool is_steady = true;
255
256       static time_point now() noexcept {
257         struct timespec ts;
258 #if defined(CLOCK_MONOTONIC_COARSE)
259         // Linux systems have _COARSE clocks.
260         clock_gettime(CLOCK_MONOTONIC_COARSE, &ts);
261 #elif defined(CLOCK_MONOTONIC_FAST)
262         // BSD systems have _FAST clocks.
263         clock_gettime(CLOCK_MONOTONIC_FAST, &ts);
264 #else
265         // And if we find neither, you may wish to consult your system's
266         // documentation.
267 #warning Falling back to CLOCK_MONOTONIC, may be slow.
268         clock_gettime(CLOCK_MONOTONIC, &ts);
269 #endif
270         return time_point(seconds(ts.tv_sec) + nanoseconds(ts.tv_nsec));
271       }
272     };
273
274     // So that our subtractions produce negative spans rather than
275     // arithmetic underflow.
276     namespace {
277       template<typename Rep1, typename Period1, typename Rep2,
278                typename Period2>
279       inline auto difference(std::chrono::duration<Rep1, Period1> minuend,
280                              std::chrono::duration<Rep2, Period2> subtrahend)
281         -> typename std::common_type<
282           std::chrono::duration<typename std::make_signed<Rep1>::type,
283                                 Period1>,
284           std::chrono::duration<typename std::make_signed<Rep2>::type,
285                                 Period2> >::type {
286         // Foo.
287         using srep =
288           typename std::common_type<
289             std::chrono::duration<typename std::make_signed<Rep1>::type,
290                                   Period1>,
291             std::chrono::duration<typename std::make_signed<Rep2>::type,
292                                   Period2> >::type;
293         return srep(srep(minuend).count() - srep(subtrahend).count());
294       }
295
296       template<typename Clock, typename Duration1, typename Duration2>
297       inline auto difference(
298         typename std::chrono::time_point<Clock, Duration1> minuend,
299         typename std::chrono::time_point<Clock, Duration2> subtrahend)
300         -> typename std::common_type<
301           std::chrono::duration<typename std::make_signed<
302                                   typename Duration1::rep>::type,
303                                 typename Duration1::period>,
304           std::chrono::duration<typename std::make_signed<
305                                   typename Duration2::rep>::type,
306                                 typename Duration2::period> >::type {
307         return difference(minuend.time_since_epoch(),
308                           subtrahend.time_since_epoch());
309       }
310     }
311   } // namespace time_detail
312
313   // duration is the concrete time representation for our code in the
314   // case that we are only interested in durations between now and the
315   // future. Using it means we don't have to have EVERY function that
316   // deals with a duration be a template. We can do so for user-facing
317   // APIs, however.
318   using time_detail::timespan;
319
320   // Similar to the above but for durations that can specify
321   // differences between now and a time point in the past.
322   using time_detail::signedspan;
323
324   // High-resolution real-time clock
325   using time_detail::real_clock;
326
327   // Low-resolution but preusmably faster real-time clock
328   using time_detail::coarse_real_clock;
329
330
331   // High-resolution monotonic clock
332   using time_detail::mono_clock;
333
334   // Low-resolution but, I would hope or there's no point, faster
335   // monotonic clock
336   using time_detail::coarse_mono_clock;
337
338   // Please note that the coarse clocks are disjoint. You cannot
339   // subtract a real_clock timepoint from a coarse_real_clock
340   // timepoint as, from C++'s perspective, they are disjoint types.
341
342   // This is not necessarily bad. If I sample a mono_clock and then a
343   // coarse_mono_clock, the coarse_mono_clock's time could potentially
344   // be previous to the mono_clock's time (just due to differing
345   // resolution) which would be Incorrect.
346
347   // This is not horrible, though, since you can use an idiom like
348   // mono_clock::timepoint(coarsepoint.time_since_epoch()) to unwrap
349   // and rewrap if you know what you're doing.
350
351
352   // Actual wall-clock times
353   typedef real_clock::time_point real_time;
354   typedef coarse_real_clock::time_point coarse_real_time;
355
356   // Monotonic times should never be serialized or communicated
357   // between machines, since they are incomparable. Thus we also don't
358   // make any provision for converting between
359   // std::chrono::steady_clock time and ceph::mono_clock time.
360   typedef mono_clock::time_point mono_time;
361   typedef coarse_mono_clock::time_point coarse_mono_time;
362
363   template<typename Rep1, typename Ratio1, typename Rep2, typename Ratio2>
364   auto floor(const std::chrono::duration<Rep1, Ratio1>& duration,
365              const std::chrono::duration<Rep2, Ratio2>& precision) ->
366     typename std::common_type<std::chrono::duration<Rep1, Ratio1>,
367                               std::chrono::duration<Rep2, Ratio2> >::type {
368     return duration - (duration % precision);
369   }
370
371   template<typename Rep1, typename Ratio1, typename Rep2, typename Ratio2>
372   auto ceil(const std::chrono::duration<Rep1, Ratio1>& duration,
373             const std::chrono::duration<Rep2, Ratio2>& precision) ->
374     typename std::common_type<std::chrono::duration<Rep1, Ratio1>,
375                               std::chrono::duration<Rep2, Ratio2> >::type {
376     auto tmod = duration % precision;
377     return duration - tmod + (tmod > tmod.zero() ? 1 : 0) * precision;
378   }
379
380   template<typename Clock, typename Duration, typename Rep, typename Ratio>
381   auto floor(const std::chrono::time_point<Clock, Duration>& timepoint,
382              const std::chrono::duration<Rep, Ratio>& precision) ->
383     std::chrono::time_point<Clock,
384                             typename std::common_type<
385                               Duration, std::chrono::duration<Rep, Ratio>
386                               >::type> {
387     return std::chrono::time_point<
388       Clock, typename std::common_type<
389         Duration, std::chrono::duration<Rep, Ratio> >::type>(
390           floor(timepoint.time_since_epoch(), precision));
391   }
392   template<typename Clock, typename Duration, typename Rep, typename Ratio>
393   auto ceil(const std::chrono::time_point<Clock, Duration>& timepoint,
394             const std::chrono::duration<Rep, Ratio>& precision) ->
395     std::chrono::time_point<Clock,
396                             typename std::common_type<
397                               Duration,
398                               std::chrono::duration<Rep, Ratio> >::type> {
399     return std::chrono::time_point<
400       Clock, typename std::common_type<
401         Duration, std::chrono::duration<Rep, Ratio> >::type>(
402           ceil(timepoint.time_since_epoch(), precision));
403   }
404
405   namespace {
406     inline timespan make_timespan(const double d) {
407       return std::chrono::duration_cast<timespan>(
408         std::chrono::duration<double>(d));
409     }
410   }
411
412   std::ostream& operator<<(std::ostream& m, const timespan& t);
413   template<typename Clock,
414            typename std::enable_if<!Clock::is_steady>::type* = nullptr>
415   std::ostream& operator<<(std::ostream& m,
416                            const std::chrono::time_point<Clock>& t);
417   template<typename Clock,
418            typename std::enable_if<Clock::is_steady>::type* = nullptr>
419   std::ostream& operator<<(std::ostream& m,
420                            const std::chrono::time_point<Clock>& t);
421
422   // The way std::chrono handles the return type of subtraction is not
423   // wonderful. The difference of two unsigned types SHOULD be signed.
424
425   namespace {
426     inline signedspan operator -(real_time minuend,
427                                  real_time subtrahend) {
428       return time_detail::difference(minuend, subtrahend);
429     }
430
431     inline signedspan operator -(coarse_real_time minuend,
432                                  coarse_real_time subtrahend) {
433       return time_detail::difference(minuend, subtrahend);
434     }
435
436     inline signedspan operator -(mono_time minuend,
437                                  mono_time subtrahend) {
438       return time_detail::difference(minuend, subtrahend);
439     }
440
441     inline signedspan operator -(coarse_mono_time minuend,
442                                  coarse_mono_time subtrahend) {
443       return time_detail::difference(minuend, subtrahend);
444     }
445   }
446
447   // We could add specializations of time_point - duration and
448   // time_point + duration to assert on overflow, but I don't think we
449   // should.
450
451 } // namespace ceph
452
453 // We need these definitions to be able to hande ::encode/::decode on
454 // time points.
455
456 template<typename Clock, typename Duration>
457 void encode(const std::chrono::time_point<Clock, Duration>& t,
458             ceph::bufferlist &bl) {
459   auto ts = Clock::to_timespec(t);
460   // A 32 bit count of seconds causes me vast unhappiness.
461   uint32_t s = ts.tv_sec;
462   uint32_t ns = ts.tv_nsec;
463   ::encode(s, bl);
464   ::encode(ns, bl);
465 }
466
467 template<typename Clock, typename Duration>
468 void decode(std::chrono::time_point<Clock, Duration>& t,
469             bufferlist::iterator& p) {
470   uint32_t s;
471   uint32_t ns;
472   ::decode(s, p);
473   ::decode(ns, p);
474   struct timespec ts = {
475     static_cast<time_t>(s),
476     static_cast<long int>(ns)};
477
478   t = Clock::from_timespec(ts);
479 }
480
481 // C++ Overload Resolution requires that our encode/decode functions
482 // be defined in the same namespace as the type. So we need this
483 // to handle things like ::encode(std::vector<ceph::real_time // > >)
484
485 namespace std {
486   namespace chrono {
487     template<typename Clock, typename Duration>
488     void encode(const time_point<Clock, Duration>& t,
489                 ceph::bufferlist &bl) {
490       ::encode(t, bl);
491     }
492
493     template<typename Clock, typename Duration>
494     void decode(time_point<Clock, Duration>& t, bufferlist::iterator &p) {
495       ::decode(t, p);
496     }
497   } // namespace chrono
498
499   // An overload of our own
500   namespace {
501     inline timespan abs(signedspan z) {
502       return z > signedspan::zero() ?
503         std::chrono::duration_cast<timespan>(z) :
504         timespan(-z.count());
505     }
506   }
507 } // namespace std
508
509 #endif // COMMON_CEPH_TIME_H