Adds test drivers for concurrent hash maps
[folly.git] / folly / synchronization / WaitOptions.h
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 <chrono>
20
21 #include <folly/CPortability.h>
22
23 namespace folly {
24
25 /// WaitOptions
26 ///
27 /// Various synchronization primitives as well as various concurrent data
28 /// structures built using them have operations which might wait. This type
29 /// represents a set of options for controlling such waiting.
30 class WaitOptions {
31  public:
32   struct Defaults {
33     /// spin_max
34     ///
35     /// If multiple threads are actively using a synchronization primitive,
36     /// whether indirectly via a higher-level concurrent data structure or
37     /// directly, where the synchronization primitive has an operation which
38     /// waits and another operation which wakes the waiter, it is common for
39     /// wait and wake events to happen almost at the same time. In this state,
40     /// we lose big 50% of the time if the wait blocks immediately.
41     ///
42     /// We can improve our chances of being waked immediately, before blocking,
43     /// by spinning for a short duration, although we have to balance this
44     /// against the extra cpu utilization, latency reduction, power consumption,
45     /// and priority inversion effect if we end up blocking anyway.
46     ///
47     /// We use a default maximum of 2 usec of spinning. As partial consolation,
48     /// since spinning as implemented in folly uses the pause instruction where
49     /// available, we give a small speed boost to the colocated hyperthread.
50     ///
51     /// On circa-2013 devbox hardware, it costs about 7 usec to FUTEX_WAIT and
52     /// then be awoken. Spins on this hw take about 7 nsec, where all but 0.5
53     /// nsec is the pause instruction.
54     static constexpr std::chrono::nanoseconds spin_max =
55         std::chrono::microseconds(2);
56   };
57
58   std::chrono::nanoseconds spin_max() const {
59     return spin_max_;
60   }
61   WaitOptions& spin_max(std::chrono::nanoseconds dur) {
62     spin_max_ = dur;
63     return *this;
64   }
65
66  private:
67   std::chrono::nanoseconds spin_max_ = Defaults::spin_max;
68 };
69
70 } // namespace folly