mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-22 02:32:36 +01:00
atomic_t: cleanup type requirements
Add C++17 requirements. Remove alignment requirements (auto-align type). What's missing is to detect padding and forbid it.
This commit is contained in:
parent
8efc22bd45
commit
d1e7837422
@ -539,6 +539,12 @@ struct alignas(16) s128
|
||||
CHECK_SIZE_ALIGN(u128, 16, 16);
|
||||
CHECK_SIZE_ALIGN(s128, 16, 16);
|
||||
|
||||
template <>
|
||||
struct get_int_impl<16>
|
||||
{
|
||||
using utype = u128;
|
||||
};
|
||||
|
||||
// Return magic value for any unsigned type
|
||||
constexpr inline struct umax_helper
|
||||
{
|
||||
|
@ -38,7 +38,7 @@ enum
|
||||
CELL_AUDIO_BLOCK_SAMPLES = 256,
|
||||
|
||||
CELL_AUDIO_CREATEEVENTFLAG_SPU = 0x00000001,
|
||||
|
||||
|
||||
CELL_AUDIO_EVENT_MIX = 0,
|
||||
CELL_AUDIO_EVENT_HEADPHONE = 1,
|
||||
|
||||
@ -144,7 +144,7 @@ struct audio_port
|
||||
u32 size;
|
||||
u64 timestamp; // copy of global timestamp
|
||||
|
||||
struct alignas(8) level_set_t
|
||||
struct level_set_t
|
||||
{
|
||||
float value;
|
||||
float inc;
|
||||
|
@ -410,7 +410,7 @@ bool squeue_test_exit();
|
||||
template<typename T, u32 sq_size = 256>
|
||||
class squeue_t
|
||||
{
|
||||
struct alignas(8) squeue_sync_var_t
|
||||
struct squeue_sync_var_t
|
||||
{
|
||||
struct
|
||||
{
|
||||
|
@ -692,7 +692,7 @@ struct alignas(128) CellSpurs
|
||||
u8 xCA; // 0xCA
|
||||
u8 xCB; // 0xCB
|
||||
|
||||
struct alignas(4) SrvTraceSyncVar
|
||||
struct SrvTraceSyncVar
|
||||
{
|
||||
u8 sysSrvTraceInitialised; // 0xCC
|
||||
u8 sysSrvNotifyUpdateTraceComplete; // 0xCD
|
||||
@ -881,7 +881,7 @@ CHECK_SIZE_ALIGN(CellSpursWorkloadAttribute, 512, 8);
|
||||
|
||||
struct alignas(128) CellSpursEventFlag
|
||||
{
|
||||
struct alignas(8) ControlSyncVar
|
||||
struct ControlSyncVar
|
||||
{
|
||||
be_t<u16> events; // 0x00 Event bits
|
||||
be_t<u16> spuTaskPendingRecv; // 0x02 A bit is set to 1 when the condition of the SPU task using the slot are met and back to 0 when the SPU task unblocks
|
||||
|
@ -36,7 +36,7 @@ enum CellSyncError1 : u32
|
||||
|
||||
struct CellSyncMutex
|
||||
{
|
||||
struct alignas(4) Counter
|
||||
struct Counter
|
||||
{
|
||||
be_t<u16> rel;
|
||||
be_t<u16> acq;
|
||||
@ -162,7 +162,7 @@ CHECK_SIZE_ALIGN(CellSyncRwm, 16, 16);
|
||||
|
||||
struct alignas(32) CellSyncQueue
|
||||
{
|
||||
struct alignas(8) ctrl_t
|
||||
struct ctrl_t
|
||||
{
|
||||
union
|
||||
{
|
||||
@ -290,7 +290,7 @@ enum CellSyncQueueDirection : u32 // CellSyncLFQueueDirection
|
||||
|
||||
struct alignas(128) CellSyncLFQueue
|
||||
{
|
||||
struct alignas(8) pop1_t
|
||||
struct pop1_t
|
||||
{
|
||||
be_t<u16> m_h1;
|
||||
be_t<u16> m_h2;
|
||||
@ -303,13 +303,13 @@ struct alignas(128) CellSyncLFQueue
|
||||
be_t<u16> pack;
|
||||
};
|
||||
|
||||
struct alignas(4) pop3_t
|
||||
struct pop3_t
|
||||
{
|
||||
be_t<u16> m_h1;
|
||||
be_t<u16> m_h2;
|
||||
};
|
||||
|
||||
struct alignas(8) push1_t
|
||||
struct push1_t
|
||||
{
|
||||
be_t<u16> m_h5;
|
||||
be_t<u16> m_h6;
|
||||
@ -322,7 +322,7 @@ struct alignas(128) CellSyncLFQueue
|
||||
be_t<u16> pack;
|
||||
};
|
||||
|
||||
struct alignas(4) push3_t
|
||||
struct push3_t
|
||||
{
|
||||
be_t<u16> m_h5;
|
||||
be_t<u16> m_h6;
|
||||
|
@ -254,10 +254,10 @@ void atomic_wait::list<Max, T...>::wait(atomic_wait_timeout timeout)
|
||||
template <typename T, std::size_t Size = sizeof(T)>
|
||||
struct atomic_storage
|
||||
{
|
||||
static_assert(sizeof(T) <= 16 && sizeof(T) == alignof(T), "atomic_storage<> error: invalid type");
|
||||
|
||||
/* First part: Non-MSVC intrinsics */
|
||||
|
||||
using type = get_uint_t<sizeof(T)>;
|
||||
|
||||
#ifndef _MSC_VER
|
||||
|
||||
#if defined(__ATOMIC_HLE_ACQUIRE) && defined(__ATOMIC_HLE_RELEASE)
|
||||
@ -270,19 +270,19 @@ struct atomic_storage
|
||||
|
||||
static inline bool compare_exchange(T& dest, T& comp, T exch)
|
||||
{
|
||||
return __atomic_compare_exchange(&dest, &comp, &exch, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
|
||||
return __atomic_compare_exchange(reinterpret_cast<type*>(&dest), reinterpret_cast<type*>(&comp), reinterpret_cast<type*>(&exch), false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
|
||||
}
|
||||
|
||||
static inline bool compare_exchange_hle_acq(T& dest, T& comp, T exch)
|
||||
{
|
||||
static_assert(sizeof(T) == 4 || sizeof(T) == 8);
|
||||
return __atomic_compare_exchange(&dest, &comp, &exch, false, s_hle_ack, s_hle_ack);
|
||||
return __atomic_compare_exchange(reinterpret_cast<type*>(&dest), reinterpret_cast<type*>(&comp), reinterpret_cast<type*>(&exch), false, s_hle_ack, s_hle_ack);
|
||||
}
|
||||
|
||||
static inline T load(const T& dest)
|
||||
{
|
||||
T result;
|
||||
__atomic_load(&dest, &result, __ATOMIC_SEQ_CST);
|
||||
__atomic_load(reinterpret_cast<const type*>(&dest), reinterpret_cast<type*>(&result), __ATOMIC_SEQ_CST);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -293,13 +293,13 @@ struct atomic_storage
|
||||
|
||||
static inline void release(T& dest, T value)
|
||||
{
|
||||
__atomic_store(&dest, &value, __ATOMIC_RELEASE);
|
||||
__atomic_store(reinterpret_cast<type*>(&dest), reinterpret_cast<type*>(&value), __ATOMIC_RELEASE);
|
||||
}
|
||||
|
||||
static inline T exchange(T& dest, T value)
|
||||
{
|
||||
T result;
|
||||
__atomic_exchange(&dest, &value, &result, __ATOMIC_SEQ_CST);
|
||||
__atomic_exchange(reinterpret_cast<type*>(&dest), reinterpret_cast<type*>(&value), reinterpret_cast<type*>(&result), __ATOMIC_SEQ_CST);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -909,6 +909,7 @@ struct atomic_storage<T, 16> : atomic_storage<T, 0>
|
||||
|
||||
static inline T exchange(T& dest, T value)
|
||||
{
|
||||
__atomic_thread_fence(__ATOMIC_ACQ_REL);
|
||||
return std::bit_cast<T>(__sync_lock_test_and_set(reinterpret_cast<u128*>(&dest), std::bit_cast<u128>(value)));
|
||||
}
|
||||
|
||||
@ -929,7 +930,7 @@ struct atomic_storage<T, 16> : atomic_storage<T, 0>
|
||||
};
|
||||
|
||||
// Atomic type with lock-free and standard layout guarantees (and appropriate limitations)
|
||||
template <typename T, std::size_t Align = alignof(T)>
|
||||
template <typename T, std::size_t Align = sizeof(T)>
|
||||
class atomic_t
|
||||
{
|
||||
protected:
|
||||
@ -937,11 +938,22 @@ protected:
|
||||
|
||||
using ptr_rt = std::conditional_t<std::is_pointer_v<type>, ullong, type>;
|
||||
|
||||
static_assert(alignof(type) == sizeof(type), "atomic_t<> error: unexpected alignment, use alignas() if necessary");
|
||||
static_assert((Align & (Align - 1)) == 0, "atomic_t<> error: unexpected Align parameter (not power of 2).");
|
||||
static_assert(Align % sizeof(type) == 0, "atomic_t<> error: invalid type, must be power of 2.");
|
||||
static_assert(sizeof(type) <= 16, "atomic_t<> error: invalid type, too big (max supported size is 16).");
|
||||
static_assert(Align >= sizeof(type), "atomic_t<> error: bad args, specify bigger alignment if necessary.");
|
||||
|
||||
static_assert(std::is_trivially_copyable_v<type>);
|
||||
static_assert(std::is_copy_constructible_v<type>);
|
||||
static_assert(std::is_move_constructible_v<type>);
|
||||
static_assert(std::is_copy_assignable_v<type>);
|
||||
static_assert(std::is_move_assignable_v<type>);
|
||||
|
||||
alignas(Align) type m_data;
|
||||
|
||||
public:
|
||||
static constexpr std::size_t align = Align;
|
||||
|
||||
atomic_t() noexcept = default;
|
||||
|
||||
atomic_t(const atomic_t&) = delete;
|
||||
|
Loading…
Reference in New Issue
Block a user