Handle max deadlines in Futex
authorYedidya Feldblum <yfeldblum@fb.com>
Fri, 19 Jan 2018 19:47:46 +0000 (11:47 -0800)
committerFacebook Github Bot <facebook-github-bot@users.noreply.github.com>
Fri, 19 Jan 2018 19:51:29 +0000 (11:51 -0800)
Summary:
[Folly] Handle max deadlines in `Futex`.

Some of the synchronization code internally treats deadlines which are equivalent to `time_point::max()` for the same clock as a sentinel value indicating a deadline at infinity, or equivalently the lack of a deadline.

Care must be taken when converting between clocks to translate a deadline at infinity for one clock to the deadline at infinity for the other clock.

Reviewed By: nbronson

Differential Revision: D6720021

fbshipit-source-id: cfc230dd2d8db55297385a4afcb6d87ae4221840

folly/detail/Futex.h

index de0c78f..aadddd0 100644 (file)
@@ -73,7 +73,9 @@ struct Futex : Atom<uint32_t> {
         std::chrono::steady_clock,
         std::chrono::system_clock>::type;
     auto const converted = time_point_conv<Target>(deadline);
-    return futexWaitImpl(expected, converted, waitMask);
+    return converted == Target::time_point::max()
+        ? futexWaitImpl(expected, nullptr, nullptr, waitMask)
+        : futexWaitImpl(expected, converted, waitMask);
   }
 
   /** Wakens up to count waiters where (waitMask & wakeMask) !=
@@ -95,9 +97,12 @@ struct Futex : Atom<uint32_t> {
   static typename TargetClock::time_point time_point_conv(
       std::chrono::time_point<Clock, Duration> const& time) {
     using std::chrono::duration_cast;
+    using TimePoint = std::chrono::time_point<Clock, Duration>;
     using TargetDuration = typename TargetClock::duration;
     using TargetTimePoint = typename TargetClock::time_point;
-    if (std::is_same<Clock, TargetClock>::value) {
+    if (time == TimePoint::max()) {
+      return TargetTimePoint::max();
+    } else if (std::is_same<Clock, TargetClock>::value) {
       // in place of time_point_cast, which cannot compile without if-constexpr
       auto const delta = time.time_since_epoch();
       return TargetTimePoint(duration_cast<TargetDuration>(delta));