atomic.cpp: continuation of fixing all-ones masks

Also added missing const noexcept.
This commit is contained in:
Nekotekina 2020-11-13 05:36:39 +03:00
parent cfda4d0ade
commit e48f160a29
2 changed files with 26 additions and 11 deletions

View File

@ -1391,7 +1391,7 @@ bool atomic_wait_engine::raw_notify(const void* data, u64 thread_id)
{
for (u64 bits = s_cond_bits[i / 64]; bits; bits &= bits - 1)
{
utils::prefetch_read(s_cond_list + i + std::countl_zero(bits));
utils::prefetch_read(s_cond_list + i + std::countr_zero(bits));
}
}

View File

@ -72,24 +72,25 @@ namespace atomic_wait
__m128i mask;
template <typename T>
constexpr void set_value(T value)
static constexpr __m128i get_value(T value = T{})
{
static_assert((sizeof(T) & (sizeof(T) - 1)) == 0);
static_assert(sizeof(T) <= 16);
if constexpr (sizeof(T) <= 8)
{
old = _mm_cvtsi64_si128(std::bit_cast<get_uint_t<sizeof(T)>, T>(value));
return _mm_cvtsi64_si128(std::bit_cast<get_uint_t<sizeof(T)>, T>(value));
}
else if constexpr (sizeof(T) == 16)
{
old = std::bit_cast<__m128i>(value);
return std::bit_cast<__m128i>(value);
}
}
void set_value()
template <typename T>
constexpr void set_value(T value = T{})
{
old = _mm_setzero_si128();
old = get_value<T>();
}
template <typename T>
@ -108,9 +109,23 @@ namespace atomic_wait
}
}
void set_mask()
template <typename T>
constexpr void set_mask()
{
mask = _mm_set1_epi64x(-1);
mask = get_mask<T>();
}
template <typename T>
static constexpr __m128i get_mask()
{
if constexpr (sizeof(T) <= 8)
{
return _mm_cvtsi64_si128(UINT64_MAX >> ((64 - sizeof(T) * 8) & 63));
}
else
{
return _mm_set1_epi64x(-1);
}
}
};
@ -131,7 +146,7 @@ namespace atomic_wait
template <typename... U, std::size_t... Align>
constexpr list(atomic_t<U, Align>&... vars)
: m_info{{&vars.raw(), sizeof(U), _mm_setzero_si128(), _mm_set1_epi64x(-1)}...}
: m_info{{&vars.raw(), sizeof(U), info::get_value<U>(), info::get_mask<U>()}...}
{
static_assert(sizeof...(U) <= Max);
}
@ -164,7 +179,7 @@ namespace atomic_wait
m_info[Index].data = &var.raw();
m_info[Index].size = sizeof(T2) | (static_cast<u8>(Flags) << 8);
m_info[Index].template set_value<T2>(value);
m_info[Index].mask = _mm_set1_epi64x(-1);
m_info[Index].template set_mask<T2>();
}
template <uint Index, op Flags = op::eq, typename T2, std::size_t Align, typename U, typename V>
@ -1447,7 +1462,7 @@ public:
// Overload with mask (only selected bits are checked), timeout is discouraged
template <atomic_wait::op Flags = atomic_wait::op::eq>
void wait(type old_value, type mask_value, atomic_wait_timeout timeout = atomic_wait_timeout::inf)
void wait(type old_value, type mask_value, atomic_wait_timeout timeout = atomic_wait_timeout::inf) const noexcept
{
if constexpr (sizeof(T) <= 8)
{