aboutsummaryrefslogtreecommitdiffstats
path: root/vespalib/src/vespa/vespalib/util/time.h
blob: 00287d847d6383bdfbd5c657d46194692b3d9a3e (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.

#pragma once

#include <chrono>
#include <vespa/vespalib/stllike/string.h>
#include <sys/time.h>

// Guidelines:
//
// If you want to store a time duration or take it as a parameter,
// prefer using vespalib::duration. This will allow automatic
// conversion for most input duration types while avoiding templates.
//
// When passing a verbatim time duration to a function, assigning it
// to a variable or comparing it to another time duration, prefer
// using chrono literals. This will greatly improve code readability.
//
// Avoid code that depends on the resolution of time
// durations. Specifically, do not use the count() function
// directly. Using the utility functions supplied below will both make
// your code safer (resolution independent) and simpler (avoiding
// duration_cast).
//
// Prefer using steady_clock, only use system_clock if you absolutely
// must have the system time.

using namespace std::literals::chrono_literals;

namespace vespalib {

using steady_clock = std::chrono::steady_clock;
using steady_time  = std::chrono::steady_clock::time_point;

using system_clock = std::chrono::system_clock;
using system_time  = std::chrono::system_clock::time_point;

using file_clock = std::chrono::file_clock;
using file_time  = std::chrono::file_clock::time_point;

using duration = std::chrono::nanoseconds;

constexpr double to_s(duration d) {
    return std::chrono::duration_cast<std::chrono::duration<double>>(d).count();
}

system_time to_utc(steady_time ts);

template <typename duration_type = duration>
constexpr duration_type from_s(double seconds) {
    return std::chrono::duration_cast<duration_type>(std::chrono::duration<double>(seconds));
}

constexpr int64_t count_s(duration d) {
    return std::chrono::duration_cast<std::chrono::seconds>(d).count();
}

constexpr int64_t count_ms(duration d) {
    return std::chrono::duration_cast<std::chrono::milliseconds>(d).count();
}

constexpr int64_t count_us(duration d) {
    return std::chrono::duration_cast<std::chrono::microseconds>(d).count();
}

constexpr int64_t count_ns(duration d) {
    return std::chrono::duration_cast<std::chrono::nanoseconds>(d).count();
}

constexpr duration from_timeval(const timeval & tv) {
    return duration(tv.tv_sec*1000000000L + tv.tv_usec*1000L);
}

constexpr duration from_timespec(const timespec & ts) {
    return duration(ts.tv_sec*1000000000L + ts.tv_nsec);
}

vespalib::string to_string(system_time time);
vespalib::string to_string(file_time time);

steady_time saturated_add(steady_time time, duration diff);

/**
 * Simple utility class used to measure how much time has elapsed
 * since it was constructed.
 **/
class Timer
{
private:
    steady_time _start;
public:
    Timer() : _start(steady_clock::now()) {}
    ~Timer();
    steady_time get_start() const { return _start; }
    duration elapsed() const { return (steady_clock::now() - _start); }
    static void waitAtLeast(duration dur, bool busyWait);
};

/**
 * The default frequency (1000hz) for vespa timer, with environment override VESPA_TIMER_HZ capped to [1..1000]
 */
uint32_t getVespaTimerHz();
duration adjustTimeoutByDetectedHz(duration timeout);
duration adjustTimeoutByHz(duration timeout, long hz);

}

#if (defined(_LIBCPP_VERSION) && _LIBCPP_VERSION < 170000) || (!defined(_LIBCPP_VERSION) && defined(_GLIBCXX_RELEASE) && _GLIBCXX_RELEASE < 12)

// Temporary workaround until libc++ supports stream operators for duration
// Temporary workaround while using libstdc++ 11

#include <iosfwd>

namespace std::chrono {

ostream& operator<<(ostream& os, const nanoseconds& value);

}
#endif