proxygen
AtomicNotification-inl.h
Go to the documentation of this file.
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 <folly/detail/Futex.h>
20 
21 #include <condition_variable>
22 #include <cstdint>
23 
24 namespace folly {
25 namespace detail {
26 namespace atomic_notification {
32 static_assert(std::is_same<atomic_uint_fast_wait_t, Futex<std::atomic>>{}, "");
33 
38 inline std::cv_status toCvStatus(FutexResult result) {
39  return (result == FutexResult::TIMEDOUT) ? std::cv_status::timeout
40  : std::cv_status::no_timeout;
41 }
42 inline std::cv_status toCvStatus(ParkResult result) {
43  return (result == ParkResult::Timeout) ? std::cv_status::timeout
44  : std::cv_status::no_timeout;
45 }
46 
47 // ParkingLot instantiation for futex management
49 
50 template <template <typename...> class Atom, typename... Args>
52  const Atom<std::uint32_t, Args...>* atomic,
53  std::uint32_t expected) {
54  futexWait(atomic, expected);
55  return;
56 }
57 
58 template <template <typename...> class Atom, typename Integer, typename... Args>
59 void atomic_wait_impl(const Atom<Integer, Args...>* atomic, Integer expected) {
60  static_assert(!std::is_same<Integer, std::uint32_t>{}, "");
61  parkingLot.park(
62  atomic, -1, [&] { return atomic->load() == expected; }, [] {});
63 }
64 
65 template <
66  template <typename...> class Atom,
67  typename... Args,
68  typename Clock,
69  typename Duration>
70 std::cv_status atomic_wait_until_impl(
71  const Atom<std::uint32_t, Args...>* atomic,
72  std::uint32_t expected,
73  const std::chrono::time_point<Clock, Duration>& deadline) {
74  return toCvStatus(futexWaitUntil(atomic, expected, deadline));
75 }
76 
77 template <
78  template <typename...> class Atom,
79  typename Integer,
80  typename... Args,
81  typename Clock,
82  typename Duration>
83 std::cv_status atomic_wait_until_impl(
84  const Atom<Integer, Args...>* atomic,
85  Integer expected,
86  const std::chrono::time_point<Clock, Duration>& deadline) {
87  static_assert(!std::is_same<Integer, std::uint32_t>{}, "");
88  return toCvStatus(parkingLot.park_until(
89  atomic, -1, [&] { return atomic->load() == expected; }, [] {}, deadline));
90 }
91 
92 template <template <typename...> class Atom, typename... Args>
93 void atomic_notify_one_impl(const Atom<std::uint32_t, Args...>* atomic) {
94  futexWake(atomic, 1);
95  return;
96 }
97 
98 template <template <typename...> class Atom, typename Integer, typename... Args>
99 void atomic_notify_one_impl(const Atom<Integer, Args...>* atomic) {
100  static_assert(!std::is_same<Integer, std::uint32_t>{}, "");
101  parkingLot.unpark(atomic, [&](const auto& data) {
104  });
105 }
106 
107 template <template <typename...> class Atom, typename Integer, typename... Args>
108 void atomic_notify_all_impl(const Atom<std::uint32_t, Args...>* atomic) {
109  futexWake(atomic);
110  return;
111 }
112 
113 template <template <typename...> class Atom, typename Integer, typename... Args>
114 void atomic_notify_all_impl(const Atom<Integer, Args...>* atomic) {
115  static_assert(!std::is_same<Integer, std::uint32_t>{}, "");
116  parkingLot.unpark(atomic, [&](const auto& data) {
119  });
120 }
121 } // namespace atomic_notification
122 } // namespace detail
123 
124 template <typename Integer>
125 void atomic_wait(const std::atomic<Integer>* atomic, Integer expected) {
127 }
128 
129 template <typename Integer, typename Clock, typename Duration>
130 std::cv_status atomic_wait_until(
131  const std::atomic<Integer>* atomic,
132  Integer expected,
133  const std::chrono::time_point<Clock, Duration>& deadline) {
135  atomic, expected, deadline);
136 }
137 
138 template <typename Integer>
139 void atomic_notify_one(const std::atomic<Integer>* atomic) {
141 }
142 
143 template <typename Integer>
144 void atomic_notify_all(const std::atomic<Integer>* atomic) {
146 }
147 
148 } // namespace folly
ParkResult
Definition: ParkingLot.h:135
LogLevel max
Definition: LogLevel.cpp:31
void atomic_notify_one_impl(const Atom< std::uint32_t, Args... > *atomic)
void unpark(const Key key, Unparker &&func)
Atom< std::uint32_t > Futex
Definition: Futex.h:51
ParkResult park(const Key key, D &&data, ToPark &&toPark, PreWait &&preWait)
Definition: ParkingLot.h:189
internal::ArgsMatcher< InnerMatcher > Args(const InnerMatcher &matcher)
—— Concurrent Priority Queue Implementation ——
Definition: AtomicBitSet.h:29
FutexResult futexWait(const Futex *futex, uint32_t expected, uint32_t waitMask)
Definition: Futex-inl.h:100
ParkingLot< std::uint32_t > parkingLot
std::chrono::milliseconds Duration
Definition: Types.h:36
void atomic_notify_all(const std::atomic< Integer > *atomic)
void atomic_wait_impl(const Atom< std::uint32_t, Args... > *atomic, std::uint32_t expected)
#define Atom
constexpr auto data(C &c) -> decltype(c.data())
Definition: Access.h:71
ParkResult park_until(const Key key, D &&data, ToPark &&toPark, PreWait &&preWait, std::chrono::time_point< Clock, Duration > deadline)
Definition: ParkingLot.h:256
FutexResult futexWaitUntil(const Futex *futex, uint32_t expected, std::chrono::time_point< Clock, Duration > const &deadline, uint32_t waitMask)
Definition: Futex-inl.h:112
void atomic_wait(const std::atomic< Integer > *atomic, Integer expected)
std::cv_status toCvStatus(FutexResult result)
void atomic_notify_one(const std::atomic< Integer > *atomic)
std::cv_status atomic_wait_until_impl(const Atom< std::uint32_t, Args... > *atomic, std::uint32_t expected, const std::chrono::time_point< Clock, Duration > &deadline)
std::atomic< std::uint32_t > atomic_uint_fast_wait_t
#define FOLLY_SAFE_DCHECK(expr, msg)
Definition: SafeAssert.h:42
void atomic_notify_all_impl(const Atom< std::uint32_t, Args... > *atomic)
int futexWake(const Futex *futex, int count, uint32_t wakeMask)
Definition: Futex-inl.h:107
std::cv_status atomic_wait_until(const std::atomic< Integer > *atomic, Integer expected, const std::chrono::time_point< Clock, Duration > &deadline)