1 | /* |
2 | * Copyright 2017-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 <atomic> |
20 | #include <cstdint> |
21 | |
22 | namespace folly { |
23 | |
24 | /** |
25 | * Sets a bit at the given index in the binary representation of the integer |
26 | * to 1. Returns the previous value of the bit, so true if the bit was not |
27 | * changed, false otherwise |
28 | * |
29 | * On some architectures, using this is more efficient than the corresponding |
30 | * std::atomic::fetch_or() with a mask. For example to set the first (least |
31 | * significant) bit of an integer, you could do atomic.fetch_or(0b1) |
32 | * |
33 | * The efficiency win is only visible in x86 (yet) and comes from the |
34 | * implementation using the x86 bts instruction when possible. |
35 | * |
36 | * When something other than std::atomic is passed, the implementation assumed |
37 | * incompatibility with this interface and calls Atomic::fetch_or() |
38 | */ |
39 | template <typename Atomic> |
40 | bool atomic_fetch_set( |
41 | Atomic& atomic, |
42 | std::size_t bit, |
43 | std::memory_order order = std::memory_order_seq_cst); |
44 | |
45 | /** |
46 | * Resets a bit at the given index in the binary representation of the integer |
47 | * to 0. Returns the previous value of the bit, so true if the bit was |
48 | * changed, false otherwise |
49 | * |
50 | * This follows the same underlying principle and implementation as |
51 | * fetch_set(). Using the optimized implementation when possible and falling |
52 | * back to std::atomic::fetch_and() when in debug mode or in an architecture |
53 | * where an optimization is not possible |
54 | */ |
55 | template <typename Atomic> |
56 | bool atomic_fetch_reset( |
57 | Atomic& atomic, |
58 | std::size_t bit, |
59 | std::memory_order order = std::memory_order_seq_cst); |
60 | |
61 | } // namespace folly |
62 | |
63 | #include <folly/synchronization/AtomicUtil-inl.h> |
64 | |