/usr/include/mircommon/mir/time/posix_timestamp.h is in libmircommon-dev 0.31.1-0ubuntu1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
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 121 122 123 124 125 126 127 128 129 | /*
* Copyright © 2016 Canonical Ltd.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License version 2 or 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Authored by: Daniel van Vugt <daniel.van.vugt@canonical.com>
*/
#ifndef MIR_TIME_POSIX_TIMESTAMP_H_
#define MIR_TIME_POSIX_TIMESTAMP_H_
#include <chrono>
#include <ctime>
#include <stdexcept>
namespace mir { namespace time {
/*
* We need absolute precision here so sadly can't use high-level C++ clocks...
* - Graphics frame timing needs support for at least the kernel clocks
* CLOCK_REALTIME and CLOCK_MONOTONIC, to be selected at runtime, whereas
* std::chrono does not support CLOCK_REALTIME or easily switching clocks.
* - mir::time::Timestamp is relative to the (wrong) epoch of steady_clock,
* so converting to/from mir::time::Timestamp would be dangerously
* inaccurate at best.
*/
struct PosixTimestamp
{
clockid_t clock_id;
std::chrono::nanoseconds nanoseconds;
PosixTimestamp()
: clock_id{CLOCK_MONOTONIC}, nanoseconds{0} {}
PosixTimestamp(clockid_t clk, std::chrono::nanoseconds ns)
: clock_id{clk}, nanoseconds{ns} {}
PosixTimestamp(clockid_t clk, struct timespec const& ts)
: clock_id{clk}, nanoseconds{ts.tv_sec*1000000000LL + ts.tv_nsec} {}
static PosixTimestamp now(clockid_t clock_id)
{
struct timespec ts;
clock_gettime(clock_id, &ts);
return PosixTimestamp(clock_id, ts);
}
};
inline void assert_same_clock(PosixTimestamp const& a, PosixTimestamp const& b)
{
if (a.clock_id != b.clock_id)
throw std::logic_error("Can't compare different time domains");
}
inline bool operator==(PosixTimestamp const& a, PosixTimestamp const& b)
{
return a.clock_id == b.clock_id && a.nanoseconds == b.nanoseconds;
}
inline PosixTimestamp operator-(PosixTimestamp const& a,
std::chrono::nanoseconds b)
{
return PosixTimestamp(a.clock_id, a.nanoseconds - b);
}
inline std::chrono::nanoseconds operator-(PosixTimestamp const& a,
PosixTimestamp const& b)
{
assert_same_clock(a, b);
return a.nanoseconds - b.nanoseconds;
}
inline PosixTimestamp operator+(PosixTimestamp const& a,
std::chrono::nanoseconds b)
{
return PosixTimestamp(a.clock_id, a.nanoseconds + b);
}
inline std::chrono::nanoseconds operator%(PosixTimestamp const& a,
std::chrono::nanoseconds b)
{
return std::chrono::nanoseconds(a.nanoseconds.count() % b.count());
}
inline bool operator>(PosixTimestamp const& a, PosixTimestamp const& b)
{
assert_same_clock(a, b);
return a.nanoseconds > b.nanoseconds;
}
inline bool operator<(PosixTimestamp const& a, PosixTimestamp const& b)
{
assert_same_clock(a, b);
return a.nanoseconds < b.nanoseconds;
}
inline bool operator>=(PosixTimestamp const& a, PosixTimestamp const& b)
{
assert_same_clock(a, b);
return a.nanoseconds >= b.nanoseconds;
}
inline bool operator<=(PosixTimestamp const& a, PosixTimestamp const& b)
{
assert_same_clock(a, b);
return a.nanoseconds <= b.nanoseconds;
}
inline void sleep_until(PosixTimestamp const& t)
{
long long ns = t.nanoseconds.count();
struct timespec ts;
ts.tv_sec = ns / 1000000000LL;
ts.tv_nsec = ns % 1000000000LL;
while (EINTR == clock_nanosleep(t.clock_id, TIMER_ABSTIME, &ts, NULL)) {}
}
}} // namespace mir::time
#endif // MIR_TIME_POSIX_TIMESTAMP_H_
|