1 | /* |
2 | * Copyright 2004-present Facebook, Inc. |
3 | * |
4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
5 | * you may not use this file except in compliance with the License. |
6 | * You may obtain a copy of the License at |
7 | * |
8 | * http://www.apache.org/licenses/LICENSE-2.0 |
9 | * |
10 | * Unless required by applicable law or agreed to in writing, software |
11 | * distributed under the License is distributed on an "AS IS" BASIS, |
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
13 | * See the License for the specific language governing permissions and |
14 | * limitations under the License. |
15 | */ |
16 | #pragma once |
17 | |
18 | #include <atomic> |
19 | #include <condition_variable> |
20 | |
21 | namespace folly { |
22 | |
23 | /** |
24 | * The behavior of the atomic_wait() family of functions is semantically |
25 | * identical to futex(). Correspondingly, calling atomic_notify_one(), |
26 | * atomic_notify_all() is identical to futexWake() with 1 and |
27 | * std::numeric_limits<int>::max() respectively |
28 | * |
29 | * The difference here compared to the futex API above is that it works with |
30 | * all types of atomic widths. When a 32 bit atomic integer is used, the |
31 | * implementation falls back to using futex() if possible, and the |
32 | * compatibility implementation for non-linux systems otherwise. For all |
33 | * other integer widths, the compatibility implementation is used |
34 | * |
35 | * The templating of this API is changed from the standard in the following |
36 | * ways |
37 | * |
38 | * - At the time of writing, libstdc++'s implementation of std::atomic<> does |
39 | * not include the value_type alias. So we rely on the atomic type being a |
40 | * template class such that the first type is the underlying value type |
41 | * - The Atom parameter allows this API to be compatible with |
42 | * DeterministicSchedule testing. |
43 | * - atomic_wait_until() does not exist in the linked paper, the version here |
44 | * is identical to futexWaitUntil() and returns std::cv_status |
45 | */ |
46 | // mimic: std::atomic_wait, p1135r0 |
47 | template <typename Integer> |
48 | void atomic_wait(const std::atomic<Integer>* atomic, Integer expected); |
49 | template <typename Integer, typename Clock, typename Duration> |
50 | std::cv_status atomic_wait_until( |
51 | const std::atomic<Integer>* atomic, |
52 | Integer expected, |
53 | const std::chrono::time_point<Clock, Duration>& deadline); |
54 | |
55 | // mimic: std::atomic_notify_one, p1135r0 |
56 | template <typename Integer> |
57 | void atomic_notify_one(const std::atomic<Integer>* atomic); |
58 | // mimic: std::atomic_notify_all, p1135r0 |
59 | template <typename Integer> |
60 | void atomic_notify_all(const std::atomic<Integer>* atomic); |
61 | |
62 | // mimic: std::atomic_uint_fast_wait_t, p1135r0 |
63 | using atomic_uint_fast_wait_t = std::atomic<std::uint32_t>; |
64 | |
65 | } // namespace folly |
66 | |
67 | #include <folly/synchronization/AtomicNotification-inl.h> |
68 | |