Skip to content

Instantly share code, notes, and snippets.

@omegacoleman
Last active November 27, 2020 14:58
Show Gist options
  • Save omegacoleman/1a174f84c42d50601a315c4e0904ab81 to your computer and use it in GitHub Desktop.
Save omegacoleman/1a174f84c42d50601a315c4e0904ab81 to your computer and use it in GitHub Desktop.
concurrent_bitset 并发bitset
#include <atomic>
#include <array>
#include <cstddef>
class cbs_8
{
private:
std::atomic<uint8_t> data_;
bool load(size_t idx) const
{
return 0 != (data_.load(std::memory_order_acquire) & (1 << idx));
}
void store(size_t idx, bool v)
{
for (;;) {
uint8_t data_before = data_.load(std::memory_order_acquire);
uint8_t data_after;
if (v) {
data_after = data_before | (1 << idx);
} else {
data_after = data_before & ~(1 << idx);
}
if (data_.compare_exchange_weak(
data_before, data_after,
std::memory_order_release,
std::memory_order_relaxed))
return;
}
}
public:
class reference
{
private:
cbs_8& container_;
size_t idx_;
public:
reference(cbs_8& container, size_t idx)
: container_(container), idx_(idx)
{}
operator bool() const {
return container_.load(idx_);
}
reference& operator=(bool v) {
container_.store(idx_, v);
return *this;
}
};
bool operator[](size_t idx) const
{
return load(idx);
}
reference operator[](size_t idx)
{
return reference{*this, idx};
}
};
template <size_t Size>
class concurrent_bitset
{
private:
static const size_t unit_size = 8;
std::array<cbs_8, (Size + (unit_size - 1)) / unit_size> units_;
public:
using reference = cbs_8::reference;
bool operator[](size_t idx) const
{
return units_[idx / unit_size][idx % unit_size];
}
reference operator[](size_t idx)
{
return units_[idx / unit_size][idx % unit_size];
}
};
#include "concurrent_bitset.hpp"
#include <iostream>
int main(void) {
concurrent_bitset<20> u;
u[0] = true;
u[7] = false;
u[14] = true;
u[15] = false;
u[19] = true;
std::cout << "u[0] = " << u[0] << std::endl;
std::cout << "u[7] = " << u[7] << std::endl;
std::cout << "u[14] = " << u[14] << std::endl;
std::cout << "u[15] = " << u[15] << std::endl;
std::cout << "u[19] = " << u[19] << std::endl;
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment