forked from isc-projects/dnsgen
-
Notifications
You must be signed in to change notification settings - Fork 0
/
timer.h
80 lines (68 loc) · 1.88 KB
/
timer.h
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
/*
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* See the COPYRIGHT file distributed with this work for additional
* information regarding copyright ownership.
*/
#pragma once
#include <time.h>
#include <ostream>
std::ostream& operator<<(std::ostream& os, const timespec& ts);
timespec operator-(const timespec& a, const timespec& b);
timespec operator+(const timespec& a, const timespec& b);
timespec operator+(const timespec& a, const uint64_t ns);
static const long ns_per_s = 1000000000UL;
//
// output a timespec with nanosecond precision
//
inline std::ostream& operator<<(std::ostream& os, const timespec& ts)
{
using namespace std;
ios init(nullptr);
init.copyfmt(os);
os << ts.tv_sec << "." << setw(9) << setfill('0') << ts.tv_nsec;
os.copyfmt(init);
return os;
}
//
// subtract one timespec from another, accounting for ns underflow
//
inline timespec operator-(const timespec& a, const timespec& b)
{
timespec res;
if (a.tv_nsec < b.tv_nsec) {
res.tv_sec = a.tv_sec - b.tv_sec - 1;
res.tv_nsec = ns_per_s + a.tv_nsec - b.tv_nsec;
} else {
res.tv_sec = a.tv_sec - b.tv_sec;
res.tv_nsec = a.tv_nsec - b.tv_nsec;
}
return res;
}
//
// add one timespec to another, accounting for ns overflow
//
inline timespec operator+(const timespec& a, const timespec& b)
{
timespec res;
res.tv_sec = a.tv_sec + b.tv_sec;
res.tv_nsec = a.tv_nsec + b.tv_nsec;
while (res.tv_nsec > ns_per_s) {
res.tv_sec += 1;
res.tv_nsec -= ns_per_s;
}
return res;
}
//
// add ns to a timespec via the preceeding function
//
inline timespec operator+(const timespec& a, const uint64_t ns)
{
auto div = ldiv(ns, ns_per_s);
timespec delta = { div.quot, div.rem };;
return a + delta;
}