proxygen
AtomicBitSet.h
Go to the documentation of this file.
1 /*
2  * Copyright 2013-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 <array>
20 #include <atomic>
21 #include <cassert>
22 #include <cstddef>
23 #include <limits>
24 
25 #include <boost/noncopyable.hpp>
26 
27 #include <folly/Portability.h>
28 
29 namespace folly {
30 
34 template <size_t N>
35 class AtomicBitSet : private boost::noncopyable {
36  public:
40  AtomicBitSet();
41 
49  bool set(size_t idx, std::memory_order order = std::memory_order_seq_cst);
50 
58  bool reset(size_t idx, std::memory_order order = std::memory_order_seq_cst);
59 
70  bool set(
71  size_t idx,
72  bool value,
73  std::memory_order order = std::memory_order_seq_cst);
74 
78  bool test(size_t idx, std::memory_order order = std::memory_order_seq_cst)
79  const;
80 
84  bool operator[](size_t idx) const;
85 
89  constexpr size_t size() const {
90  return N;
91  }
92 
93  private:
94  // Pick the largest lock-free type available
95 #if (ATOMIC_LLONG_LOCK_FREE == 2)
96  typedef unsigned long long BlockType;
97 #elif (ATOMIC_LONG_LOCK_FREE == 2)
98  typedef unsigned long BlockType;
99 #else
100  // Even if not lock free, what can we do?
101  typedef unsigned int BlockType;
102 #endif
103  typedef std::atomic<BlockType> AtomicBlockType;
104 
105  static constexpr size_t kBitsPerBlock =
106  std::numeric_limits<BlockType>::digits;
107 
108  static constexpr size_t blockIndex(size_t bit) {
109  return bit / kBitsPerBlock;
110  }
111 
112  static constexpr size_t bitOffset(size_t bit) {
113  return bit % kBitsPerBlock;
114  }
115 
116  // avoid casts
117  static constexpr BlockType kOne = 1;
118 
119  std::array<AtomicBlockType, N> data_;
120 };
121 
122 // value-initialize to zero
123 template <size_t N>
125 
126 template <size_t N>
127 inline bool AtomicBitSet<N>::set(size_t idx, std::memory_order order) {
128  assert(idx < N * kBitsPerBlock);
129  BlockType mask = kOne << bitOffset(idx);
130  return data_[blockIndex(idx)].fetch_or(mask, order) & mask;
131 }
132 
133 template <size_t N>
134 inline bool AtomicBitSet<N>::reset(size_t idx, std::memory_order order) {
135  assert(idx < N * kBitsPerBlock);
136  BlockType mask = kOne << bitOffset(idx);
137  return data_[blockIndex(idx)].fetch_and(~mask, order) & mask;
138 }
139 
140 template <size_t N>
141 inline bool
142 AtomicBitSet<N>::set(size_t idx, bool value, std::memory_order order) {
143  return value ? set(idx, order) : reset(idx, order);
144 }
145 
146 template <size_t N>
147 inline bool AtomicBitSet<N>::test(size_t idx, std::memory_order order) const {
148  assert(idx < N * kBitsPerBlock);
149  BlockType mask = kOne << bitOffset(idx);
150  return data_[blockIndex(idx)].load(order) & mask;
151 }
152 
153 template <size_t N>
154 inline bool AtomicBitSet<N>::operator[](size_t idx) const {
155  return test(idx);
156 }
157 
158 } // namespace folly
bool reset(size_t idx, std::memory_order order=std::memory_order_seq_cst)
Definition: AtomicBitSet.h:134
constexpr size_t size() const
Definition: AtomicBitSet.h:89
bool operator[](size_t idx) const
Definition: AtomicBitSet.h:154
—— Concurrent Priority Queue Implementation ——
Definition: AtomicBitSet.h:29
unsigned int BlockType
Definition: AtomicBitSet.h:101
static constexpr size_t kBitsPerBlock
Definition: AtomicBitSet.h:105
bool test(size_t idx, std::memory_order order=std::memory_order_seq_cst) const
Definition: AtomicBitSet.h:147
static constexpr BlockType kOne
Definition: AtomicBitSet.h:117
std::array< AtomicBlockType, N > data_
Definition: AtomicBitSet.h:119
static constexpr size_t blockIndex(size_t bit)
Definition: AtomicBitSet.h:108
uint64_t value(const typename LockFreeRingBuffer< T, Atom >::Cursor &rbcursor)
static constexpr size_t bitOffset(size_t bit)
Definition: AtomicBitSet.h:112
int order
bool set(size_t idx, std::memory_order order=std::memory_order_seq_cst)
Definition: AtomicBitSet.h:127
std::atomic< BlockType > AtomicBlockType
Definition: AtomicBitSet.h:103