proxygen
Spin.h
Go to the documentation of this file.
1 /*
2  * Copyright 2018-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 
17 #pragma once
18 
19 #include <algorithm>
20 #include <chrono>
21 #include <thread>
22 
23 #include <folly/portability/Asm.h>
25 
26 namespace folly {
27 namespace detail {
28 
29 enum class spin_result {
30  success, // condition passed
31  timeout, // exceeded deadline
32  advance, // exceeded current wait-options component timeout
33 };
34 
35 template <typename Clock, typename Duration, typename F>
37  std::chrono::time_point<Clock, Duration> const& deadline,
38  WaitOptions const& opt,
39  F f) {
40  if (opt.spin_max() <= opt.spin_max().zero()) {
41  return spin_result::advance;
42  }
43 
44  auto tbegin = Clock::now();
45  while (true) {
46  if (f()) {
47  return spin_result::success;
48  }
49 
50  auto const tnow = Clock::now();
51  if (tnow >= deadline) {
52  return spin_result::timeout;
53  }
54 
55  // Backward time discontinuity in Clock? revise pre_block starting point
56  tbegin = std::min(tbegin, tnow);
57  if (tnow >= tbegin + opt.spin_max()) {
58  return spin_result::advance;
59  }
60 
61  // The pause instruction is the polite way to spin, but it doesn't
62  // actually affect correctness to omit it if we don't have it. Pausing
63  // donates the full capabilities of the current core to its other
64  // hyperthreads for a dozen cycles or so.
66  }
67 }
68 
69 template <typename Clock, typename Duration, typename F>
71  std::chrono::time_point<Clock, Duration> const& deadline,
72  F f) {
73  while (true) {
74  if (f()) {
75  return spin_result::success;
76  }
77 
79  if (deadline != max && Clock::now() >= deadline) {
80  return spin_result::timeout;
81  }
82 
84  }
85 }
86 
87 } // namespace detail
88 } // namespace folly
spin_result spin_yield_until(std::chrono::time_point< Clock, Duration > const &deadline, F f)
Definition: Spin.h:70
auto f
std::chrono::nanoseconds spin_max() const
Definition: WaitOptions.h:58
LogLevel max
Definition: LogLevel.cpp:31
std::chrono::steady_clock::time_point now()
—— Concurrent Priority Queue Implementation ——
Definition: AtomicBitSet.h:29
LogLevel min
Definition: LogLevel.cpp:30
spin_result spin_pause_until(std::chrono::time_point< Clock, Duration > const &deadline, WaitOptions const &opt, F f)
Definition: Spin.h:36
void asm_volatile_pause()
Definition: Asm.h:37