vn-verdnaturachat/ios/Pods/Flipper-Folly/folly/synchronization/WaitOptions.h

80 lines
2.8 KiB
C++

/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <chrono>
#include <folly/CPortability.h>
namespace folly {
/// WaitOptions
///
/// Various synchronization primitives as well as various concurrent data
/// structures built using them have operations which might wait. This type
/// represents a set of options for controlling such waiting.
class WaitOptions {
public:
struct Defaults {
/// spin_max
///
/// If multiple threads are actively using a synchronization primitive,
/// whether indirectly via a higher-level concurrent data structure or
/// directly, where the synchronization primitive has an operation which
/// waits and another operation which wakes the waiter, it is common for
/// wait and wake events to happen almost at the same time. In this state,
/// we lose big 50% of the time if the wait blocks immediately.
///
/// We can improve our chances of being waked immediately, before blocking,
/// by spinning for a short duration, although we have to balance this
/// against the extra cpu utilization, latency reduction, power consumption,
/// and priority inversion effect if we end up blocking anyway.
///
/// We use a default maximum of 2 usec of spinning. As partial consolation,
/// since spinning as implemented in folly uses the pause instruction where
/// available, we give a small speed boost to the colocated hyperthread.
///
/// On circa-2013 devbox hardware, it costs about 7 usec to FUTEX_WAIT and
/// then be awoken. Spins on this hw take about 7 nsec, where all but 0.5
/// nsec is the pause instruction.
static constexpr std::chrono::nanoseconds spin_max =
std::chrono::microseconds(2);
static constexpr bool logging_enabled = true;
};
constexpr std::chrono::nanoseconds spin_max() const {
return spin_max_;
}
constexpr WaitOptions& spin_max(std::chrono::nanoseconds dur) {
spin_max_ = dur;
return *this;
}
constexpr bool logging_enabled() const {
return logging_enabled_;
}
constexpr WaitOptions& logging_enabled(bool enable) {
logging_enabled_ = enable;
return *this;
}
private:
std::chrono::nanoseconds spin_max_ = Defaults::spin_max;
bool logging_enabled_ = Defaults::logging_enabled;
};
} // namespace folly