]> git.proxmox.com Git - ceph.git/blame - ceph/src/rocksdb/third-party/folly/folly/detail/Futex.h
update source to Ceph Pacific 16.2.2
[ceph.git] / ceph / src / rocksdb / third-party / folly / folly / detail / Futex.h
CommitLineData
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#include <atomic>
9#include <cassert>
10#include <chrono>
11#include <cstdint>
12#include <limits>
13#include <type_traits>
14
15namespace folly {
16namespace detail {
17
18enum class FutexResult {
19 VALUE_CHANGED, /* futex value didn't match expected */
20 AWOKEN, /* wakeup by matching futex wake, or spurious wakeup */
21 INTERRUPTED, /* wakeup by interrupting signal */
22 TIMEDOUT, /* wakeup by expiring deadline */
23};
24
25/**
26 * Futex is an atomic 32 bit unsigned integer that provides access to the
27 * futex() syscall on that value. It is templated in such a way that it
28 * can interact properly with DeterministicSchedule testing.
29 *
30 * If you don't know how to use futex(), you probably shouldn't be using
31 * this class. Even if you do know how, you should have a good reason
32 * (and benchmarks to back you up).
33 *
34 * Because of the semantics of the futex syscall, the futex family of
35 * functions are available as free functions rather than member functions
36 */
37template <template <typename> class Atom = std::atomic>
38using Futex = Atom<std::uint32_t>;
39
40/**
41 * Puts the thread to sleep if this->load() == expected. Returns true when
42 * it is returning because it has consumed a wake() event, false for any
43 * other return (signal, this->load() != expected, or spurious wakeup).
44 */
45template <typename Futex>
46FutexResult
47futexWait(const Futex* futex, uint32_t expected, uint32_t waitMask = -1);
48
49/**
50 * Similar to futexWait but also accepts a deadline until when the wait call
51 * may block.
52 *
53 * Optimal clock types: std::chrono::system_clock, std::chrono::steady_clock.
54 * NOTE: On some systems steady_clock is just an alias for system_clock,
55 * and is not actually steady.
56 *
57 * For any other clock type, now() will be invoked twice.
58 */
59template <typename Futex, class Clock, class Duration>
60FutexResult futexWaitUntil(
61 const Futex* futex,
62 uint32_t expected,
63 std::chrono::time_point<Clock, Duration> const& deadline,
64 uint32_t waitMask = -1);
65
66/**
67 * Wakes up to count waiters where (waitMask & wakeMask) != 0, returning the
68 * number of awoken threads, or -1 if an error occurred. Note that when
69 * constructing a concurrency primitive that can guard its own destruction, it
70 * is likely that you will want to ignore EINVAL here (as well as making sure
71 * that you never touch the object after performing the memory store that is
72 * the linearization point for unlock or control handoff). See
73 * https://sourceware.org/bugzilla/show_bug.cgi?id=13690
74 */
75template <typename Futex>
76int futexWake(
77 const Futex* futex,
78 int count = std::numeric_limits<int>::max(),
79 uint32_t wakeMask = -1);
80
81/** A std::atomic subclass that can be used to force Futex to emulate
82 * the underlying futex() syscall. This is primarily useful to test or
83 * benchmark the emulated implementation on systems that don't need it. */
84template <typename T>
85struct EmulatedFutexAtomic : public std::atomic<T> {
86 EmulatedFutexAtomic() noexcept = default;
87 constexpr /* implicit */ EmulatedFutexAtomic(T init) noexcept
88 : std::atomic<T>(init) {}
89 // It doesn't copy or move
90 EmulatedFutexAtomic(EmulatedFutexAtomic&& rhs) = delete;
91};
92
93} // namespace detail
94} // namespace folly
95
96#include <folly/detail/Futex-inl.h>