summaryrefslogtreecommitdiff
path: root/absl/synchronization/internal/kernel_timeout.cc
diff options
context:
space:
mode:
Diffstat (limited to 'absl/synchronization/internal/kernel_timeout.cc')
-rw-r--r--absl/synchronization/internal/kernel_timeout.cc41
1 files changed, 41 insertions, 0 deletions
diff --git a/absl/synchronization/internal/kernel_timeout.cc b/absl/synchronization/internal/kernel_timeout.cc
index 8d9e7d74..548a8fc6 100644
--- a/absl/synchronization/internal/kernel_timeout.cc
+++ b/absl/synchronization/internal/kernel_timeout.cc
@@ -15,6 +15,7 @@
#include "absl/synchronization/internal/kernel_timeout.h"
#include <algorithm>
+#include <chrono> // NOLINT(build/c++11)
#include <cstdint>
#include <ctime>
#include <limits>
@@ -163,6 +164,46 @@ KernelTimeout::DWord KernelTimeout::InMillisecondsFromNow() const {
return DWord{0};
}
+std::chrono::time_point<std::chrono::system_clock>
+KernelTimeout::ToChronoTimePoint() const {
+ if (!has_timeout()) {
+ return std::chrono::time_point<std::chrono::system_clock>::max();
+ }
+
+ // The cast to std::microseconds is because (on some platforms) the
+ // std::ratio used by std::chrono::steady_clock doesn't convert to
+ // std::nanoseconds, so it doesn't compile.
+ auto micros = std::chrono::duration_cast<std::chrono::microseconds>(
+ std::chrono::nanoseconds(RawNanos()));
+ if (is_relative_timeout()) {
+ auto now = std::chrono::system_clock::now();
+ if (micros >
+ std::chrono::time_point<std::chrono::system_clock>::max() - now) {
+ // Overflow.
+ return std::chrono::time_point<std::chrono::system_clock>::max();
+ }
+ return now + micros;
+ }
+ return std::chrono::system_clock::from_time_t(0) + micros;
+}
+
+std::chrono::nanoseconds KernelTimeout::ToChronoDuration() const {
+ if (!has_timeout()) {
+ return std::chrono::nanoseconds::max();
+ }
+ if (is_absolute_timeout()) {
+ auto d = std::chrono::duration_cast<std::chrono::nanoseconds>(
+ std::chrono::nanoseconds(RawNanos()) -
+ (std::chrono::system_clock::now() -
+ std::chrono::system_clock::from_time_t(0)));
+ if (d < std::chrono::nanoseconds(0)) {
+ d = std::chrono::nanoseconds(0);
+ }
+ return d;
+ }
+ return std::chrono::nanoseconds(RawNanos());
+}
+
} // namespace synchronization_internal
ABSL_NAMESPACE_END
} // namespace absl