]>
Commit | Line | Data |
---|---|---|
f67539c2 TL |
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). | |
5 | ||
6 | #pragma once | |
7 | ||
8 | /* | |
9 | * @author Keith Adams <kma@fb.com> | |
10 | * @author Jordan DeLong <delong.j@fb.com> | |
11 | */ | |
12 | ||
13 | #include <cstdint> | |
14 | #include <thread> | |
15 | ||
16 | #include <folly/portability/Asm.h> | |
17 | ||
18 | namespace folly { | |
19 | ||
20 | ////////////////////////////////////////////////////////////////////// | |
21 | ||
22 | namespace detail { | |
23 | ||
24 | /* | |
25 | * A helper object for the contended case. Starts off with eager | |
26 | * spinning, and falls back to sleeping for small quantums. | |
27 | */ | |
28 | class Sleeper { | |
29 | static const uint32_t kMaxActiveSpin = 4000; | |
30 | ||
31 | uint32_t spinCount; | |
32 | ||
33 | public: | |
34 | Sleeper() noexcept : spinCount(0) {} | |
35 | ||
36 | static void sleep() noexcept { | |
37 | /* | |
38 | * Always sleep 0.5ms, assuming this will make the kernel put | |
39 | * us down for whatever its minimum timer resolution is (in | |
40 | * linux this varies by kernel version from 1ms to 10ms). | |
41 | */ | |
42 | std::this_thread::sleep_for(std::chrono::microseconds{500}); | |
43 | } | |
44 | ||
45 | void wait() noexcept { | |
46 | if (spinCount < kMaxActiveSpin) { | |
47 | ++spinCount; | |
48 | asm_volatile_pause(); | |
49 | } else { | |
50 | sleep(); | |
51 | } | |
52 | } | |
53 | }; | |
54 | ||
55 | } // namespace detail | |
56 | } // namespace folly | |
57 |