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