1 // Copyright (c) 2011-present, Facebook, Inc. All rights reserved. 2 // This source code is licensed under both the GPLv2 (found in the 3 // COPYING file in the root directory) and Apache 2.0 License 4 // (found in the LICENSE.Apache file in the root directory). 5 6 #pragma once 7 8 #include <atomic> 9 #include <condition_variable> 10 11 namespace folly { 12 13 /** 14 * The behavior of the atomic_wait() family of functions is semantically 15 * identical to futex(). Correspondingly, calling atomic_notify_one(), 16 * atomic_notify_all() is identical to futexWake() with 1 and 17 * std::numeric_limits<int>::max() respectively 18 * 19 * The difference here compared to the futex API above is that it works with 20 * all types of atomic widths. When a 32 bit atomic integer is used, the 21 * implementation falls back to using futex() if possible, and the 22 * compatibility implementation for non-linux systems otherwise. For all 23 * other integer widths, the compatibility implementation is used 24 * 25 * The templating of this API is changed from the standard in the following 26 * ways 27 * 28 * - At the time of writing, libstdc++'s implementation of std::atomic<> does 29 * not include the value_type alias. So we rely on the atomic type being a 30 * template class such that the first type is the underlying value type 31 * - The Atom parameter allows this API to be compatible with 32 * DeterministicSchedule testing. 33 * - atomic_wait_until() does not exist in the linked paper, the version here 34 * is identical to futexWaitUntil() and returns std::cv_status 35 */ 36 // mimic: std::atomic_wait, p1135r0 37 template <typename Integer> 38 void atomic_wait(const std::atomic<Integer>* atomic, Integer expected); 39 template <typename Integer, typename Clock, typename Duration> 40 std::cv_status atomic_wait_until( 41 const std::atomic<Integer>* atomic, 42 Integer expected, 43 const std::chrono::time_point<Clock, Duration>& deadline); 44 45 // mimic: std::atomic_notify_one, p1135r0 46 template <typename Integer> 47 void atomic_notify_one(const std::atomic<Integer>* atomic); 48 // mimic: std::atomic_notify_all, p1135r0 49 template <typename Integer> 50 void atomic_notify_all(const std::atomic<Integer>* atomic); 51 52 // mimic: std::atomic_uint_fast_wait_t, p1135r0 53 using atomic_uint_fast_wait_t = std::atomic<std::uint32_t>; 54 55 } // namespace folly 56 57 #include <folly/synchronization/AtomicNotification-inl.h> 58