Skip to content

Commit 25911ff

Browse files
authored
Merge pull request #182 from elbeno/fix-atomic-bitset-reset
🐛 Fix `atomic_bitset::reset` for order
2 parents 4b3c50f + 8a14d9e commit 25911ff

File tree

2 files changed

+39
-15
lines changed

2 files changed

+39
-15
lines changed

include/stdx/atomic_bitset.hpp

Lines changed: 33 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -159,28 +159,35 @@ class atomic_bitset {
159159
return *this;
160160
}
161161

162-
template <typename T> auto reset(T idx) -> bitset_t {
162+
template <typename T>
163+
auto reset(T idx, std::memory_order order = std::memory_order_seq_cst)
164+
-> bitset_t {
163165
auto const pos = static_cast<std::size_t>(to_underlying(idx));
164-
return bitset_t{
165-
atomic::fetch_and(storage, static_cast<elem_t>(~(bit << pos)))};
166-
}
167-
168-
auto reset(std::memory_order order = std::memory_order_seq_cst)
169-
LIFETIMEBOUND -> atomic_bitset & {
170-
atomic::store(storage, elem_t{}, order);
171-
return *this;
166+
return bitset_t{atomic::fetch_and(
167+
storage, static_cast<elem_t>(~(bit << pos)), order)};
172168
}
173169

174170
auto
175171
reset(lsb_t lsb, msb_t msb,
176172
std::memory_order order = std::memory_order_seq_cst) -> bitset_t {
177-
return set(lsb, msb, false, order);
173+
auto const l = to_underlying(lsb);
174+
auto const m = to_underlying(msb);
175+
auto const shifted_value = bit_mask<elem_t>(m, l);
176+
return bitset_t{atomic::fetch_and(storage, ~shifted_value, order)};
178177
}
179178

180179
auto
181180
reset(lsb_t lsb, length_t len,
182181
std::memory_order order = std::memory_order_seq_cst) -> bitset_t {
183-
return set(lsb, len, false, order);
182+
auto const l = to_underlying(lsb);
183+
auto const length = to_underlying(len);
184+
return reset(lsb, static_cast<msb_t>(l + length - 1), order);
185+
}
186+
187+
auto reset(std::memory_order order = std::memory_order_seq_cst)
188+
LIFETIMEBOUND -> atomic_bitset & {
189+
atomic::store(storage, elem_t{}, order);
190+
return *this;
184191
}
185192

186193
template <typename T>
@@ -191,6 +198,21 @@ class atomic_bitset {
191198
atomic::fetch_xor(storage, static_cast<elem_t>(bit << pos), order)};
192199
}
193200

201+
auto flip(lsb_t lsb, msb_t msb,
202+
std::memory_order order = std::memory_order_seq_cst) -> bitset_t {
203+
auto const l = to_underlying(lsb);
204+
auto const m = to_underlying(msb);
205+
auto const shifted_value = bit_mask<elem_t>(m, l);
206+
return bitset_t{atomic::fetch_xor(storage, shifted_value, order)};
207+
}
208+
209+
auto flip(lsb_t lsb, length_t len,
210+
std::memory_order order = std::memory_order_seq_cst) -> bitset_t {
211+
auto const l = to_underlying(lsb);
212+
auto const length = to_underlying(len);
213+
return flip(lsb, static_cast<msb_t>(l + length - 1), order);
214+
}
215+
194216
auto flip(std::memory_order order = std::memory_order_seq_cst) -> bitset_t {
195217
return bitset_t{atomic::fetch_xor(storage, mask, order)};
196218
}

test/atomic_bitset.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -355,11 +355,13 @@ TEMPLATE_TEST_CASE("reset returns the previous bitset", "[atomic_bitset]",
355355
TEMPLATE_TEST_CASE("flip returns the previous bitset", "[atomic_bitset]",
356356
std::uint8_t, std::uint16_t, std::uint32_t, std::uint64_t) {
357357
using namespace stdx::literals;
358-
auto bs = stdx::atomic_bitset<1, TestType>{0b1ul};
359-
CHECK(bs.flip() == stdx::bitset<1, TestType>{0b1ul});
358+
auto bs = stdx::atomic_bitset<8, TestType>{0b111ul};
359+
CHECK(bs.flip(0) == stdx::bitset<8, TestType>{0b111ul});
360360
CHECK(not bs[0]);
361-
CHECK(bs.flip(0) == stdx::bitset<1, TestType>{});
362-
CHECK(bs[0]);
361+
CHECK(bs.flip(1_lsb, 1_len) == stdx::bitset<8, TestType>{0b110ul});
362+
CHECK(not bs[1]);
363+
CHECK(bs.flip(2_lsb, 2_msb) == stdx::bitset<8, TestType>{0b100ul});
364+
CHECK(not bs[2]);
363365
}
364366

365367
TEST_CASE("atomic bitset is thread-safe", "[atomic_bitset]") {

0 commit comments

Comments
 (0)