mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2025-11-17 09:31:17 +01:00
kern: exception flags are now atomic.
This is a really weird one, because they didn't actually update the code which updates these flags in asm, these still use ldrb/orr/strb. But every access to these via c++ is now an atomic ldxrb/stxrb loop. Maybe they just forgot to update the asm?
This commit is contained in:
parent
2a44550dbe
commit
ac382f69e7
@ -105,7 +105,7 @@ namespace ams::kern {
|
|||||||
util::Atomic<u8> dpc_flags;
|
util::Atomic<u8> dpc_flags;
|
||||||
u8 current_svc_id;
|
u8 current_svc_id;
|
||||||
u8 reserved_2c;
|
u8 reserved_2c;
|
||||||
u8 exception_flags;
|
util::Atomic<u8> exception_flags;
|
||||||
bool is_pinned;
|
bool is_pinned;
|
||||||
u8 reserved_2f;
|
u8 reserved_2f;
|
||||||
u8 reserved_30[0x10];
|
u8 reserved_30[0x10];
|
||||||
@ -417,17 +417,17 @@ namespace ams::kern {
|
|||||||
private:
|
private:
|
||||||
ALWAYS_INLINE void SetExceptionFlag(ExceptionFlag flag) {
|
ALWAYS_INLINE void SetExceptionFlag(ExceptionFlag flag) {
|
||||||
MESOSPHERE_ASSERT_THIS();
|
MESOSPHERE_ASSERT_THIS();
|
||||||
this->GetStackParameters().exception_flags |= flag;
|
this->GetStackParameters().exception_flags.FetchOr<std::memory_order_relaxed>(flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
ALWAYS_INLINE void ClearExceptionFlag(ExceptionFlag flag) {
|
ALWAYS_INLINE void ClearExceptionFlag(ExceptionFlag flag) {
|
||||||
MESOSPHERE_ASSERT_THIS();
|
MESOSPHERE_ASSERT_THIS();
|
||||||
this->GetStackParameters().exception_flags &= ~flag;
|
this->GetStackParameters().exception_flags.FetchAnd<std::memory_order_relaxed>(~flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
ALWAYS_INLINE bool IsExceptionFlagSet(ExceptionFlag flag) const {
|
ALWAYS_INLINE bool IsExceptionFlagSet(ExceptionFlag flag) const {
|
||||||
MESOSPHERE_ASSERT_THIS();
|
MESOSPHERE_ASSERT_THIS();
|
||||||
return this->GetStackParameters().exception_flags & flag;
|
return this->GetStackParameters().exception_flags.Load<std::memory_order_relaxed>() & flag;
|
||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
/* ALWAYS_INLINE void SetCallingSvc() { return this->SetExceptionFlag(ExceptionFlag_IsCallingSvc); } */
|
/* ALWAYS_INLINE void SetCallingSvc() { return this->SetExceptionFlag(ExceptionFlag_IsCallingSvc); } */
|
||||||
|
|||||||
@ -286,15 +286,15 @@ namespace ams::util {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#define AMS_UTIL_IMPL_DEFINE_ATOMIC_FETCH_OPERATE_FUNCTION(_OPERATION_, _OPERATOR_, _POINTER_ALLOWED_) \
|
#define AMS_UTIL_IMPL_DEFINE_ATOMIC_FETCH_OPERATE_FUNCTION(_OPERATION_, _OPERATOR_, _POINTER_ALLOWED_) \
|
||||||
template<bool Enable = (IsIntegral || (_POINTER_ALLOWED_ && IsPointer)), typename = typename std::enable_if<Enable, void>::type> \
|
template<std::memory_order Order = std::memory_order_seq_cst, bool Enable = (IsIntegral || (_POINTER_ALLOWED_ && IsPointer)), typename = typename std::enable_if<Enable, void>::type> \
|
||||||
ALWAYS_INLINE T Fetch ## _OPERATION_(DifferenceType arg) { \
|
ALWAYS_INLINE T Fetch ## _OPERATION_(DifferenceType arg) { \
|
||||||
static_assert(Enable == (IsIntegral || (_POINTER_ALLOWED_ && IsPointer))); \
|
static_assert(Enable == (IsIntegral || (_POINTER_ALLOWED_ && IsPointer))); \
|
||||||
volatile StorageType * const p = this->GetStoragePointer(); \
|
volatile StorageType * const p = this->GetStoragePointer(); \
|
||||||
\
|
\
|
||||||
StorageType current; \
|
StorageType current; \
|
||||||
do { \
|
do { \
|
||||||
current = impl::LoadAcquireExclusiveForAtomic<StorageType>(p); \
|
current = impl::LoadExclusiveForAtomicByMemoryOrder<Order, StorageType>(p); \
|
||||||
} while (AMS_UNLIKELY(!impl::StoreReleaseExclusiveForAtomic<StorageType>(p, ConvertToStorage(ConvertToType(current) _OPERATOR_ arg)))); \
|
} while (AMS_UNLIKELY((!impl::StoreExclusiveForAtomicByMemoryOrder<Order, StorageType>(p, ConvertToStorage(ConvertToType(current) _OPERATOR_ arg))))); \
|
||||||
return ConvertToType(current); \
|
return ConvertToType(current); \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
@ -390,15 +390,15 @@ namespace ams::util {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#define AMS_UTIL_IMPL_DEFINE_ATOMIC_FETCH_OPERATE_FUNCTION(_OPERATION_, _OPERATOR_, _POINTER_ALLOWED_) \
|
#define AMS_UTIL_IMPL_DEFINE_ATOMIC_FETCH_OPERATE_FUNCTION(_OPERATION_, _OPERATOR_, _POINTER_ALLOWED_) \
|
||||||
template<bool Enable = (IsIntegral || (_POINTER_ALLOWED_ && IsPointer)), typename = typename std::enable_if<Enable, void>::type> \
|
template<std::memory_order Order = std::memory_order_seq_cst, bool Enable = (IsIntegral || (_POINTER_ALLOWED_ && IsPointer)), typename = typename std::enable_if<Enable, void>::type> \
|
||||||
ALWAYS_INLINE T Fetch ## _OPERATION_(DifferenceType arg) const { \
|
ALWAYS_INLINE T Fetch ## _OPERATION_(DifferenceType arg) const { \
|
||||||
static_assert(Enable == (IsIntegral || (_POINTER_ALLOWED_ && IsPointer))); \
|
static_assert(Enable == (IsIntegral || (_POINTER_ALLOWED_ && IsPointer))); \
|
||||||
volatile StorageType * const p = this->GetStoragePointer(); \
|
volatile StorageType * const p = this->GetStoragePointer(); \
|
||||||
\
|
\
|
||||||
StorageType current; \
|
StorageType current; \
|
||||||
do { \
|
do { \
|
||||||
current = impl::LoadAcquireExclusiveForAtomic<StorageType>(p); \
|
current = impl::LoadExclusiveForAtomicByMemoryOrder<Order, StorageType>(p); \
|
||||||
} while (AMS_UNLIKELY(!impl::StoreReleaseExclusiveForAtomic<StorageType>(p, ConvertToStorage(ConvertToType(current) _OPERATOR_ arg)))); \
|
} while (AMS_UNLIKELY((!impl::StoreExclusiveForAtomicByMemoryOrder<Order, StorageType>(p, ConvertToStorage(ConvertToType(current) _OPERATOR_ arg))))); \
|
||||||
return ConvertToType(current); \
|
return ConvertToType(current); \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user