]>
git.proxmox.com Git - ceph.git/blob - ceph/src/rocksdb/third-party/folly/folly/synchronization/detail/Spin.h
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).
12 #include <folly/portability/Asm.h>
13 #include <folly/synchronization/WaitOptions.h>
18 enum class spin_result
{
19 success
, // condition passed
20 timeout
, // exceeded deadline
21 advance
, // exceeded current wait-options component timeout
24 template <typename Clock
, typename Duration
, typename F
>
25 spin_result
spin_pause_until(
26 std::chrono::time_point
<Clock
, Duration
> const& deadline
,
27 WaitOptions
const& opt
,
29 if (opt
.spin_max() <= opt
.spin_max().zero()) {
30 return spin_result::advance
;
33 auto tbegin
= Clock::now();
36 return spin_result::success
;
39 auto const tnow
= Clock::now();
40 if (tnow
>= deadline
) {
41 return spin_result::timeout
;
44 // Backward time discontinuity in Clock? revise pre_block starting point
45 tbegin
= std::min(tbegin
, tnow
);
46 if (tnow
>= tbegin
+ opt
.spin_max()) {
47 return spin_result::advance
;
50 // The pause instruction is the polite way to spin, but it doesn't
51 // actually affect correctness to omit it if we don't have it. Pausing
52 // donates the full capabilities of the current core to its other
53 // hyperthreads for a dozen cycles or so.
58 template <typename Clock
, typename Duration
, typename F
>
59 spin_result
spin_yield_until(
60 std::chrono::time_point
<Clock
, Duration
> const& deadline
,
64 return spin_result::success
;
67 auto const max
= std::chrono::time_point
<Clock
, Duration
>::max();
68 if (deadline
!= max
&& Clock::now() >= deadline
) {
69 return spin_result::timeout
;
72 std::this_thread::yield();