Files
threadweaver/include/weaver/atomic.h

89 lines
2.0 KiB
C++

#ifndef THWEAVER_ATOMIC_H
#define THWEAVER_ATOMIC_H
#include <cstdint>
#include <concepts>
#include <limits>
#include <type_traits>
template <typename T>
concept Additive = std::is_integral_v<T> && !std::is_same_v<T, bool>;
template <typename A, typename T>
concept AtomicAdditive =
requires(A a, T v) {
{
a.load()
}
-> std::same_as<T>;
{
a.store(v)
};
{
a.fetch_add(v)
}
-> std::same_as<T>;
{
a.fetch_sub(v)
}
-> std::same_as<T>;
};
template <typename T>
concept Bitwise =
(std::is_integral_v<T> || std::is_enum_v<T>) &&
!std::is_same_v<T, bool>;
template <typename A, typename T>
concept AtomicBitwise =
requires(A a, T v) {
{
a.load()
}
-> std::same_as<T>;
{
a.store(v)
};
{
a.fetch_or(v)
}
-> std::same_as<T>;
{
a.fetch_and(v)
}
-> std::same_as<T>;
{
a.fetch_xor(v)
}
-> std::same_as<T>;
};
// Uses the full bitmap
template<typename Atomic, typename T, uint32_t NumBits, typename Index = uint32_t>
requires Bitwise<T> && AtomicBitwise<Atomic, T> &&
Additive<Index> && std::is_unsigned_v<Index>
class AtomicBitmap {
public:
static_assert(NumBits <= std::numeric_limits<T>::digits);
AtomicBitmap() noexcept
: bits(T {}), rotation(0) {}
void reset(const T &bits, const Index rotation) noexcept;
bool get_bit(const Index n) const noexcept;
void set_bit(const Index n) noexcept;
void clear_bit(const Index n) noexcept;
void rotate(const Index n) noexcept;
Index get_rotation() const noexcept;
Index get_low_bit() const noexcept;
Index rotate_to_low_bit(const Index offset = 0) noexcept;
private:
Atomic bits;
Index rotation;
};
#endif