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:
SciresM 2020-05-11 15:02:10 -07:00 committed by GitHub
parent 17b6bcfd37
commit 3a1ccdd919
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
258 changed files with 723 additions and 804 deletions

View file

@ -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 {

View file

@ -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);
}

View file

@ -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) { /* ... */ }

View file

@ -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;

View file

@ -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 {

View file

@ -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:

View file

@ -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;

View file

@ -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> {

View file

@ -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;

View file

@ -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);

View file

@ -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: