[UNTESTED] Basic queue and fan-in fabric implementation without full template generalization
This commit is contained in:
88
include/weaver/atomic.h
Normal file
88
include/weaver/atomic.h
Normal file
@@ -0,0 +1,88 @@
|
||||
#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
|
||||
Reference in New Issue
Block a user