mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2025-06-02 23:59:49 -04:00
Switch atmosphere's build target to C++20. (#952)
* ams: update to build with gcc10/c++20 * remove mno-outline-atomics * ams: take care of most TODO C++20s * fusee/sept: update for gcc10 * whoosh, your code now uses pre-compiled headers * make: dependency fixes
This commit is contained in:
parent
17b6bcfd37
commit
3a1ccdd919
258 changed files with 723 additions and 804 deletions
|
@ -72,7 +72,7 @@ namespace ams::kern::arch::arm64 {
|
|||
SgirTargetListFilter_Reserved = (3 << 24),
|
||||
};
|
||||
};
|
||||
static_assert(std::is_pod<GicDistributor>::value);
|
||||
static_assert(util::is_pod<GicDistributor>::value);
|
||||
static_assert(sizeof(GicDistributor) == 0x1000);
|
||||
|
||||
struct GicCpuInterface {
|
||||
|
@ -98,7 +98,7 @@ namespace ams::kern::arch::arm64 {
|
|||
u32 dir;
|
||||
u32 _0x1004[1023];
|
||||
};
|
||||
static_assert(std::is_pod<GicCpuInterface>::value);
|
||||
static_assert(util::is_pod<GicCpuInterface>::value);
|
||||
static_assert(sizeof(GicCpuInterface) == 0x2000);
|
||||
|
||||
struct KInterruptController {
|
||||
|
@ -164,11 +164,11 @@ namespace ams::kern::arch::arm64 {
|
|||
}
|
||||
|
||||
void SetTarget(s32 irq, s32 core_id) const {
|
||||
this->gicd->itargetsr.bytes[irq] |= GetGicMask(core_id);
|
||||
this->gicd->itargetsr.bytes[irq] = this->gicd->itargetsr.bytes[irq] | GetGicMask(core_id);
|
||||
}
|
||||
|
||||
void ClearTarget(s32 irq, s32 core_id) const {
|
||||
this->gicd->itargetsr.bytes[irq] &= ~GetGicMask(core_id);
|
||||
this->gicd->itargetsr.bytes[irq] = this->gicd->itargetsr.bytes[irq] & ~GetGicMask(core_id);
|
||||
}
|
||||
|
||||
void SetPriorityLevel(s32 irq, s32 level) const {
|
||||
|
|
|
@ -32,7 +32,7 @@ namespace ams::kern::init {
|
|||
u32 init_array_offset;
|
||||
u32 init_array_end_offset;
|
||||
};
|
||||
static_assert(std::is_pod<KernelLayout>::value);
|
||||
static_assert(util::is_pod<KernelLayout>::value);
|
||||
static_assert(sizeof(KernelLayout) == 0x30);
|
||||
|
||||
}
|
|
@ -185,10 +185,7 @@ namespace ams::kern {
|
|||
T *obj;
|
||||
private:
|
||||
constexpr ALWAYS_INLINE void Swap(KScopedAutoObject &rhs) {
|
||||
/* TODO: C++20 constexpr std::swap */
|
||||
T *tmp = rhs.obj;
|
||||
rhs.obj = this->obj;
|
||||
this->obj = tmp;
|
||||
std::swap(this->obj, rhs.obj);
|
||||
}
|
||||
public:
|
||||
constexpr ALWAYS_INLINE KScopedAutoObject() : obj(nullptr) { /* ... */ }
|
||||
|
|
|
@ -64,7 +64,7 @@ namespace ams::kern {
|
|||
|
||||
static constexpr u32 GetCapabilityId(CapabilityType type) {
|
||||
const u32 flag = GetCapabilityFlag(type);
|
||||
if (true /* C++20: std::is_constant_evaluated() */) {
|
||||
if (std::is_constant_evaluated()) {
|
||||
return CountTrailingZero(flag);
|
||||
} else {
|
||||
return static_cast<u32>(__builtin_ctz(flag));
|
||||
|
@ -84,7 +84,7 @@ namespace ams::kern {
|
|||
template<CapabilityType Type>
|
||||
static constexpr inline u32 CapabilityId = []() -> u32 {
|
||||
const u32 flag = static_cast<u32>(Type) + 1;
|
||||
if (true /* C++20: std::is_constant_evaluated() */) {
|
||||
if (std::is_constant_evaluated()) {
|
||||
for (u32 i = 0; i < BITSIZEOF(u32); i++) {
|
||||
if (flag & (1u << i)) {
|
||||
return i;
|
||||
|
|
|
@ -31,8 +31,10 @@ namespace ams::kern {
|
|||
s32 core_id;
|
||||
void *exception_stack_top;
|
||||
};
|
||||
static_assert(std::is_pod<KCurrentContext>::value);
|
||||
static_assert(std::is_standard_layout<KCurrentContext>::value && std::is_trivially_destructible<KCurrentContext>::value);
|
||||
static_assert(sizeof(KCurrentContext) <= cpu::DataCacheLineSize);
|
||||
static_assert(sizeof(std::atomic<KThread *>) == sizeof(KThread *));
|
||||
static_assert(sizeof(std::atomic<KProcess *>) == sizeof(KProcess *));
|
||||
|
||||
namespace impl {
|
||||
|
||||
|
|
|
@ -65,7 +65,7 @@ namespace ams::kern {
|
|||
Node *next;
|
||||
u8 buffer[PageSize - sizeof(Node *)];
|
||||
};
|
||||
static_assert(std::is_pod<Node>::value);
|
||||
static_assert(util::is_pod<Node>::value);
|
||||
private:
|
||||
Node *root;
|
||||
public:
|
||||
|
|
|
@ -18,39 +18,34 @@
|
|||
|
||||
namespace ams::kern {
|
||||
|
||||
/*
|
||||
TODO: C++20
|
||||
template<typename T>
|
||||
concept KPriorityQueueAffinityMask = !std::is_reference<T>::value && requires (T &t) {
|
||||
{ t.GetAffinityMask() } -> std::convertible_to<u64>;
|
||||
{ t.SetAffinityMask(std::declval<u64>()) };
|
||||
|
||||
template<typename T>
|
||||
concept KPriorityQueueAffinityMask = !std::is_reference<T>::value && requires (T &t) {
|
||||
{ t.GetAffinityMask() } -> std::convertible_to<u64>;
|
||||
{ t.SetAffinityMask(std::declval<u64>()) };
|
||||
{ t.GetAffinity(std::declval<int32_t>()) } -> std::same_as<bool>;
|
||||
{ t.SetAffinity(std::declval<int32_t>(), std::declval<bool>()) };
|
||||
{ t.SetAll() };
|
||||
};
|
||||
|
||||
{ t.GetAffinity(std::declval<int32_t>()) } -> std::same_as<bool>;
|
||||
{ t.SetAffinity(std::declval<int32_t>(), std::declval<bool>()) };
|
||||
{ t.SetAll() };
|
||||
};
|
||||
template<typename T>
|
||||
concept KPriorityQueueMember = !std::is_reference<T>::value && requires (T &t) {
|
||||
{ typename T::QueueEntry() };
|
||||
{ (typename T::QueueEntry()).Initialize() };
|
||||
{ (typename T::QueueEntry()).SetPrev(std::addressof(t)) };
|
||||
{ (typename T::QueueEntry()).SetNext(std::addressof(t)) };
|
||||
{ (typename T::QueueEntry()).GetNext() } -> std::same_as<T*>;
|
||||
{ (typename T::QueueEntry()).GetPrev() } -> std::same_as<T*>;
|
||||
{ t.GetPriorityQueueEntry(std::declval<s32>()) } -> std::same_as<typename T::QueueEntry &>;
|
||||
|
||||
template<typename T>
|
||||
concept KPriorityQueueMember = !std::is_reference<T>::value && requires (T &t) {
|
||||
{ typename T::QueueEntry() };
|
||||
{ (typename T::QueueEntry()).Initialize() };
|
||||
{ (typename T::QueueEntry()).SetPrev(std::addressof(t)) };
|
||||
{ (typename T::QueueEntry()).SetNext(std::addressof(t)) };
|
||||
{ (typename T::QueueEntry()).GetNext() } -> std::same_as<T*>;
|
||||
{ (typename T::QueueEntry()).GetPrev() } -> std::same_as<T*>;
|
||||
{ t.GetPriorityQueueEntry(std::declval<s32>()) } -> std::same_as<typename T::QueueEntry &>;
|
||||
{ t.GetAffinityMask() };
|
||||
{ typename std::remove_cvref<decltype(t.GetAffinityMask())>::type() } -> KPriorityQueueAffinityMask;
|
||||
|
||||
{ t.GetAffinityMask() };
|
||||
{ typename std::remove_cvref<decltype(t.GetAffinityMask())>::type() } -> KPriorityQueueAffinityMask;
|
||||
{ t.GetActiveCore() } -> std::convertible_to<s32>;
|
||||
{ t.GetPriority() } -> std::convertible_to<s32>;
|
||||
};
|
||||
|
||||
{ t.GetActiveCore() } -> std::convertible_to<s32>;
|
||||
{ t.GetPriority() } -> std::convertible_to<s32>;
|
||||
};
|
||||
*/
|
||||
|
||||
|
||||
template<typename Member, size_t _NumCores, int LowestPriority, int HighestPriority> /* TODO C++20: requires KPriorityQueueMember<Member> */
|
||||
template<typename Member, size_t _NumCores, int LowestPriority, int HighestPriority> requires KPriorityQueueMember<Member>
|
||||
class KPriorityQueue {
|
||||
public:
|
||||
using AffinityMaskType = typename std::remove_cv<typename std::remove_reference<decltype(std::declval<Member>().GetAffinityMask())>::type>::type;
|
||||
|
|
|
@ -33,8 +33,6 @@ namespace ams::kern {
|
|||
NON_COPYABLE(KScheduler);
|
||||
NON_MOVEABLE(KScheduler);
|
||||
public:
|
||||
using LockType = KAbstractSchedulerLock<KScheduler>;
|
||||
|
||||
static constexpr s32 HighestCoreMigrationAllowedPriority = 2;
|
||||
static_assert(ams::svc::LowestThreadPriority >= HighestCoreMigrationAllowedPriority);
|
||||
static_assert(ams::svc::HighestThreadPriority <= HighestCoreMigrationAllowedPriority);
|
||||
|
@ -50,9 +48,6 @@ namespace ams::kern {
|
|||
private:
|
||||
friend class KScopedSchedulerLock;
|
||||
friend class KScopedSchedulerLockAndSleep;
|
||||
static bool s_scheduler_update_needed;
|
||||
static LockType s_scheduler_lock;
|
||||
static KSchedulerPriorityQueue s_priority_queue;
|
||||
private:
|
||||
SchedulingState state;
|
||||
bool is_active;
|
||||
|
@ -160,6 +155,12 @@ namespace ams::kern {
|
|||
}
|
||||
|
||||
NOINLINE u64 UpdateHighestPriorityThread(KThread *thread);
|
||||
public:
|
||||
using LockType = KAbstractSchedulerLock<KScheduler>;
|
||||
private:
|
||||
static bool s_scheduler_update_needed;
|
||||
static KSchedulerPriorityQueue s_priority_queue;
|
||||
static LockType s_scheduler_lock;
|
||||
};
|
||||
|
||||
class KScopedSchedulerLock : KScopedLock<KScheduler::LockType> {
|
||||
|
|
|
@ -23,19 +23,14 @@ namespace ams::kern {
|
|||
|
||||
class KThread;
|
||||
|
||||
/*
|
||||
TODO: C++20
|
||||
template<typename T>
|
||||
concept KSchedulerLockable = !std::is_reference<T>::value && requires(T) {
|
||||
{ T::DisableScheduling() } -> std::same_as<void>;
|
||||
{ T::EnableScheduling(std::declval<u64>()) } -> std::same_as<void>;
|
||||
{ T::UpdateHighestPriorityThreads() } -> std::convertible_to<u64>;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
concept KSchedulerLockable = !std::is_reference<T>::value && requires {
|
||||
{ T::DisableScheduling() } -> std::same_as<void>;
|
||||
{ T::EnableScheduling(std::declval<u64>()) } -> std::same_as<void>;
|
||||
{ T::UpdateHighestPriorityThreads() } -> std::convertible_to<u64>;
|
||||
};
|
||||
|
||||
*/
|
||||
|
||||
template<typename SchedulerType> /* TODO C++20: requires KSchedulerLockable<SchedulerType> */
|
||||
template<typename SchedulerType> requires KSchedulerLockable<SchedulerType>
|
||||
class KAbstractSchedulerLock {
|
||||
private:
|
||||
KAlignedSpinLock spin_lock;
|
||||
|
|
|
@ -18,18 +18,13 @@
|
|||
|
||||
namespace ams::kern {
|
||||
|
||||
/*
|
||||
TODO: C++20
|
||||
template<typename T>
|
||||
concept KLockable = !std::is_reference<T>::value && requires (T &t) {
|
||||
{ t.Lock() } -> std::same_as<void>;
|
||||
{ t.Unlock() } -> std::same_as<void>;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
concept KLockable = !std::is_reference<T>::value && requires (T &t) {
|
||||
{ t.Lock() } -> std::same_as<void>;
|
||||
{ t.Unlock() } -> std::same_as<void>;
|
||||
};
|
||||
|
||||
*/
|
||||
|
||||
template<typename T> /* TODO C++20: requires KLockable<T> */
|
||||
template<typename T> requires KLockable<T>
|
||||
class KScopedLock {
|
||||
NON_COPYABLE(KScopedLock);
|
||||
NON_MOVEABLE(KScopedLock);
|
||||
|
|
|
@ -22,47 +22,35 @@ namespace ams::kern::svc {
|
|||
|
||||
namespace impl {
|
||||
|
||||
/* TODO: C++20
|
||||
template<typename T>
|
||||
concept Pointer = std::is_pointer<T>::value;
|
||||
|
||||
template<typename T>
|
||||
concept NonConstPointer = Pointer<T> && !std::is_const<typename std::remove_pointer<T>::type>::value;
|
||||
|
||||
template<typename T>
|
||||
concept ConstPointer = Pointer<T> && std::is_const<typename std::remove_pointer<T>::type>::value;
|
||||
|
||||
template<typename T, size_t N>
|
||||
concept AlignedNPointer = Pointer<T> && alignof(typename std::remove_pointer<T>::type) >= N && util::IsAligned(sizeof(typename std::remove_pointer<T>::type), N);
|
||||
|
||||
template<typename T>
|
||||
concept Aligned8Pointer = AlignedNPointer<T, sizeof(u8)>;
|
||||
|
||||
template<typename T>
|
||||
concept Aligned16Pointer = AlignedNPointer<T, sizeof(u16)> && Aligned8<T>;
|
||||
|
||||
template<typename T>
|
||||
concept Aligned32Pointer = AlignedNPointer<T, sizeof(u32)> && Aligned16<T>;
|
||||
|
||||
template<typename T>
|
||||
concept Aligned64Pointer = AlignedNPointer<T, sizeof(u64)> && Aligned32<T>;
|
||||
*/
|
||||
template<typename T>
|
||||
concept Pointer = std::is_pointer<T>::value;
|
||||
|
||||
template<typename T>
|
||||
constexpr inline bool IsPointer = std::is_pointer<T>::value;
|
||||
concept NonConstPointer = Pointer<T> && !std::is_const<typename std::remove_pointer<T>::type>::value;
|
||||
|
||||
template<typename T>
|
||||
constexpr inline bool IsConstPointer = IsPointer<T> && std::is_const<typename std::remove_pointer<T>::type>::value;
|
||||
|
||||
template<typename T>
|
||||
constexpr inline bool IsNonConstPointer = IsPointer<T> && !std::is_const<typename std::remove_pointer<T>::type>::value;
|
||||
concept ConstPointer = Pointer<T> && std::is_const<typename std::remove_pointer<T>::type>::value;
|
||||
|
||||
template<typename T, size_t N>
|
||||
constexpr inline bool IsAlignedNPointer = IsPointer<T> && alignof(typename std::remove_pointer<T>::type) >= N && util::IsAligned(sizeof(typename std::remove_pointer<T>::type), N);
|
||||
concept AlignedNPointer = Pointer<T> && alignof(typename std::remove_pointer<T>::type) >= N && util::IsAligned(sizeof(typename std::remove_pointer<T>::type), N);
|
||||
|
||||
template<typename _T, typename = void> /* requires Aligned8Pointer<_T> */
|
||||
class KUserPointerImplTraits {
|
||||
static_assert(IsAlignedNPointer<_T, sizeof(u8)>);
|
||||
template<typename T>
|
||||
concept Aligned8Pointer = AlignedNPointer<T, sizeof(u8)>;
|
||||
|
||||
template<typename T>
|
||||
concept Aligned16Pointer = AlignedNPointer<T, sizeof(u16)> && Aligned8Pointer<T>;
|
||||
|
||||
template<typename T>
|
||||
concept Aligned32Pointer = AlignedNPointer<T, sizeof(u32)> && Aligned16Pointer<T>;
|
||||
|
||||
template<typename T>
|
||||
concept Aligned64Pointer = AlignedNPointer<T, sizeof(u64)> && Aligned32Pointer<T>;
|
||||
|
||||
template<typename _T>
|
||||
class KUserPointerImplTraits;
|
||||
|
||||
template<typename _T> requires Aligned8Pointer<_T>
|
||||
class KUserPointerImplTraits<_T> {
|
||||
public:
|
||||
using T = typename std::remove_const<typename std::remove_pointer<_T>::type>::type;
|
||||
public:
|
||||
|
@ -77,9 +65,8 @@ namespace ams::kern::svc {
|
|||
}
|
||||
};
|
||||
|
||||
template<typename _T> /* requires Aligned32Pointer<_T> */
|
||||
class KUserPointerImplTraits<_T, typename std::enable_if<IsAlignedNPointer<_T, sizeof(u32)> && !IsAlignedNPointer<_T, sizeof(u64)>>::type> {
|
||||
static_assert(IsAlignedNPointer<_T, sizeof(u32)>);
|
||||
template<typename _T> requires Aligned32Pointer<_T>
|
||||
class KUserPointerImplTraits<_T> {
|
||||
public:
|
||||
using T = typename std::remove_const<typename std::remove_pointer<_T>::type>::type;
|
||||
public:
|
||||
|
@ -94,9 +81,8 @@ namespace ams::kern::svc {
|
|||
}
|
||||
};
|
||||
|
||||
template<typename _T> /* requires Aligned64Pointer<_T> */
|
||||
class KUserPointerImplTraits<_T, typename std::enable_if<IsAlignedNPointer<_T, sizeof(u64)>>::type> {
|
||||
static_assert(IsAlignedNPointer<_T, sizeof(u64)>);
|
||||
template<typename _T> requires Aligned64Pointer<_T>
|
||||
class KUserPointerImplTraits<_T> {
|
||||
public:
|
||||
using T = typename std::remove_const<typename std::remove_pointer<_T>::type>::type;
|
||||
public:
|
||||
|
@ -111,8 +97,11 @@ namespace ams::kern::svc {
|
|||
}
|
||||
};
|
||||
|
||||
template<typename _T> /* requires Aligned8Pointer<_T> */
|
||||
class KUserPointerImpl : impl::KUserPointerTag {
|
||||
template<typename _T>
|
||||
class KUserPointerImpl;
|
||||
|
||||
template<typename _T> requires Aligned8Pointer<_T>
|
||||
class KUserPointerImpl<_T> : impl::KUserPointerTag {
|
||||
private:
|
||||
using Traits = KUserPointerImplTraits<_T>;
|
||||
protected:
|
||||
|
@ -170,11 +159,11 @@ namespace ams::kern::svc {
|
|||
|
||||
}
|
||||
|
||||
template<typename T, typename = void>
|
||||
class KUserPointer;
|
||||
template<typename T>
|
||||
struct KUserPointer;
|
||||
|
||||
template<typename T> /* requires impl::ConstPointer<T> */
|
||||
struct KUserPointer<T, typename std::enable_if<impl::IsConstPointer<T>>::type> : public impl::KUserPointerImpl<T> {
|
||||
template<typename T> requires impl::ConstPointer<T>
|
||||
struct KUserPointer<T> : public impl::KUserPointerImpl<T> {
|
||||
public:
|
||||
static constexpr bool IsInput = true;
|
||||
public:
|
||||
|
@ -186,8 +175,8 @@ namespace ams::kern::svc {
|
|||
using impl::KUserPointerImpl<T>::GetUnsafePointer;
|
||||
};
|
||||
|
||||
template<typename T> /* requires impl::NonConstPointer<T> */
|
||||
struct KUserPointer<T, typename std::enable_if<impl::IsNonConstPointer<T>>::type> : public impl::KUserPointerImpl<T> {
|
||||
template<typename T> requires impl::NonConstPointer<T>
|
||||
struct KUserPointer<T> : public impl::KUserPointerImpl<T> {
|
||||
public:
|
||||
static constexpr bool IsInput = false;
|
||||
public:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue