mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2024-12-22 12:21:18 +00:00
kern: avoid constexpr init for many objects (avoids unnecessary memory clear) (#1668)
This commit is contained in:
parent
20716cb3de
commit
36e4914be8
77 changed files with 489 additions and 339 deletions
|
@ -168,7 +168,8 @@ namespace ams::kern::arch::arm64 {
|
|||
return entry;
|
||||
}
|
||||
public:
|
||||
constexpr KPageTable() : KPageTableBase(), m_manager(), m_ttbr(), m_asid() { /* ... */ }
|
||||
constexpr explicit KPageTable(util::ConstantInitializeTag) : KPageTableBase(util::ConstantInitialize), m_manager(), m_ttbr(), m_asid() { /* ... */ }
|
||||
explicit KPageTable() { /* ... */ }
|
||||
|
||||
static NOINLINE void Initialize(s32 core_id);
|
||||
|
||||
|
|
|
@ -105,7 +105,9 @@ namespace ams::kern::arch::arm64 {
|
|||
return GetL3EntryFromTable(KMemoryLayout::GetLinearVirtualAddress(entry->GetTable()), address);
|
||||
}
|
||||
public:
|
||||
constexpr KPageTableImpl() : m_table(), m_is_kernel(), m_num_entries() { /* ... */ }
|
||||
constexpr explicit KPageTableImpl(util::ConstantInitializeTag) : m_table(), m_is_kernel(), m_num_entries() { /* ... */ }
|
||||
|
||||
explicit KPageTableImpl() { /* ... */ }
|
||||
|
||||
NOINLINE void InitializeForKernel(void *tb, KVirtualAddress start, KVirtualAddress end);
|
||||
NOINLINE void InitializeForProcess(void *tb, KVirtualAddress start, KVirtualAddress end);
|
||||
|
|
|
@ -23,8 +23,6 @@ namespace ams::kern::arch::arm64 {
|
|||
private:
|
||||
KPageTable m_page_table;
|
||||
public:
|
||||
constexpr KProcessPageTable() : m_page_table() { /* ... */ }
|
||||
|
||||
void Activate(u64 id) {
|
||||
/* Activate the page table with the specified contextidr. */
|
||||
m_page_table.Activate(id);
|
||||
|
|
|
@ -25,7 +25,7 @@ namespace ams::kern::arch::arm64 {
|
|||
KPageTable m_page_table;
|
||||
u64 m_ttbr0_identity[cpu::NumCores];
|
||||
public:
|
||||
constexpr KSupervisorPageTable() : m_page_table(), m_ttbr0_identity() { /* ... */ }
|
||||
constexpr KSupervisorPageTable() : m_page_table(util::ConstantInitialize), m_ttbr0_identity() { /* ... */ }
|
||||
|
||||
NOINLINE void Initialize(s32 core_id);
|
||||
|
||||
|
|
|
@ -57,7 +57,8 @@ namespace ams::kern::arch::arm64 {
|
|||
static void RestoreFpuRegisters64(const KThreadContext &);
|
||||
static void RestoreFpuRegisters32(const KThreadContext &);
|
||||
public:
|
||||
constexpr explicit KThreadContext() : m_callee_saved(), m_lr(), m_sp(), m_cpacr(), m_fpcr(), m_fpsr(), m_fpu_registers(), m_locked() { /* ... */ }
|
||||
constexpr explicit KThreadContext(util::ConstantInitializeTag) : m_callee_saved(), m_lr(), m_sp(), m_cpacr(), m_fpcr(), m_fpsr(), m_fpu_registers(), m_locked() { /* ... */ }
|
||||
explicit KThreadContext() { /* ... */ }
|
||||
|
||||
Result Initialize(KVirtualAddress u_pc, KVirtualAddress k_sp, KVirtualAddress u_sp, uintptr_t arg, bool is_user, bool is_64_bit, bool is_main);
|
||||
Result Finalize();
|
||||
|
|
|
@ -61,7 +61,12 @@ namespace ams::kern::board::nintendo::nx {
|
|||
return KPageTable::GetPageTablePhysicalAddress(addr);
|
||||
}
|
||||
public:
|
||||
constexpr KDevicePageTable() : m_tables(), m_table_asids(), m_attached_device(), m_attached_value(), m_detached_value(), m_hs_attached_value(), m_hs_detached_value() { /* ... */ }
|
||||
constexpr KDevicePageTable()
|
||||
: m_tables{Null<KVirtualAddress>, Null<KVirtualAddress>, Null<KVirtualAddress>, Null<KVirtualAddress>},
|
||||
m_table_asids(), m_attached_device(), m_attached_value(), m_detached_value(), m_hs_attached_value(), m_hs_detached_value()
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
Result Initialize(u64 space_address, u64 space_size);
|
||||
void Finalize();
|
||||
|
|
|
@ -25,7 +25,7 @@ namespace ams::kern {
|
|||
private:
|
||||
ThreadTree m_tree;
|
||||
public:
|
||||
constexpr KAddressArbiter() : m_tree() { /* ... */ }
|
||||
constexpr KAddressArbiter() = default;
|
||||
|
||||
Result SignalToAddress(uintptr_t addr, ams::svc::SignalType type, s32 value, s32 count) {
|
||||
switch (type) {
|
||||
|
|
|
@ -121,7 +121,7 @@ namespace ams::kern {
|
|||
public:
|
||||
static KAutoObject *Create(KAutoObject *ptr);
|
||||
public:
|
||||
constexpr ALWAYS_INLINE explicit KAutoObject() : m_next_closed_object(nullptr), m_ref_count(0)
|
||||
constexpr ALWAYS_INLINE explicit KAutoObject(util::ConstantInitializeTag) : m_next_closed_object(nullptr), m_ref_count(0)
|
||||
#if defined(MESOSPHERE_ENABLE_DEVIRTUALIZED_DYNAMIC_CAST)
|
||||
, m_class_token(0)
|
||||
#endif
|
||||
|
@ -129,6 +129,8 @@ namespace ams::kern {
|
|||
MESOSPHERE_ASSERT_THIS();
|
||||
}
|
||||
|
||||
ALWAYS_INLINE explicit KAutoObject() : m_ref_count(0) { MESOSPHERE_ASSERT_THIS(); }
|
||||
|
||||
/* Destroy is responsible for destroying the auto object's resources when ref_count hits zero. */
|
||||
virtual void Destroy() { MESOSPHERE_ASSERT_THIS(); }
|
||||
|
||||
|
@ -208,9 +210,11 @@ namespace ams::kern {
|
|||
|
||||
class KAutoObjectWithListBase : public KAutoObject {
|
||||
private:
|
||||
void *m_alignment_forcer_unused[0]{};
|
||||
void *m_alignment_forcer_unused[0];
|
||||
public:
|
||||
constexpr ALWAYS_INLINE KAutoObjectWithListBase() = default;
|
||||
constexpr ALWAYS_INLINE explicit KAutoObjectWithListBase(util::ConstantInitializeTag) : KAutoObject(util::ConstantInitialize), m_alignment_forcer_unused{} { /* ... */ }
|
||||
|
||||
ALWAYS_INLINE explicit KAutoObjectWithListBase() { /* ... */ }
|
||||
};
|
||||
|
||||
class KAutoObjectWithList : public KAutoObjectWithListBase {
|
||||
|
@ -219,7 +223,8 @@ namespace ams::kern {
|
|||
private:
|
||||
util::IntrusiveRedBlackTreeNode m_list_node;
|
||||
public:
|
||||
constexpr ALWAYS_INLINE KAutoObjectWithList() : m_list_node() { /* ... */ }
|
||||
constexpr ALWAYS_INLINE KAutoObjectWithList(util::ConstantInitializeTag) : KAutoObjectWithListBase(util::ConstantInitialize), m_list_node(util::ConstantInitialize) { /* ... */ }
|
||||
ALWAYS_INLINE explicit KAutoObjectWithList() { /* ... */ }
|
||||
|
||||
static ALWAYS_INLINE int Compare(const KAutoObjectWithList &lhs, const KAutoObjectWithList &rhs) {
|
||||
const u64 lid = lhs.GetId();
|
||||
|
@ -252,7 +257,6 @@ namespace ams::kern {
|
|||
std::swap(m_obj, rhs.m_obj);
|
||||
}
|
||||
public:
|
||||
constexpr ALWAYS_INLINE KScopedAutoObject() : m_obj(nullptr) { /* ... */ }
|
||||
constexpr ALWAYS_INLINE KScopedAutoObject(T *o) : m_obj(o) {
|
||||
if (m_obj != nullptr) {
|
||||
m_obj->Open();
|
||||
|
|
|
@ -171,14 +171,14 @@ namespace ams::kern {
|
|||
CapabilityFlag<CapabilityType::HandleTable> |
|
||||
CapabilityFlag<CapabilityType::DebugFlags>;
|
||||
private:
|
||||
svc::SvcAccessFlagSet m_svc_access_flags{};
|
||||
InterruptFlagSet m_irq_access_flags{};
|
||||
u64 m_core_mask{};
|
||||
u64 m_priority_mask{};
|
||||
util::BitPack32 m_debug_capabilities{0};
|
||||
s32 m_handle_table_size{};
|
||||
util::BitPack32 m_intended_kernel_version{0};
|
||||
u32 m_program_type{};
|
||||
svc::SvcAccessFlagSet m_svc_access_flags;
|
||||
InterruptFlagSet m_irq_access_flags;
|
||||
u64 m_core_mask;
|
||||
u64 m_priority_mask;
|
||||
util::BitPack32 m_debug_capabilities;
|
||||
s32 m_handle_table_size;
|
||||
util::BitPack32 m_intended_kernel_version;
|
||||
u32 m_program_type;
|
||||
private:
|
||||
constexpr bool SetSvcAllowed(u32 id) {
|
||||
if (AMS_LIKELY(id < m_svc_access_flags.GetCount())) {
|
||||
|
@ -213,7 +213,8 @@ namespace ams::kern {
|
|||
Result SetCapabilities(const u32 *caps, s32 num_caps, KProcessPageTable *page_table);
|
||||
Result SetCapabilities(svc::KUserPointer<const u32 *> user_caps, s32 num_caps, KProcessPageTable *page_table);
|
||||
public:
|
||||
constexpr KCapabilities() = default;
|
||||
constexpr explicit KCapabilities(util::ConstantInitializeTag) : m_svc_access_flags{}, m_irq_access_flags{}, m_core_mask{}, m_priority_mask{}, m_debug_capabilities{0}, m_handle_table_size{}, m_intended_kernel_version{}, m_program_type{} { /* ... */ }
|
||||
KCapabilities() { /* ... */ }
|
||||
|
||||
Result Initialize(const u32 *caps, s32 num_caps, KProcessPageTable *page_table);
|
||||
Result Initialize(svc::KUserPointer<const u32 *> user_caps, s32 num_caps, KProcessPageTable *page_table);
|
||||
|
|
|
@ -33,7 +33,9 @@ namespace ams::kern {
|
|||
s32 m_max_sessions;
|
||||
KPort *m_parent;
|
||||
public:
|
||||
constexpr KClientPort() : m_num_sessions(0), m_peak_sessions(0), m_max_sessions(), m_parent() { /* ... */ }
|
||||
constexpr explicit KClientPort(util::ConstantInitializeTag) : KSynchronizationObject(util::ConstantInitialize), m_num_sessions(0), m_peak_sessions(0), m_max_sessions(), m_parent() { /* ... */ }
|
||||
|
||||
explicit KClientPort() { /* ... */ }
|
||||
|
||||
void Initialize(KPort *parent, s32 max_sessions);
|
||||
void OnSessionFinalized();
|
||||
|
|
|
@ -27,7 +27,8 @@ namespace ams::kern {
|
|||
private:
|
||||
KSession *m_parent;
|
||||
public:
|
||||
constexpr KClientSession() : m_parent() { /* ... */ }
|
||||
constexpr explicit KClientSession(util::ConstantInitializeTag) : KAutoObject(util::ConstantInitialize), m_parent() { /* ... */ }
|
||||
explicit KClientSession() { /* ... */ }
|
||||
|
||||
void Initialize(KSession *parent) {
|
||||
/* Set member variables. */
|
||||
|
|
|
@ -26,7 +26,7 @@ namespace ams::kern {
|
|||
private:
|
||||
ThreadTree m_tree;
|
||||
public:
|
||||
constexpr KConditionVariable() : m_tree() { /* ... */ }
|
||||
constexpr KConditionVariable() = default;
|
||||
|
||||
/* Arbitration. */
|
||||
static Result SignalToAddress(KProcessAddress addr);
|
||||
|
|
|
@ -33,7 +33,7 @@ namespace ams::kern {
|
|||
KProcess::State m_old_process_state;
|
||||
bool m_is_attached;
|
||||
public:
|
||||
explicit KDebugBase() : m_event_info_list(), m_process_holder(), m_lock() { /* ... */ }
|
||||
explicit KDebugBase() { /* ... */ }
|
||||
protected:
|
||||
bool Is64Bit() const;
|
||||
public:
|
||||
|
|
|
@ -30,7 +30,7 @@ namespace ams::kern {
|
|||
u64 m_space_size;
|
||||
bool m_is_initialized;
|
||||
public:
|
||||
constexpr KDeviceAddressSpace() : m_lock(), m_table(), m_space_address(), m_space_size(), m_is_initialized() { /* ... */ }
|
||||
explicit KDeviceAddressSpace() : m_is_initialized(false) { /* ... */ }
|
||||
|
||||
Result Initialize(u64 address, u64 size);
|
||||
virtual void Finalize() override;
|
||||
|
|
|
@ -40,7 +40,7 @@ namespace ams::kern {
|
|||
KVirtualAddress m_address;
|
||||
size_t m_size;
|
||||
public:
|
||||
KDynamicPageManager() : m_lock(), m_page_bitmap(), m_used(), m_peak(), m_count(), m_address(), m_size() { /* ... */ }
|
||||
KDynamicPageManager() : m_lock(), m_page_bitmap(), m_used(), m_peak(), m_count(), m_address(Null<KVirtualAddress>), m_size() { /* ... */ }
|
||||
|
||||
Result Initialize(KVirtualAddress memory, size_t sz) {
|
||||
/* We need to have positive size. */
|
||||
|
|
|
@ -32,7 +32,7 @@ namespace ams::kern {
|
|||
util::Atomic<size_t> m_used{0};
|
||||
util::Atomic<size_t> m_peak{0};
|
||||
util::Atomic<size_t> m_count{0};
|
||||
KVirtualAddress m_address{};
|
||||
KVirtualAddress m_address{Null<KVirtualAddress>};
|
||||
size_t m_size{};
|
||||
public:
|
||||
constexpr KDynamicSlabHeap() = default;
|
||||
|
|
|
@ -29,12 +29,15 @@ namespace ams::kern {
|
|||
bool m_initialized;
|
||||
bool m_readable_event_destroyed;
|
||||
public:
|
||||
constexpr KEvent()
|
||||
: m_readable_event(), m_owner(), m_initialized(), m_readable_event_destroyed()
|
||||
constexpr explicit KEvent(util::ConstantInitializeTag)
|
||||
: KAutoObjectWithSlabHeapAndContainer<KEvent, KAutoObjectWithList, true>(util::ConstantInitialize),
|
||||
m_readable_event(util::ConstantInitialize), m_owner(), m_initialized(), m_readable_event_destroyed()
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
explicit KEvent() : m_readable_event(), m_owner(), m_initialized(), m_readable_event_destroyed() { /* ... */ }
|
||||
|
||||
void Initialize();
|
||||
virtual void Finalize() override;
|
||||
|
||||
|
|
|
@ -63,16 +63,16 @@ namespace ams::kern {
|
|||
private:
|
||||
EntryInfo m_entry_infos[MaxTableSize];
|
||||
KAutoObject *m_objects[MaxTableSize];
|
||||
mutable KSpinLock m_lock;
|
||||
s32 m_free_head_index;
|
||||
u16 m_table_size;
|
||||
u16 m_max_count;
|
||||
u16 m_next_linear_id;
|
||||
u16 m_count;
|
||||
mutable KSpinLock m_lock;
|
||||
public:
|
||||
constexpr KHandleTable() :
|
||||
m_entry_infos(), m_objects(), m_free_head_index(-1), m_table_size(0), m_max_count(0), m_next_linear_id(MinLinearId), m_count(0), m_lock()
|
||||
{ MESOSPHERE_ASSERT_THIS(); }
|
||||
constexpr explicit KHandleTable(util::ConstantInitializeTag) : m_entry_infos(), m_objects(), m_lock(), m_free_head_index(-1), m_table_size(), m_max_count(), m_next_linear_id(MinLinearId), m_count() { /* ... */ }
|
||||
|
||||
explicit KHandleTable() : m_free_head_index(-1), m_lock(), m_count() { MESOSPHERE_ASSERT_THIS(); }
|
||||
|
||||
constexpr NOINLINE Result Initialize(s32 size) {
|
||||
MESOSPHERE_ASSERT_THIS();
|
||||
|
|
|
@ -31,7 +31,9 @@ namespace ams::kern {
|
|||
s32 m_core_id;
|
||||
bool m_is_initialized;
|
||||
public:
|
||||
constexpr KInterruptEvent() : m_interrupt_id(-1), m_core_id(-1), m_is_initialized(false) { /* ... */ }
|
||||
constexpr explicit KInterruptEvent(util::ConstantInitializeTag) : KAutoObjectWithSlabHeapAndContainer<KInterruptEvent, KReadableEvent>(util::ConstantInitialize), m_interrupt_id(-1), m_core_id(-1), m_is_initialized(false) { /* ... */ }
|
||||
|
||||
explicit KInterruptEvent() : m_interrupt_id(-1), m_is_initialized(false) { /* ... */ }
|
||||
|
||||
Result Initialize(int32_t interrupt_name, ams::svc::InterruptType type);
|
||||
virtual void Finalize() override;
|
||||
|
|
|
@ -33,7 +33,7 @@ namespace ams::kern {
|
|||
public:
|
||||
static bool IsValidIoPoolType(ams::svc::IoPoolType pool_type);
|
||||
public:
|
||||
explicit KIoPool() : m_lock(), m_io_region_list(), m_is_initialized(false) {
|
||||
explicit KIoPool() : m_is_initialized(false) {
|
||||
/* ... */
|
||||
}
|
||||
|
||||
|
|
|
@ -40,11 +40,7 @@ namespace ams::kern {
|
|||
util::IntrusiveListNode m_process_list_node;
|
||||
util::IntrusiveListNode m_pool_list_node;
|
||||
public:
|
||||
explicit KIoRegion()
|
||||
: m_lock(), m_pool(nullptr), m_is_initialized(false), m_process_list_node(), m_pool_list_node()
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
explicit KIoRegion() : m_pool(nullptr), m_is_initialized(false) { /* ... */ }
|
||||
|
||||
Result Initialize(KIoPool *pool, KPhysicalAddress phys_addr, size_t size, ams::svc::MemoryMapping mapping, ams::svc::MemoryPermission perm);
|
||||
virtual void Finalize() override;
|
||||
|
|
|
@ -26,7 +26,7 @@ namespace ams::kern {
|
|||
private:
|
||||
KLightSession *m_parent;
|
||||
public:
|
||||
constexpr KLightClientSession() : m_parent() { /* ... */ }
|
||||
explicit KLightClientSession() { /* ... */ }
|
||||
|
||||
void Initialize(KLightSession *parent) {
|
||||
/* Set member variables. */
|
||||
|
|
|
@ -26,7 +26,9 @@ namespace ams::kern {
|
|||
private:
|
||||
KThread::WaiterList m_wait_list;
|
||||
public:
|
||||
constexpr ALWAYS_INLINE KLightConditionVariable() : m_wait_list() { /* ... */ }
|
||||
constexpr explicit ALWAYS_INLINE KLightConditionVariable(util::ConstantInitializeTag) : m_wait_list() { /* ... */ }
|
||||
|
||||
explicit ALWAYS_INLINE KLightConditionVariable() { /* ... */ }
|
||||
public:
|
||||
void Wait(KLightLock *lock, s64 timeout = -1ll, bool allow_terminating_thread = true);
|
||||
void Broadcast();
|
||||
|
|
|
@ -25,7 +25,7 @@ namespace ams::kern {
|
|||
private:
|
||||
util::Atomic<uintptr_t> m_tag;
|
||||
public:
|
||||
constexpr KLightLock() : m_tag(0) { /* ... */ }
|
||||
constexpr ALWAYS_INLINE KLightLock() : m_tag(0) { /* ... */ }
|
||||
|
||||
void Lock() {
|
||||
MESOSPHERE_ASSERT_THIS();
|
||||
|
|
|
@ -32,7 +32,7 @@ namespace ams::kern {
|
|||
u64 m_server_thread_id;
|
||||
KThread *m_server_thread;
|
||||
public:
|
||||
constexpr KLightServerSession() : m_parent(), m_request_list(), m_current_request(), m_server_thread_id(), m_server_thread() { /* ... */ }
|
||||
explicit KLightServerSession() : m_current_request(nullptr), m_server_thread_id(std::numeric_limits<u64>::max()), m_server_thread() { /* ... */ }
|
||||
|
||||
void Initialize(KLightSession *parent) {
|
||||
/* Set member variables. */
|
||||
|
|
|
@ -46,11 +46,7 @@ namespace ams::kern {
|
|||
KProcess *m_process;
|
||||
bool m_initialized;
|
||||
public:
|
||||
constexpr KLightSession()
|
||||
: m_server(), m_client(), m_state(State::Invalid), m_port(), m_name(), m_process(), m_initialized()
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
explicit KLightSession() : m_state(State::Invalid), m_process(), m_initialized() { /* ... */ }
|
||||
|
||||
void Initialize(KClientPort *client_port, uintptr_t name);
|
||||
virtual void Finalize() override;
|
||||
|
|
|
@ -349,28 +349,30 @@ namespace ams::kern {
|
|||
};
|
||||
}
|
||||
public:
|
||||
constexpr KMemoryBlock()
|
||||
: m_device_disable_merge_left_count(), m_device_disable_merge_right_count(), m_address(), m_num_pages(), m_memory_state(KMemoryState_None), m_ipc_lock_count(), m_device_use_count(), m_ipc_disable_merge_count(), m_permission(), m_original_permission(), m_attribute(), m_disable_merge_attribute()
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
explicit KMemoryBlock() { /* ... */ }
|
||||
|
||||
constexpr KMemoryBlock(KProcessAddress addr, size_t np, KMemoryState ms, KMemoryPermission p, KMemoryAttribute attr)
|
||||
: m_device_disable_merge_left_count(), m_device_disable_merge_right_count(), m_address(addr), m_num_pages(np), m_memory_state(ms), m_ipc_lock_count(0), m_device_use_count(0), m_ipc_disable_merge_count(), m_permission(p), m_original_permission(KMemoryPermission_None), m_attribute(attr), m_disable_merge_attribute()
|
||||
constexpr KMemoryBlock(util::ConstantInitializeTag, KProcessAddress addr, size_t np, KMemoryState ms, KMemoryPermission p, KMemoryAttribute attr)
|
||||
: util::IntrusiveRedBlackTreeBaseNode<KMemoryBlock>(util::ConstantInitialize), m_device_disable_merge_left_count(),
|
||||
m_device_disable_merge_right_count(), m_address(addr), m_num_pages(np), m_memory_state(ms), m_ipc_lock_count(0),
|
||||
m_device_use_count(0), m_ipc_disable_merge_count(), m_permission(p), m_original_permission(KMemoryPermission_None),
|
||||
m_attribute(attr), m_disable_merge_attribute()
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
constexpr void Initialize(KProcessAddress addr, size_t np, KMemoryState ms, KMemoryPermission p, KMemoryAttribute attr) {
|
||||
MESOSPHERE_ASSERT_THIS();
|
||||
m_address = addr;
|
||||
m_num_pages = np;
|
||||
m_memory_state = ms;
|
||||
m_ipc_lock_count = 0;
|
||||
m_device_use_count = 0;
|
||||
m_permission = p;
|
||||
m_original_permission = KMemoryPermission_None;
|
||||
m_attribute = attr;
|
||||
m_device_disable_merge_left_count = 0;
|
||||
m_device_disable_merge_right_count = 0;
|
||||
m_address = addr;
|
||||
m_num_pages = np;
|
||||
m_memory_state = ms;
|
||||
m_ipc_lock_count = 0;
|
||||
m_device_use_count = 0;
|
||||
m_permission = p;
|
||||
m_original_permission = KMemoryPermission_None;
|
||||
m_attribute = attr;
|
||||
m_disable_merge_attribute = KMemoryBlockDisableMergeAttribute_None;
|
||||
}
|
||||
|
||||
constexpr bool HasProperties(KMemoryState s, KMemoryPermission p, KMemoryAttribute a) const {
|
||||
|
|
|
@ -88,7 +88,9 @@ namespace ams::kern {
|
|||
private:
|
||||
void CoalesceForUpdate(KMemoryBlockManagerUpdateAllocator *allocator, KProcessAddress address, size_t num_pages);
|
||||
public:
|
||||
constexpr KMemoryBlockManager() : m_memory_block_tree(), m_start_address(), m_end_address() { /* ... */ }
|
||||
constexpr explicit KMemoryBlockManager(util::ConstantInitializeTag) : m_memory_block_tree(), m_start_address(Null<KProcessAddress>), m_end_address(Null<KProcessAddress>) { /* ... */ }
|
||||
|
||||
explicit KMemoryBlockManager() { /* ... */ }
|
||||
|
||||
iterator end() { return m_memory_block_tree.end(); }
|
||||
const_iterator end() const { return m_memory_block_tree.end(); }
|
||||
|
@ -105,7 +107,7 @@ namespace ams::kern {
|
|||
void UpdateIfMatch(KMemoryBlockManagerUpdateAllocator *allocator, KProcessAddress address, size_t num_pages, KMemoryState test_state, KMemoryPermission test_perm, KMemoryAttribute test_attr, KMemoryState state, KMemoryPermission perm, KMemoryAttribute attr);
|
||||
|
||||
iterator FindIterator(KProcessAddress address) const {
|
||||
return m_memory_block_tree.find(KMemoryBlock(address, 1, KMemoryState_Free, KMemoryPermission_None, KMemoryAttribute_None));
|
||||
return m_memory_block_tree.find(KMemoryBlock(util::ConstantInitialize, address, 1, KMemoryState_Free, KMemoryPermission_None, KMemoryAttribute_None));
|
||||
}
|
||||
|
||||
const KMemoryBlock *FindBlock(KProcessAddress address) const {
|
||||
|
|
|
@ -54,12 +54,12 @@ namespace ams::kern {
|
|||
|
||||
class KMemoryLayout {
|
||||
private:
|
||||
static /* constinit */ inline uintptr_t s_linear_phys_to_virt_diff;
|
||||
static /* constinit */ inline uintptr_t s_linear_virt_to_phys_diff;
|
||||
static /* constinit */ inline KMemoryRegionTree s_virtual_tree;
|
||||
static /* constinit */ inline KMemoryRegionTree s_physical_tree;
|
||||
static /* constinit */ inline KMemoryRegionTree s_virtual_linear_tree;
|
||||
static /* constinit */ inline KMemoryRegionTree s_physical_linear_tree;
|
||||
static constinit inline uintptr_t s_linear_phys_to_virt_diff;
|
||||
static constinit inline uintptr_t s_linear_virt_to_phys_diff;
|
||||
static constinit inline KMemoryRegionTree s_virtual_tree;
|
||||
static constinit inline KMemoryRegionTree s_physical_tree;
|
||||
static constinit inline KMemoryRegionTree s_virtual_linear_tree;
|
||||
static constinit inline KMemoryRegionTree s_physical_linear_tree;
|
||||
private:
|
||||
template<typename AddressType> requires IsKTypedAddress<AddressType>
|
||||
static ALWAYS_INLINE bool IsTypedAddress(const KMemoryRegion *®ion, AddressType address, KMemoryRegionTree &tree, KMemoryRegionType type) {
|
||||
|
|
|
@ -68,7 +68,7 @@ namespace ams::kern {
|
|||
Impl *m_next;
|
||||
Impl *m_prev;
|
||||
public:
|
||||
Impl() : m_heap(), m_page_reference_counts(), m_management_region(), m_pool(), m_next(), m_prev() { /* ... */ }
|
||||
Impl() : m_heap(), m_page_reference_counts(), m_management_region(Null<KVirtualAddress>), m_pool(), m_next(), m_prev() { /* ... */ }
|
||||
|
||||
size_t Initialize(KPhysicalAddress address, size_t size, KVirtualAddress management, KVirtualAddress management_end, Pool p);
|
||||
|
||||
|
|
|
@ -43,13 +43,14 @@ namespace ams::kern {
|
|||
}
|
||||
}
|
||||
public:
|
||||
constexpr ALWAYS_INLINE KMemoryRegion() : m_address(0), m_pair_address(0), m_last_address(0), m_attributes(0), m_type_id(0) { /* ... */ }
|
||||
constexpr ALWAYS_INLINE KMemoryRegion(uintptr_t a, size_t la, uintptr_t p, u32 r, u32 t) :
|
||||
constexpr ALWAYS_INLINE KMemoryRegion() : util::IntrusiveRedBlackTreeBaseNode<KMemoryRegion>(util::ConstantInitialize), m_address(0), m_pair_address(0), m_last_address(0), m_attributes(0), m_type_id(0) { /* ... */ }
|
||||
|
||||
ALWAYS_INLINE KMemoryRegion(uintptr_t a, size_t la, uintptr_t p, u32 r, u32 t) :
|
||||
m_address(a), m_pair_address(p), m_last_address(la), m_attributes(r), m_type_id(t)
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
constexpr ALWAYS_INLINE KMemoryRegion(uintptr_t a, size_t la, u32 r, u32 t) : KMemoryRegion(a, la, std::numeric_limits<uintptr_t>::max(), r, t) { /* ... */ }
|
||||
ALWAYS_INLINE KMemoryRegion(uintptr_t a, size_t la, u32 r, u32 t) : KMemoryRegion(a, la, std::numeric_limits<uintptr_t>::max(), r, t) { /* ... */ }
|
||||
private:
|
||||
constexpr ALWAYS_INLINE void Reset(uintptr_t a, uintptr_t la, uintptr_t p, u32 r, u32 t) {
|
||||
m_address = a;
|
||||
|
|
|
@ -29,8 +29,6 @@ namespace ams::kern {
|
|||
private:
|
||||
char m_name[NameLengthMax];
|
||||
KAutoObject *m_object;
|
||||
public:
|
||||
constexpr KObjectName() : m_name(), m_object() { /* ... */ }
|
||||
public:
|
||||
static Result NewFromName(KAutoObject *obj, const char *name);
|
||||
static Result Delete(KAutoObject *obj, const char *name);
|
||||
|
|
|
@ -43,7 +43,7 @@ namespace ams::kern {
|
|||
return rnd_bit;
|
||||
}
|
||||
public:
|
||||
RandomBitGenerator() : m_rng(), m_entropy(), m_bits_available() {
|
||||
RandomBitGenerator() : m_entropy(), m_bits_available() {
|
||||
m_rng.Initialize(static_cast<u32>(KSystemControl::GenerateRandomU64()));
|
||||
}
|
||||
|
||||
|
|
|
@ -28,11 +28,11 @@ namespace ams::kern {
|
|||
private:
|
||||
friend class KPageGroup;
|
||||
private:
|
||||
KBlockInfo *m_next{};
|
||||
u32 m_page_index{};
|
||||
u32 m_num_pages{};
|
||||
KBlockInfo *m_next;
|
||||
u32 m_page_index;
|
||||
u32 m_num_pages;
|
||||
public:
|
||||
constexpr KBlockInfo() = default;
|
||||
KBlockInfo() : m_next(nullptr) { /* ... */ }
|
||||
|
||||
constexpr ALWAYS_INLINE void Initialize(KPhysicalAddress addr, size_t np) {
|
||||
MESOSPHERE_ASSERT(util::IsAligned(GetInteger(addr), PageSize));
|
||||
|
|
|
@ -59,7 +59,7 @@ namespace ams::kern {
|
|||
size_t m_block_shift;
|
||||
size_t m_next_block_shift;
|
||||
public:
|
||||
Block() : m_bitmap(), m_heap_address(), m_end_offset(), m_block_shift(), m_next_block_shift() { /* ... */ }
|
||||
Block() : m_bitmap(), m_heap_address(Null<KPhysicalAddress>), m_end_offset(), m_block_shift(), m_next_block_shift() { /* ... */ }
|
||||
|
||||
constexpr size_t GetShift() const { return m_block_shift; }
|
||||
constexpr size_t GetNextShift() const { return m_next_block_shift; }
|
||||
|
@ -134,7 +134,7 @@ namespace ams::kern {
|
|||
|
||||
void FreeBlock(KPhysicalAddress block, s32 index);
|
||||
public:
|
||||
KPageHeap() : m_heap_address(), m_heap_size(), m_initial_used_size(), m_num_blocks(), m_blocks() { /* ... */ }
|
||||
KPageHeap() : m_heap_address(Null<KPhysicalAddress>), m_heap_size(), m_initial_used_size(), m_num_blocks(), m_blocks() { /* ... */ }
|
||||
|
||||
constexpr KPhysicalAddress GetAddress() const { return m_heap_address; }
|
||||
constexpr size_t GetSize() const { return m_heap_size; }
|
||||
|
|
|
@ -144,45 +144,60 @@ namespace ams::kern {
|
|||
PageLinkedList *GetPageList() { return std::addressof(m_ll); }
|
||||
};
|
||||
private:
|
||||
KProcessAddress m_address_space_start{};
|
||||
KProcessAddress m_address_space_end{};
|
||||
KProcessAddress m_heap_region_start{};
|
||||
KProcessAddress m_heap_region_end{};
|
||||
KProcessAddress m_current_heap_end{};
|
||||
KProcessAddress m_alias_region_start{};
|
||||
KProcessAddress m_alias_region_end{};
|
||||
KProcessAddress m_stack_region_start{};
|
||||
KProcessAddress m_stack_region_end{};
|
||||
KProcessAddress m_kernel_map_region_start{};
|
||||
KProcessAddress m_kernel_map_region_end{};
|
||||
KProcessAddress m_alias_code_region_start{};
|
||||
KProcessAddress m_alias_code_region_end{};
|
||||
KProcessAddress m_code_region_start{};
|
||||
KProcessAddress m_code_region_end{};
|
||||
size_t m_max_heap_size{};
|
||||
size_t m_mapped_physical_memory_size{};
|
||||
size_t m_mapped_unsafe_physical_memory{};
|
||||
size_t m_mapped_ipc_server_memory{};
|
||||
mutable KLightLock m_general_lock{};
|
||||
mutable KLightLock m_map_physical_memory_lock{};
|
||||
KLightLock m_device_map_lock{};
|
||||
KPageTableImpl m_impl{};
|
||||
KMemoryBlockManager m_memory_block_manager{};
|
||||
u32 m_allocate_option{};
|
||||
u32 m_address_space_width{};
|
||||
bool m_is_kernel{};
|
||||
bool m_enable_aslr{};
|
||||
bool m_enable_device_address_space_merge{};
|
||||
KMemoryBlockSlabManager *m_memory_block_slab_manager{};
|
||||
KBlockInfoManager *m_block_info_manager{};
|
||||
KResourceLimit *m_resource_limit{};
|
||||
const KMemoryRegion *m_cached_physical_linear_region{};
|
||||
const KMemoryRegion *m_cached_physical_heap_region{};
|
||||
MemoryFillValue m_heap_fill_value{};
|
||||
MemoryFillValue m_ipc_fill_value{};
|
||||
MemoryFillValue m_stack_fill_value{};
|
||||
KProcessAddress m_address_space_start;
|
||||
KProcessAddress m_address_space_end;
|
||||
KProcessAddress m_heap_region_start;
|
||||
KProcessAddress m_heap_region_end;
|
||||
KProcessAddress m_current_heap_end;
|
||||
KProcessAddress m_alias_region_start;
|
||||
KProcessAddress m_alias_region_end;
|
||||
KProcessAddress m_stack_region_start;
|
||||
KProcessAddress m_stack_region_end;
|
||||
KProcessAddress m_kernel_map_region_start;
|
||||
KProcessAddress m_kernel_map_region_end;
|
||||
KProcessAddress m_alias_code_region_start;
|
||||
KProcessAddress m_alias_code_region_end;
|
||||
KProcessAddress m_code_region_start;
|
||||
KProcessAddress m_code_region_end;
|
||||
size_t m_max_heap_size;
|
||||
size_t m_mapped_physical_memory_size;
|
||||
size_t m_mapped_unsafe_physical_memory;
|
||||
size_t m_mapped_ipc_server_memory;
|
||||
mutable KLightLock m_general_lock;
|
||||
mutable KLightLock m_map_physical_memory_lock;
|
||||
KLightLock m_device_map_lock;
|
||||
KPageTableImpl m_impl;
|
||||
KMemoryBlockManager m_memory_block_manager;
|
||||
u32 m_allocate_option;
|
||||
u32 m_address_space_width;
|
||||
bool m_is_kernel;
|
||||
bool m_enable_aslr;
|
||||
bool m_enable_device_address_space_merge;
|
||||
KMemoryBlockSlabManager *m_memory_block_slab_manager;
|
||||
KBlockInfoManager *m_block_info_manager;
|
||||
KResourceLimit *m_resource_limit;
|
||||
const KMemoryRegion *m_cached_physical_linear_region;
|
||||
const KMemoryRegion *m_cached_physical_heap_region;
|
||||
MemoryFillValue m_heap_fill_value;
|
||||
MemoryFillValue m_ipc_fill_value;
|
||||
MemoryFillValue m_stack_fill_value;
|
||||
public:
|
||||
constexpr KPageTableBase() { /* ... */ }
|
||||
constexpr explicit KPageTableBase(util::ConstantInitializeTag)
|
||||
: m_address_space_start(Null<KProcessAddress>), m_address_space_end(Null<KProcessAddress>), m_heap_region_start(Null<KProcessAddress>),
|
||||
m_heap_region_end(Null<KProcessAddress>), m_current_heap_end(Null<KProcessAddress>), m_alias_region_start(Null<KProcessAddress>),
|
||||
m_alias_region_end(Null<KProcessAddress>), m_stack_region_start(Null<KProcessAddress>), m_stack_region_end(Null<KProcessAddress>),
|
||||
m_kernel_map_region_start(Null<KProcessAddress>), m_kernel_map_region_end(Null<KProcessAddress>), m_alias_code_region_start(Null<KProcessAddress>),
|
||||
m_alias_code_region_end(Null<KProcessAddress>), m_code_region_start(Null<KProcessAddress>), m_code_region_end(Null<KProcessAddress>),
|
||||
m_max_heap_size(), m_mapped_physical_memory_size(), m_mapped_unsafe_physical_memory(), m_mapped_ipc_server_memory(), m_general_lock(),
|
||||
m_map_physical_memory_lock(), m_device_map_lock(), m_impl(util::ConstantInitialize), m_memory_block_manager(util::ConstantInitialize),
|
||||
m_allocate_option(), m_address_space_width(), m_is_kernel(), m_enable_aslr(), m_enable_device_address_space_merge(),
|
||||
m_memory_block_slab_manager(), m_block_info_manager(), m_resource_limit(), m_cached_physical_linear_region(), m_cached_physical_heap_region(),
|
||||
m_heap_fill_value(), m_ipc_fill_value(), m_stack_fill_value()
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
explicit KPageTableBase() { /* ... */ }
|
||||
|
||||
NOINLINE Result InitializeForKernel(bool is_64_bit, void *table, KVirtualAddress start, KVirtualAddress end);
|
||||
NOINLINE Result InitializeForProcess(ams::svc::CreateProcessFlag as_type, bool enable_aslr, bool enable_device_address_space_merge, bool from_back, KMemoryManager::Pool pool, void *table, KProcessAddress start, KProcessAddress end, KProcessAddress code_address, size_t code_size, KMemoryBlockSlabManager *mem_block_slab_manager, KBlockInfoManager *block_info_manager, KResourceLimit *resource_limit);
|
||||
|
|
|
@ -27,9 +27,10 @@ namespace ams::kern {
|
|||
private:
|
||||
using BaseHeap = KDynamicResourceManager<impl::PageTablePage, true>;
|
||||
private:
|
||||
KPageTableSlabHeap *m_pt_heap{};
|
||||
KPageTableSlabHeap *m_pt_heap;
|
||||
public:
|
||||
constexpr KPageTableManager() = default;
|
||||
constexpr explicit KPageTableManager(util::ConstantInitializeTag) : m_pt_heap() { /* ... */ }
|
||||
explicit KPageTableManager() { /* ... */ }
|
||||
|
||||
ALWAYS_INLINE void Initialize(KDynamicPageManager *page_allocator, KPageTableSlabHeap *pt_heap) {
|
||||
m_pt_heap = pt_heap;
|
||||
|
|
|
@ -41,7 +41,7 @@ namespace ams::kern {
|
|||
State m_state;
|
||||
bool m_is_light;
|
||||
public:
|
||||
constexpr KPort() : m_server(), m_client(), m_name(), m_state(State::Invalid), m_is_light() { /* ... */ }
|
||||
explicit KPort() : m_state(State::Invalid), m_is_light() { /* ... */ }
|
||||
|
||||
static void PostDestroy(uintptr_t arg) { MESOSPHERE_UNUSED(arg); /* ... */ }
|
||||
|
||||
|
|
|
@ -57,73 +57,73 @@ namespace ams::kern {
|
|||
using TLPTree = util::IntrusiveRedBlackTreeBaseTraits<KThreadLocalPage>::TreeType<KThreadLocalPage>;
|
||||
using TLPIterator = TLPTree::iterator;
|
||||
private:
|
||||
KProcessPageTable m_page_table{};
|
||||
util::Atomic<size_t> m_used_kernel_memory_size{0};
|
||||
TLPTree m_fully_used_tlp_tree{};
|
||||
TLPTree m_partially_used_tlp_tree{};
|
||||
s32 m_ideal_core_id{};
|
||||
void *m_attached_object{};
|
||||
KResourceLimit *m_resource_limit{};
|
||||
KVirtualAddress m_system_resource_address{};
|
||||
size_t m_system_resource_num_pages{};
|
||||
size_t m_memory_release_hint{};
|
||||
State m_state{};
|
||||
KLightLock m_state_lock{};
|
||||
KLightLock m_list_lock{};
|
||||
KConditionVariable m_cond_var{};
|
||||
KAddressArbiter m_address_arbiter{};
|
||||
u64 m_entropy[4]{};
|
||||
bool m_is_signaled{};
|
||||
bool m_is_initialized{};
|
||||
bool m_is_application{};
|
||||
char m_name[13]{};
|
||||
util::Atomic<u16> m_num_running_threads{0};
|
||||
u32 m_flags{};
|
||||
KMemoryManager::Pool m_memory_pool{};
|
||||
s64 m_schedule_count{};
|
||||
KCapabilities m_capabilities{};
|
||||
ams::svc::ProgramId m_program_id{};
|
||||
u64 m_process_id{};
|
||||
s64 m_creation_time{};
|
||||
KProcessAddress m_code_address{};
|
||||
size_t m_code_size{};
|
||||
size_t m_main_thread_stack_size{};
|
||||
size_t m_max_process_memory{};
|
||||
u32 m_version{};
|
||||
KHandleTable m_handle_table{};
|
||||
KProcessAddress m_plr_address{};
|
||||
void *m_plr_heap_address{};
|
||||
KThread *m_exception_thread{};
|
||||
ThreadList m_thread_list{};
|
||||
SharedMemoryInfoList m_shared_memory_list{};
|
||||
IoRegionList m_io_region_list{};
|
||||
bool m_is_suspended{};
|
||||
bool m_is_immortal{};
|
||||
bool m_is_jit_debug{};
|
||||
bool m_is_handle_table_initialized{};
|
||||
ams::svc::DebugEvent m_jit_debug_event_type{};
|
||||
ams::svc::DebugException m_jit_debug_exception_type{};
|
||||
uintptr_t m_jit_debug_params[4]{};
|
||||
u64 m_jit_debug_thread_id{};
|
||||
KWaitObject m_wait_object{};
|
||||
KThread *m_running_threads[cpu::NumCores]{};
|
||||
u64 m_running_thread_idle_counts[cpu::NumCores]{};
|
||||
KThread *m_pinned_threads[cpu::NumCores]{};
|
||||
util::Atomic<s64> m_cpu_time{0};
|
||||
util::Atomic<s64> m_num_process_switches{0};
|
||||
util::Atomic<s64> m_num_thread_switches{0};
|
||||
util::Atomic<s64> m_num_fpu_switches{0};
|
||||
util::Atomic<s64> m_num_supervisor_calls{0};
|
||||
util::Atomic<s64> m_num_ipc_messages{0};
|
||||
util::Atomic<s64> m_num_ipc_replies{0};
|
||||
util::Atomic<s64> m_num_ipc_receives{0};
|
||||
KDynamicPageManager m_dynamic_page_manager{};
|
||||
KMemoryBlockSlabManager m_memory_block_slab_manager{};
|
||||
KBlockInfoManager m_block_info_manager{};
|
||||
KPageTableManager m_page_table_manager{};
|
||||
KMemoryBlockSlabHeap m_memory_block_heap{};
|
||||
KBlockInfoSlabHeap m_block_info_heap{};
|
||||
KPageTableSlabHeap m_page_table_heap{};
|
||||
KProcessPageTable m_page_table;
|
||||
util::Atomic<size_t> m_used_kernel_memory_size;
|
||||
TLPTree m_fully_used_tlp_tree;
|
||||
TLPTree m_partially_used_tlp_tree;
|
||||
s32 m_ideal_core_id;
|
||||
void *m_attached_object;
|
||||
KResourceLimit *m_resource_limit;
|
||||
KVirtualAddress m_system_resource_address;
|
||||
size_t m_system_resource_num_pages;
|
||||
size_t m_memory_release_hint;
|
||||
State m_state;
|
||||
KLightLock m_state_lock;
|
||||
KLightLock m_list_lock;
|
||||
KConditionVariable m_cond_var;
|
||||
KAddressArbiter m_address_arbiter;
|
||||
u64 m_entropy[4];
|
||||
bool m_is_signaled;
|
||||
bool m_is_initialized;
|
||||
bool m_is_application;
|
||||
char m_name[13];
|
||||
util::Atomic<u16> m_num_running_threads;
|
||||
u32 m_flags;
|
||||
KMemoryManager::Pool m_memory_pool;
|
||||
s64 m_schedule_count;
|
||||
KCapabilities m_capabilities;
|
||||
ams::svc::ProgramId m_program_id;
|
||||
u64 m_process_id;
|
||||
s64 m_creation_time;
|
||||
KProcessAddress m_code_address;
|
||||
size_t m_code_size;
|
||||
size_t m_main_thread_stack_size;
|
||||
size_t m_max_process_memory;
|
||||
u32 m_version;
|
||||
KHandleTable m_handle_table;
|
||||
KProcessAddress m_plr_address;
|
||||
void *m_plr_heap_address;
|
||||
KThread *m_exception_thread;
|
||||
ThreadList m_thread_list;
|
||||
SharedMemoryInfoList m_shared_memory_list;
|
||||
IoRegionList m_io_region_list;
|
||||
bool m_is_suspended;
|
||||
bool m_is_immortal;
|
||||
bool m_is_jit_debug;
|
||||
bool m_is_handle_table_initialized;
|
||||
ams::svc::DebugEvent m_jit_debug_event_type;
|
||||
ams::svc::DebugException m_jit_debug_exception_type;
|
||||
uintptr_t m_jit_debug_params[4];
|
||||
u64 m_jit_debug_thread_id;
|
||||
KWaitObject m_wait_object;
|
||||
KThread *m_running_threads[cpu::NumCores];
|
||||
u64 m_running_thread_idle_counts[cpu::NumCores];
|
||||
KThread *m_pinned_threads[cpu::NumCores];
|
||||
util::Atomic<s64> m_cpu_time;
|
||||
util::Atomic<s64> m_num_process_switches;
|
||||
util::Atomic<s64> m_num_thread_switches;
|
||||
util::Atomic<s64> m_num_fpu_switches;
|
||||
util::Atomic<s64> m_num_supervisor_calls;
|
||||
util::Atomic<s64> m_num_ipc_messages;
|
||||
util::Atomic<s64> m_num_ipc_replies;
|
||||
util::Atomic<s64> m_num_ipc_receives;
|
||||
KDynamicPageManager m_dynamic_page_manager;
|
||||
KMemoryBlockSlabManager m_memory_block_slab_manager;
|
||||
KBlockInfoManager m_block_info_manager;
|
||||
KPageTableManager m_page_table_manager;
|
||||
KMemoryBlockSlabHeap m_memory_block_heap;
|
||||
KBlockInfoSlabHeap m_block_info_heap;
|
||||
KPageTableSlabHeap m_page_table_heap;
|
||||
private:
|
||||
Result Initialize(const ams::svc::CreateProcessParameter ¶ms);
|
||||
|
||||
|
@ -145,7 +145,7 @@ namespace ams::kern {
|
|||
m_pinned_threads[core_id] = nullptr;
|
||||
}
|
||||
public:
|
||||
KProcess() { /* ... */ }
|
||||
explicit KProcess() : m_is_initialized(false) { /* ... */ }
|
||||
|
||||
Result Initialize(const ams::svc::CreateProcessParameter ¶ms, const KPageGroup &pg, const u32 *caps, s32 num_caps, KResourceLimit *res_limit, KMemoryManager::Pool pool, bool immortal);
|
||||
Result Initialize(const ams::svc::CreateProcessParameter ¶ms, svc::KUserPointer<const u32 *> caps, s32 num_caps, KResourceLimit *res_limit, KMemoryManager::Pool pool);
|
||||
|
|
|
@ -27,7 +27,9 @@ namespace ams::kern {
|
|||
bool m_is_signaled;
|
||||
KEvent *m_parent;
|
||||
public:
|
||||
constexpr explicit KReadableEvent() : KSynchronizationObject(), m_is_signaled(), m_parent() { MESOSPHERE_ASSERT_THIS(); }
|
||||
constexpr explicit KReadableEvent(util::ConstantInitializeTag) : KSynchronizationObject(util::ConstantInitialize), m_is_signaled(), m_parent() { MESOSPHERE_ASSERT_THIS(); }
|
||||
|
||||
explicit KReadableEvent() { /* ... */ }
|
||||
|
||||
void Initialize(KEvent *parent);
|
||||
|
||||
|
|
|
@ -33,7 +33,15 @@ namespace ams::kern {
|
|||
s32 m_waiter_count;
|
||||
KLightConditionVariable m_cond_var;
|
||||
public:
|
||||
constexpr ALWAYS_INLINE KResourceLimit() : m_limit_values(), m_current_values(), m_current_hints(), m_peak_values(), m_lock(), m_waiter_count(), m_cond_var() { /* ... */ }
|
||||
constexpr explicit ALWAYS_INLINE KResourceLimit(util::ConstantInitializeTag)
|
||||
: KAutoObjectWithSlabHeapAndContainer<KResourceLimit, KAutoObjectWithList>(util::ConstantInitialize),
|
||||
m_limit_values(), m_current_values(), m_current_hints(), m_peak_values(), m_lock(), m_waiter_count(),
|
||||
m_cond_var(util::ConstantInitialize)
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
explicit ALWAYS_INLINE KResourceLimit() { /* ... */ }
|
||||
|
||||
static void PostDestroy(uintptr_t arg) { MESOSPHERE_UNUSED(arg); /* ... */ }
|
||||
|
||||
|
|
|
@ -62,8 +62,7 @@ namespace ams::kern {
|
|||
KThread *m_idle_thread;
|
||||
util::Atomic<KThread *> m_current_thread;
|
||||
public:
|
||||
constexpr KScheduler()
|
||||
: m_state(), m_is_active(false), m_core_id(0), m_last_context_switch_time(0), m_idle_thread(nullptr), m_current_thread(nullptr)
|
||||
constexpr KScheduler() : m_state(), m_is_active(false), m_core_id(0), m_last_context_switch_time(0), m_idle_thread(nullptr), m_current_thread(nullptr)
|
||||
{
|
||||
m_state.needs_scheduling = true;
|
||||
m_state.interrupt_task_runnable = false;
|
||||
|
|
|
@ -34,7 +34,8 @@ namespace ams::kern {
|
|||
LightSessionList m_light_session_list;
|
||||
KPort *m_parent;
|
||||
public:
|
||||
constexpr KServerPort() : m_session_list(), m_light_session_list(), m_parent() { /* ... */ }
|
||||
constexpr explicit KServerPort(util::ConstantInitializeTag) : KSynchronizationObject(util::ConstantInitialize), m_session_list(), m_light_session_list(), m_parent() { /* ... */ }
|
||||
explicit KServerPort() { /* ... */ }
|
||||
|
||||
void Initialize(KPort *parent);
|
||||
void EnqueueSession(KServerSession *session);
|
||||
|
|
|
@ -33,7 +33,8 @@ namespace ams::kern {
|
|||
KSessionRequest *m_current_request;
|
||||
KLightLock m_lock;
|
||||
public:
|
||||
constexpr KServerSession() : m_parent(), m_request_list(), m_current_request(), m_lock() { /* ... */ }
|
||||
constexpr explicit KServerSession(util::ConstantInitializeTag) : KSynchronizationObject(util::ConstantInitialize), m_parent(), m_request_list(), m_current_request(), m_lock() { /* ... */ }
|
||||
explicit KServerSession() : m_current_request(nullptr), m_lock() { /* ... */ }
|
||||
|
||||
virtual void Destroy() override;
|
||||
|
||||
|
|
|
@ -51,12 +51,16 @@ namespace ams::kern {
|
|||
return static_cast<State>(m_atomic_state.Load());
|
||||
}
|
||||
public:
|
||||
constexpr KSession()
|
||||
: m_atomic_state(static_cast<std::underlying_type<State>::type>(State::Invalid)), m_initialized(), m_server(), m_client(), m_port(), m_name(), m_process()
|
||||
constexpr explicit KSession(util::ConstantInitializeTag)
|
||||
: KAutoObjectWithSlabHeapAndContainer<KSession, KAutoObjectWithList, true>(util::ConstantInitialize),
|
||||
m_atomic_state(static_cast<std::underlying_type<State>::type>(State::Invalid)), m_initialized(),
|
||||
m_server(util::ConstantInitialize), m_client(util::ConstantInitialize), m_port(), m_name(), m_process()
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
explicit KSession() : m_atomic_state(util::ToUnderlying(State::Invalid)), m_initialized(false), m_process(nullptr) { /* ... */ }
|
||||
|
||||
void Initialize(KClientPort *client_port, uintptr_t name);
|
||||
virtual void Finalize() override;
|
||||
|
||||
|
|
|
@ -33,14 +33,14 @@ namespace ams::kern {
|
|||
|
||||
class Mapping {
|
||||
private:
|
||||
KProcessAddress m_client_address;
|
||||
KProcessAddress m_server_address;
|
||||
uintptr_t m_client_address;
|
||||
uintptr_t m_server_address;
|
||||
size_t m_size;
|
||||
KMemoryState m_state;
|
||||
public:
|
||||
constexpr void Set(KProcessAddress c, KProcessAddress s, size_t sz, KMemoryState st) {
|
||||
m_client_address = c;
|
||||
m_server_address = s;
|
||||
m_client_address = GetInteger(c);
|
||||
m_server_address = GetInteger(s);
|
||||
m_size = sz;
|
||||
m_state = st;
|
||||
}
|
||||
|
@ -57,7 +57,9 @@ namespace ams::kern {
|
|||
u8 m_num_recv;
|
||||
u8 m_num_exch;
|
||||
public:
|
||||
constexpr explicit SessionMappings() : m_static_mappings(), m_mappings(), m_num_send(), m_num_recv(), m_num_exch() { /* ... */ }
|
||||
constexpr explicit SessionMappings(util::ConstantInitializeTag) : m_static_mappings(), m_mappings(), m_num_send(), m_num_recv(), m_num_exch() { /* ... */ }
|
||||
|
||||
explicit SessionMappings() : m_mappings(nullptr), m_num_send(), m_num_recv(), m_num_exch() { /* ... */ }
|
||||
|
||||
void Initialize() { /* ... */ }
|
||||
void Finalize();
|
||||
|
@ -119,8 +121,6 @@ namespace ams::kern {
|
|||
return m_mappings[index - NumStaticMappings];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
private:
|
||||
SessionMappings m_mappings;
|
||||
|
@ -130,11 +130,13 @@ namespace ams::kern {
|
|||
uintptr_t m_address;
|
||||
size_t m_size;
|
||||
public:
|
||||
constexpr KSessionRequest() : m_mappings(), m_thread(), m_server(), m_event(), m_address(), m_size() { /* ... */ }
|
||||
constexpr explicit KSessionRequest(util::ConstantInitializeTag) : KAutoObject(util::ConstantInitialize), m_mappings(util::ConstantInitialize), m_thread(), m_server(), m_event(), m_address(), m_size() { /* ... */ }
|
||||
|
||||
explicit KSessionRequest() : m_thread(nullptr), m_server(nullptr), m_event(nullptr) { /* ... */ }
|
||||
|
||||
static KSessionRequest *Create() {
|
||||
KSessionRequest *req = KSessionRequest::Allocate();
|
||||
if (req != nullptr) {
|
||||
if (AMS_LIKELY(req != nullptr)) {
|
||||
KAutoObject::Create(req);
|
||||
}
|
||||
return req;
|
||||
|
@ -142,7 +144,7 @@ namespace ams::kern {
|
|||
|
||||
static KSessionRequest *CreateFromUnusedSlabMemory() {
|
||||
KSessionRequest *req = KSessionRequest::AllocateFromUnusedSlabMemory();
|
||||
if (req != nullptr) {
|
||||
if (AMS_LIKELY(req != nullptr)) {
|
||||
KAutoObject::Create(req);
|
||||
}
|
||||
return req;
|
||||
|
|
|
@ -26,7 +26,7 @@ namespace ams::kern {
|
|||
KSharedMemory *m_shared_memory;
|
||||
size_t m_reference_count;
|
||||
public:
|
||||
constexpr KSharedMemoryInfo() : m_shared_memory(), m_reference_count() { /* ... */ }
|
||||
explicit KSharedMemoryInfo() { /* ... */ }
|
||||
~KSharedMemoryInfo() { /* ... */ }
|
||||
|
||||
constexpr void Initialize(KSharedMemory *m) {
|
||||
|
|
|
@ -32,7 +32,8 @@ namespace ams::kern {
|
|||
ThreadListNode *m_thread_list_head;
|
||||
ThreadListNode *m_thread_list_tail;
|
||||
protected:
|
||||
constexpr ALWAYS_INLINE explicit KSynchronizationObject() : KAutoObjectWithList(), m_thread_list_head(), m_thread_list_tail() { MESOSPHERE_ASSERT_THIS(); }
|
||||
constexpr ALWAYS_INLINE explicit KSynchronizationObject(util::ConstantInitializeTag) : KAutoObjectWithList(util::ConstantInitialize), m_thread_list_head(), m_thread_list_tail() { MESOSPHERE_ASSERT_THIS(); }
|
||||
ALWAYS_INLINE explicit KSynchronizationObject() : m_thread_list_head(), m_thread_list_tail() { MESOSPHERE_ASSERT_THIS(); }
|
||||
|
||||
virtual void OnFinalizeSynchronizationObject() { MESOSPHERE_ASSERT_THIS(); }
|
||||
|
||||
|
|
|
@ -120,8 +120,6 @@ namespace ams::kern {
|
|||
KThread *m_prev;
|
||||
KThread *m_next;
|
||||
public:
|
||||
constexpr QueueEntry() : m_prev(nullptr), m_next(nullptr) { /* ... */ }
|
||||
|
||||
constexpr void Initialize() {
|
||||
m_prev = nullptr;
|
||||
m_next = nullptr;
|
||||
|
@ -140,7 +138,9 @@ namespace ams::kern {
|
|||
KSynchronizationObject *m_sync_objects[ams::svc::ArgumentHandleCountMax];
|
||||
ams::svc::Handle m_handles[ams::svc::ArgumentHandleCountMax * (sizeof(KSynchronizationObject *) / sizeof(ams::svc::Handle))];
|
||||
|
||||
constexpr SyncObjectBuffer() : m_sync_objects() { /* ... */ }
|
||||
constexpr explicit SyncObjectBuffer(util::ConstantInitializeTag) : m_sync_objects() { /* ... */ }
|
||||
|
||||
explicit SyncObjectBuffer() { /* ... */ }
|
||||
};
|
||||
static_assert(sizeof(SyncObjectBuffer::m_sync_objects) == sizeof(SyncObjectBuffer::m_handles));
|
||||
|
||||
|
@ -177,64 +177,79 @@ namespace ams::kern {
|
|||
static_assert(ams::util::HasRedBlackKeyType<ConditionVariableComparator>);
|
||||
static_assert(std::same_as<ams::util::RedBlackKeyType<ConditionVariableComparator, void>, ConditionVariableComparator::RedBlackKeyType>);
|
||||
private:
|
||||
util::IntrusiveListNode m_process_list_node{};
|
||||
util::IntrusiveRedBlackTreeNode m_condvar_arbiter_tree_node{};
|
||||
s32 m_priority{};
|
||||
util::IntrusiveListNode m_process_list_node;
|
||||
util::IntrusiveRedBlackTreeNode m_condvar_arbiter_tree_node;
|
||||
s32 m_priority;
|
||||
|
||||
using ConditionVariableThreadTreeTraits = util::IntrusiveRedBlackTreeMemberTraitsDeferredAssert<&KThread::m_condvar_arbiter_tree_node>;
|
||||
using ConditionVariableThreadTree = ConditionVariableThreadTreeTraits::TreeType<ConditionVariableComparator>;
|
||||
|
||||
ConditionVariableThreadTree *m_condvar_tree{};
|
||||
uintptr_t m_condvar_key{};
|
||||
alignas(16) KThreadContext m_thread_context{};
|
||||
u64 m_virtual_affinity_mask{};
|
||||
KAffinityMask m_physical_affinity_mask{};
|
||||
u64 m_thread_id{};
|
||||
util::Atomic<s64> m_cpu_time{0};
|
||||
KProcessAddress m_address_key{};
|
||||
KProcess *m_parent{};
|
||||
void *m_kernel_stack_top{};
|
||||
u32 *m_light_ipc_data{};
|
||||
KProcessAddress m_tls_address{};
|
||||
void *m_tls_heap_address{};
|
||||
KLightLock m_activity_pause_lock{};
|
||||
SyncObjectBuffer m_sync_object_buffer{};
|
||||
s64 m_schedule_count{};
|
||||
s64 m_last_scheduled_tick{};
|
||||
QueueEntry m_per_core_priority_queue_entry[cpu::NumCores]{};
|
||||
KThreadQueue *m_wait_queue{};
|
||||
WaiterList m_waiter_list{};
|
||||
WaiterList m_pinned_waiter_list{};
|
||||
KThread *m_lock_owner{};
|
||||
uintptr_t m_debug_params[3]{};
|
||||
KAutoObject *m_closed_object{};
|
||||
u32 m_address_key_value{};
|
||||
u32 m_suspend_request_flags{};
|
||||
u32 m_suspend_allowed_flags{};
|
||||
s32 m_synced_index{};
|
||||
ConditionVariableThreadTree *m_condvar_tree;
|
||||
uintptr_t m_condvar_key;
|
||||
alignas(16) KThreadContext m_thread_context;
|
||||
u64 m_virtual_affinity_mask;
|
||||
KAffinityMask m_physical_affinity_mask;
|
||||
u64 m_thread_id;
|
||||
util::Atomic<s64> m_cpu_time;
|
||||
KProcessAddress m_address_key;
|
||||
KProcess *m_parent;
|
||||
void *m_kernel_stack_top;
|
||||
u32 *m_light_ipc_data;
|
||||
KProcessAddress m_tls_address;
|
||||
void *m_tls_heap_address;
|
||||
KLightLock m_activity_pause_lock;
|
||||
SyncObjectBuffer m_sync_object_buffer;
|
||||
s64 m_schedule_count;
|
||||
s64 m_last_scheduled_tick;
|
||||
QueueEntry m_per_core_priority_queue_entry[cpu::NumCores];
|
||||
KThreadQueue *m_wait_queue;
|
||||
WaiterList m_waiter_list;
|
||||
WaiterList m_pinned_waiter_list;
|
||||
KThread *m_lock_owner;
|
||||
uintptr_t m_debug_params[3];
|
||||
KAutoObject *m_closed_object;
|
||||
u32 m_address_key_value;
|
||||
u32 m_suspend_request_flags;
|
||||
u32 m_suspend_allowed_flags;
|
||||
s32 m_synced_index;
|
||||
Result m_wait_result;
|
||||
Result m_debug_exception_result;
|
||||
s32 m_base_priority{};
|
||||
s32 m_base_priority_on_unpin{};
|
||||
s32 m_physical_ideal_core_id{};
|
||||
s32 m_virtual_ideal_core_id{};
|
||||
s32 m_num_kernel_waiters{};
|
||||
s32 m_current_core_id{};
|
||||
s32 m_core_id{};
|
||||
KAffinityMask m_original_physical_affinity_mask{};
|
||||
s32 m_original_physical_ideal_core_id{};
|
||||
s32 m_num_core_migration_disables{};
|
||||
ThreadState m_thread_state{};
|
||||
util::Atomic<bool> m_termination_requested{false};
|
||||
bool m_wait_cancelled{};
|
||||
bool m_cancellable{};
|
||||
bool m_signaled{};
|
||||
bool m_initialized{};
|
||||
bool m_debug_attached{};
|
||||
s8 m_priority_inheritance_count{};
|
||||
bool m_resource_limit_release_hint{};
|
||||
s32 m_base_priority;
|
||||
s32 m_base_priority_on_unpin;
|
||||
s32 m_physical_ideal_core_id;
|
||||
s32 m_virtual_ideal_core_id;
|
||||
s32 m_num_kernel_waiters;
|
||||
s32 m_current_core_id;
|
||||
s32 m_core_id;
|
||||
KAffinityMask m_original_physical_affinity_mask;
|
||||
s32 m_original_physical_ideal_core_id;
|
||||
s32 m_num_core_migration_disables;
|
||||
ThreadState m_thread_state;
|
||||
util::Atomic<bool> m_termination_requested;
|
||||
bool m_wait_cancelled;
|
||||
bool m_cancellable;
|
||||
bool m_signaled;
|
||||
bool m_initialized;
|
||||
bool m_debug_attached;
|
||||
s8 m_priority_inheritance_count;
|
||||
bool m_resource_limit_release_hint;
|
||||
public:
|
||||
constexpr KThread() : m_wait_result(svc::ResultNoSynchronizationObject()), m_debug_exception_result(ResultSuccess()) { /* ... */ }
|
||||
constexpr explicit KThread(util::ConstantInitializeTag)
|
||||
: KAutoObjectWithSlabHeapAndContainer<KThread, KSynchronizationObject>(util::ConstantInitialize), KTimerTask(util::ConstantInitialize),
|
||||
m_process_list_node{}, m_condvar_arbiter_tree_node{util::ConstantInitialize}, m_priority{-1}, m_condvar_tree{}, m_condvar_key{},
|
||||
m_thread_context{util::ConstantInitialize}, m_virtual_affinity_mask{}, m_physical_affinity_mask{}, m_thread_id{}, m_cpu_time{0}, m_address_key{Null<KProcessAddress>}, m_parent{},
|
||||
m_kernel_stack_top{}, m_light_ipc_data{}, m_tls_address{Null<KProcessAddress>}, m_tls_heap_address{}, m_activity_pause_lock{}, m_sync_object_buffer{util::ConstantInitialize},
|
||||
m_schedule_count{}, m_last_scheduled_tick{}, m_per_core_priority_queue_entry{}, m_wait_queue{}, m_waiter_list{}, m_pinned_waiter_list{},
|
||||
m_lock_owner{}, m_debug_params{}, m_closed_object{}, m_address_key_value{}, m_suspend_request_flags{}, m_suspend_allowed_flags{}, m_synced_index{},
|
||||
m_wait_result{svc::ResultNoSynchronizationObject()}, m_debug_exception_result{ResultSuccess()}, m_base_priority{}, m_base_priority_on_unpin{},
|
||||
m_physical_ideal_core_id{}, m_virtual_ideal_core_id{}, m_num_kernel_waiters{}, m_current_core_id{}, m_core_id{}, m_original_physical_affinity_mask{},
|
||||
m_original_physical_ideal_core_id{}, m_num_core_migration_disables{}, m_thread_state{}, m_termination_requested{false}, m_wait_cancelled{},
|
||||
m_cancellable{}, m_signaled{}, m_initialized{}, m_debug_attached{}, m_priority_inheritance_count{}, m_resource_limit_release_hint{}
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
explicit KThread() : m_priority(-1), m_condvar_tree(nullptr), m_condvar_key(0), m_parent(nullptr), m_initialized(false) { /* ... */ }
|
||||
|
||||
Result Initialize(KThreadFunction func, uintptr_t arg, void *kern_stack_top, KProcessAddress user_stack_top, s32 prio, s32 virt_core, KProcess *owner, ThreadType type);
|
||||
private:
|
||||
|
|
|
@ -33,13 +33,13 @@ namespace ams::kern {
|
|||
KProcess *m_owner;
|
||||
bool m_is_region_free[RegionsPerPage];
|
||||
public:
|
||||
constexpr explicit KThreadLocalPage(KProcessAddress addr) : m_virt_addr(addr), m_owner(nullptr), m_is_region_free() {
|
||||
for (size_t i = 0; i < RegionsPerPage; i++) {
|
||||
explicit KThreadLocalPage(KProcessAddress addr) : m_virt_addr(addr), m_owner(nullptr) {
|
||||
for (size_t i = 0; i < util::size(m_is_region_free); i++) {
|
||||
m_is_region_free[i] = true;
|
||||
}
|
||||
}
|
||||
|
||||
constexpr explicit KThreadLocalPage() : KThreadLocalPage(Null<KProcessAddress>) { /* ... */ }
|
||||
explicit KThreadLocalPage() : KThreadLocalPage(Null<KProcessAddress>) { /* ... */ }
|
||||
|
||||
constexpr ALWAYS_INLINE KProcessAddress GetAddress() const { return m_virt_addr; }
|
||||
|
||||
|
|
|
@ -30,7 +30,8 @@ namespace ams::kern {
|
|||
}
|
||||
}
|
||||
public:
|
||||
constexpr ALWAYS_INLINE KTimerTask() : m_time(0) { /* ... */ }
|
||||
constexpr explicit ALWAYS_INLINE KTimerTask(util::ConstantInitializeTag) : util::IntrusiveRedBlackTreeBaseNode<KTimerTask>(util::ConstantInitialize), m_time(0) { /* ... */ }
|
||||
explicit ALWAYS_INLINE KTimerTask() : m_time(0) { /* ... */ }
|
||||
|
||||
constexpr ALWAYS_INLINE void SetTime(s64 t) {
|
||||
m_time = t;
|
||||
|
|
|
@ -26,7 +26,7 @@ namespace ams::kern {
|
|||
uintptr_t m_address;
|
||||
public:
|
||||
/* Constructors. */
|
||||
constexpr ALWAYS_INLINE KTypedAddress() : m_address(0) { /* ... */ }
|
||||
ALWAYS_INLINE KTypedAddress() { /* ... */ }
|
||||
constexpr ALWAYS_INLINE KTypedAddress(uintptr_t a) : m_address(a) { /* ... */ }
|
||||
template<typename U>
|
||||
constexpr ALWAYS_INLINE explicit KTypedAddress(U *ptr) : m_address(reinterpret_cast<uintptr_t>(ptr)) { /* ... */ }
|
||||
|
@ -146,13 +146,13 @@ namespace ams::kern {
|
|||
}
|
||||
|
||||
template<typename T, typename U>
|
||||
constexpr ALWAYS_INLINE T *GetPointer(KTypedAddress<true, U> address) {
|
||||
return CONST_FOLD(reinterpret_cast<T *>(address.GetValue()));
|
||||
ALWAYS_INLINE T *GetPointer(KTypedAddress<true, U> address) {
|
||||
return reinterpret_cast<T *>(address.GetValue());
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
constexpr ALWAYS_INLINE void *GetVoidPointer(KTypedAddress<true, T> address) {
|
||||
return CONST_FOLD(reinterpret_cast<void *>(address.GetValue()));
|
||||
ALWAYS_INLINE void *GetVoidPointer(KTypedAddress<true, T> address) {
|
||||
return reinterpret_cast<void *>(address.GetValue());
|
||||
}
|
||||
|
||||
#else
|
||||
|
@ -170,12 +170,12 @@ namespace ams::kern {
|
|||
|
||||
template<typename T>
|
||||
constexpr ALWAYS_INLINE T *GetPointer(uintptr_t address) {
|
||||
return CONST_FOLD(reinterpret_cast<T *>(address));
|
||||
return reinterpret_cast<T *>(address);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
constexpr ALWAYS_INLINE void *GetVoidPointer(uintptr_t address) {
|
||||
return CONST_FOLD(reinterpret_cast<void *>(address));
|
||||
return reinterpret_cast<void *>(address);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -85,7 +85,9 @@ namespace ams::kern {
|
|||
ALWAYS_INLINE ~ListAccessor() { /* ... */ }
|
||||
};
|
||||
public:
|
||||
constexpr KAutoObjectWithSlabHeapAndContainer() = default;
|
||||
constexpr explicit KAutoObjectWithSlabHeapAndContainer(util::ConstantInitializeTag) : Base(util::ConstantInitialize) { /* ... */ }
|
||||
|
||||
explicit KAutoObjectWithSlabHeapAndContainer() { /* ... */ }
|
||||
|
||||
virtual void Destroy() override {
|
||||
const bool is_initialized = this->IsInitialized();
|
||||
|
|
|
@ -129,7 +129,7 @@ namespace ams::kern::arch::arm64::cpu {
|
|||
|
||||
void ProcessOperation();
|
||||
public:
|
||||
constexpr KCacheHelperInterruptHandler() : KInterruptHandler(), m_lock(), m_cv_lock(), m_cv(), m_target_cores(0), m_operation(Operation::Idle) { /* ... */ }
|
||||
constexpr KCacheHelperInterruptHandler() : KInterruptHandler(), m_lock(), m_cv_lock(), m_cv(util::ConstantInitialize), m_target_cores(0), m_operation(Operation::Idle) { /* ... */ }
|
||||
|
||||
void Initialize(s32 core_id) {
|
||||
/* Reserve a thread from the system limit. */
|
||||
|
|
|
@ -283,9 +283,6 @@ namespace ams::kern::arch::arm64 {
|
|||
/* Check that the name is a valid instruction breakpoint. */
|
||||
R_UNLESS((name - ams::svc::HardwareBreakPointRegisterName_I0) <= num_bp, svc::ResultNotSupported());
|
||||
|
||||
/* We may be getting the process, so prepare a scoped reference holder. */
|
||||
KScopedAutoObject<KProcess> process;
|
||||
|
||||
/* Configure flags/value. */
|
||||
if ((flags & 1) != 0) {
|
||||
/* We're enabling the breakpoint. Check that the flags are allowable. */
|
||||
|
|
|
@ -233,7 +233,7 @@ namespace ams::kern::arch::arm64 {
|
|||
|
||||
/* Begin the traversal. */
|
||||
TraversalContext context;
|
||||
TraversalEntry cur_entry = {};
|
||||
TraversalEntry cur_entry = { .phys_addr = Null<KPhysicalAddress>, .block_size = 0, .sw_reserved_bits = 0 };
|
||||
bool cur_valid = false;
|
||||
TraversalEntry next_entry;
|
||||
bool next_valid;
|
||||
|
|
|
@ -345,8 +345,8 @@ namespace ams::kern::board::nintendo::nx {
|
|||
/* Globals. */
|
||||
constinit KLightLock g_lock;
|
||||
constinit u8 g_reserved_asid;
|
||||
constinit KPhysicalAddress g_memory_controller_address;
|
||||
constinit KPhysicalAddress g_reserved_table_phys_addr;
|
||||
constinit KPhysicalAddress g_memory_controller_address{Null<KPhysicalAddress>};
|
||||
constinit KPhysicalAddress g_reserved_table_phys_addr{Null<KPhysicalAddress>};
|
||||
constinit KDeviceAsidManager g_asid_manager;
|
||||
constinit u32 g_saved_page_tables[AsidCount];
|
||||
constinit u32 g_saved_asid_registers[ams::svc::DeviceName_Count];
|
||||
|
|
|
@ -66,7 +66,7 @@ namespace ams::kern::board::nintendo::nx {
|
|||
constinit u64 g_sleep_target_cores;
|
||||
constinit KLightLock g_request_lock;
|
||||
constinit KLightLock g_cv_lock;
|
||||
constinit KLightConditionVariable g_cv;
|
||||
constinit KLightConditionVariable g_cv{util::ConstantInitialize};
|
||||
constinit KPhysicalAddress g_sleep_buffer_phys_addrs[cpu::NumCores];
|
||||
alignas(1_KB) constinit u64 g_sleep_buffers[cpu::NumCores][1_KB / sizeof(u64)];
|
||||
constinit SavedSystemRegisters g_sleep_system_registers[cpu::NumCores] = {};
|
||||
|
|
|
@ -43,7 +43,7 @@ namespace ams::kern::board::nintendo::nx {
|
|||
/* To save space (and because mt19337_t isn't secure anyway), */
|
||||
/* We will use TinyMT. */
|
||||
constinit bool g_initialized_random_generator;
|
||||
constinit util::TinyMT g_random_generator;
|
||||
constinit util::TinyMT g_random_generator{util::ConstantInitialize};
|
||||
constinit KSpinLock g_random_lock;
|
||||
|
||||
ALWAYS_INLINE size_t GetRealMemorySizeForInit() {
|
||||
|
|
|
@ -19,7 +19,12 @@ namespace ams::kern {
|
|||
|
||||
Result KCapabilities::Initialize(const u32 *caps, s32 num_caps, KProcessPageTable *page_table) {
|
||||
/* We're initializing an initial process. */
|
||||
/* Most fields have already been cleared by our constructor. */
|
||||
m_svc_access_flags.Reset();
|
||||
m_irq_access_flags.Reset();
|
||||
m_debug_capabilities = {0};
|
||||
m_handle_table_size = 0;
|
||||
m_intended_kernel_version = {0};
|
||||
m_program_type = 0;
|
||||
|
||||
/* Initial processes may run on all cores. */
|
||||
m_core_mask = cpu::VirtualCoreMask;
|
||||
|
@ -38,7 +43,16 @@ namespace ams::kern {
|
|||
|
||||
Result KCapabilities::Initialize(svc::KUserPointer<const u32 *> user_caps, s32 num_caps, KProcessPageTable *page_table) {
|
||||
/* We're initializing a user process. */
|
||||
/* Most fields have already been cleared by our constructor. */
|
||||
m_svc_access_flags.Reset();
|
||||
m_irq_access_flags.Reset();
|
||||
m_debug_capabilities = {0};
|
||||
m_handle_table_size = 0;
|
||||
m_intended_kernel_version = {0};
|
||||
m_program_type = 0;
|
||||
|
||||
/* User processes must specify what cores/priorities they can use. */
|
||||
m_core_mask = 0;
|
||||
m_priority_mask = 0;
|
||||
|
||||
/* Parse the user capabilities array. */
|
||||
return this->SetCapabilities(user_caps, num_caps, page_table);
|
||||
|
|
|
@ -23,7 +23,7 @@ namespace ams::kern {
|
|||
private:
|
||||
static constinit inline KLightLock s_req_lock;
|
||||
static constinit inline KLightLock s_lock;
|
||||
static constinit inline KLightConditionVariable s_cond_var;
|
||||
static constinit inline KLightConditionVariable s_cond_var{util::ConstantInitialize};
|
||||
static constinit inline u64 s_core_mask;
|
||||
static constinit inline KDpcTask *s_task;
|
||||
private:
|
||||
|
|
|
@ -195,9 +195,11 @@ namespace ams::kern::KDumpObject {
|
|||
char name[9] = {};
|
||||
{
|
||||
/* Find the client port process. */
|
||||
KScopedAutoObject<KProcess> client_port_process;
|
||||
KProcess *client_port_process = nullptr;
|
||||
ON_SCOPE_EXIT { if (client_port_process != nullptr) { client_port_process->Close(); } };
|
||||
|
||||
{
|
||||
for (auto it = accessor.begin(); it != end && client_port_process.IsNull(); ++it) {
|
||||
for (auto it = accessor.begin(); it != end && client_port_process == nullptr; ++it) {
|
||||
KProcess *cur = static_cast<KProcess *>(std::addressof(*it));
|
||||
for (size_t j = 0; j < cur->GetHandleTable().GetTableSize(); ++j) {
|
||||
ams::svc::Handle cur_h = ams::svc::InvalidHandle;
|
||||
|
@ -205,6 +207,7 @@ namespace ams::kern::KDumpObject {
|
|||
if (cur_o.IsNotNull()) {
|
||||
if (cur_o.GetPointerUnsafe() == client) {
|
||||
client_port_process = cur;
|
||||
client_port_process->Open();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -213,7 +216,7 @@ namespace ams::kern::KDumpObject {
|
|||
}
|
||||
|
||||
/* Read the port name. */
|
||||
if (client_port_process.IsNotNull()) {
|
||||
if (client_port_process != nullptr) {
|
||||
if (R_FAILED(client_port_process->GetPageTable().CopyMemoryFromLinearToKernel(KProcessAddress(name), 8, port_name, KMemoryState_None, KMemoryState_None, KMemoryPermission_UserRead, KMemoryAttribute_None, KMemoryAttribute_None))) {
|
||||
std::memset(name, 0, sizeof(name));
|
||||
}
|
||||
|
|
|
@ -26,8 +26,8 @@ namespace ams::kern {
|
|||
|
||||
/* Set our members. */
|
||||
m_heap_address = address;
|
||||
m_heap_size = size;
|
||||
m_num_blocks = num_block_shifts;
|
||||
m_heap_size = size;
|
||||
m_num_blocks = num_block_shifts;
|
||||
|
||||
/* Setup bitmaps. */
|
||||
u64 *cur_bitmap_storage = GetPointer<u64>(management_address);
|
||||
|
|
|
@ -706,7 +706,7 @@ namespace ams::kern {
|
|||
|
||||
/* Begin traversal. */
|
||||
TraversalContext context;
|
||||
TraversalEntry cur_entry = {};
|
||||
TraversalEntry cur_entry = { .phys_addr = Null<KPhysicalAddress>, .block_size = 0, .sw_reserved_bits = 0 };
|
||||
bool cur_valid = false;
|
||||
TraversalEntry next_entry;
|
||||
bool next_valid;
|
||||
|
@ -1400,7 +1400,7 @@ namespace ams::kern {
|
|||
|
||||
/* Begin a traversal. */
|
||||
TraversalContext context;
|
||||
TraversalEntry cur_entry = {};
|
||||
TraversalEntry cur_entry = { .phys_addr = Null<KPhysicalAddress>, .block_size = 0, .sw_reserved_bits = 0 };
|
||||
R_UNLESS(impl.BeginTraversal(std::addressof(cur_entry), std::addressof(context), address), svc::ResultInvalidCurrentMemory());
|
||||
|
||||
/* The region we're traversing has to be heap. */
|
||||
|
@ -4423,7 +4423,7 @@ namespace ams::kern {
|
|||
|
||||
/* Begin traversal. */
|
||||
TraversalContext context;
|
||||
TraversalEntry cur_entry = {};
|
||||
TraversalEntry cur_entry = { .phys_addr = Null<KPhysicalAddress>, .block_size = 0, .sw_reserved_bits = 0 };
|
||||
bool cur_valid = false;
|
||||
TraversalEntry next_entry;
|
||||
bool next_valid;
|
||||
|
|
|
@ -220,8 +220,8 @@ namespace ams::kern {
|
|||
/* Set thread fields. */
|
||||
for (size_t i = 0; i < cpu::NumCores; i++) {
|
||||
m_running_threads[i] = nullptr;
|
||||
m_running_thread_idle_counts[i] = 0;
|
||||
m_pinned_threads[i] = nullptr;
|
||||
m_running_thread_idle_counts[i] = 0;
|
||||
}
|
||||
|
||||
/* Set max memory based on address space type. */
|
||||
|
|
|
@ -24,17 +24,11 @@ namespace ams::kern {
|
|||
}
|
||||
|
||||
void KResourceLimit::Initialize() {
|
||||
/* This should be unnecessary for us, because our constructor will clear all fields. */
|
||||
/* The following is analagous to what Nintendo's implementation (no constexpr constructor) would do, though. */
|
||||
/*
|
||||
m_waiter_count = 0;
|
||||
for (size_t i = 0; i < util::size(m_limit_values); i++) {
|
||||
m_limit_values[i] = 0;
|
||||
m_current_values[i] = 0;
|
||||
m_current_hints[i] = 0;
|
||||
m_peak_values[i] = 0;
|
||||
}
|
||||
*/
|
||||
m_waiter_count = 0;
|
||||
std::memset(m_limit_values, 0, sizeof(m_limit_values));
|
||||
std::memset(m_current_values, 0, sizeof(m_current_values));
|
||||
std::memset(m_current_hints, 0, sizeof(m_current_hints));
|
||||
std::memset(m_peak_values, 0, sizeof(m_peak_values));
|
||||
}
|
||||
|
||||
void KResourceLimit::Finalize() {
|
||||
|
|
|
@ -973,7 +973,7 @@ namespace ams::kern {
|
|||
|
||||
/* Get the request and client thread. */
|
||||
KSessionRequest *request;
|
||||
KScopedAutoObject<KThread> client_thread;
|
||||
KThread *client_thread;
|
||||
{
|
||||
KScopedSchedulerLock sl;
|
||||
|
||||
|
@ -991,9 +991,13 @@ namespace ams::kern {
|
|||
m_request_list.pop_front();
|
||||
|
||||
/* Get the thread for the request. */
|
||||
client_thread = KScopedAutoObject<KThread>(request->GetThread());
|
||||
R_UNLESS(client_thread.IsNotNull(), svc::ResultSessionClosed());
|
||||
client_thread = request->GetThread();
|
||||
R_UNLESS(client_thread != nullptr, svc::ResultSessionClosed());
|
||||
|
||||
/* Open the client thread. */
|
||||
client_thread->Open();
|
||||
}
|
||||
ON_SCOPE_EXIT { client_thread->Close(); };
|
||||
|
||||
/* Set the request as our current. */
|
||||
m_current_request = request;
|
||||
|
@ -1004,7 +1008,7 @@ namespace ams::kern {
|
|||
bool recv_list_broken = false;
|
||||
|
||||
/* Receive the message. */
|
||||
Result result = ReceiveMessage(recv_list_broken, server_message, server_buffer_size, server_message_paddr, *client_thread.GetPointerUnsafe(), client_message, client_buffer_size, this, request);
|
||||
Result result = ReceiveMessage(recv_list_broken, server_message, server_buffer_size, server_message_paddr, *client_thread, client_message, client_buffer_size, this, request);
|
||||
|
||||
/* Handle cleanup on receive failure. */
|
||||
if (R_FAILED(result)) {
|
||||
|
|
|
@ -132,6 +132,7 @@ namespace ams::kern {
|
|||
/* Set parent and condvar tree. */
|
||||
m_parent = nullptr;
|
||||
m_condvar_tree = nullptr;
|
||||
m_condvar_key = 0;
|
||||
|
||||
/* Set sync booleans. */
|
||||
m_signaled = false;
|
||||
|
@ -179,7 +180,7 @@ namespace ams::kern {
|
|||
m_current_core_id = phys_core;
|
||||
|
||||
/* We haven't released our resource limit hint, and we've spent no time on the cpu. */
|
||||
m_resource_limit_release_hint = 0;
|
||||
m_resource_limit_release_hint = false;
|
||||
m_cpu_time = 0;
|
||||
|
||||
/* Setup our kernel stack. */
|
||||
|
@ -1328,7 +1329,7 @@ namespace ams::kern {
|
|||
private:
|
||||
u64 m_id;
|
||||
public:
|
||||
constexpr explicit IdObjectHelper(u64 id) : m_id(id) { /* ... */ }
|
||||
explicit IdObjectHelper(u64 id) : m_id(id) { /* ... */ }
|
||||
virtual u64 GetId() const override { return m_id; }
|
||||
};
|
||||
|
||||
|
|
|
@ -42,7 +42,7 @@ namespace ams::kern {
|
|||
}
|
||||
}
|
||||
public:
|
||||
constexpr KUnusedSlabMemory(size_t size) : m_size(size) { /* ... */ }
|
||||
KUnusedSlabMemory(size_t size) : m_size(size) { /* ... */ }
|
||||
|
||||
constexpr ALWAYS_INLINE KVirtualAddress GetAddress() const { return reinterpret_cast<uintptr_t>(this); }
|
||||
constexpr ALWAYS_INLINE size_t GetSize() const { return m_size; }
|
||||
|
|
|
@ -26,7 +26,7 @@ namespace ams::os::impl {
|
|||
private:
|
||||
void Initialize();
|
||||
public:
|
||||
constexpr RngManager() : m_mt(), m_lock(), m_initialized() { /* ... */ }
|
||||
RngManager() : m_mt(), m_lock(), m_initialized() { /* ... */ }
|
||||
public:
|
||||
u64 GenerateRandomU64();
|
||||
};
|
||||
|
|
|
@ -20,7 +20,7 @@ namespace ams::os {
|
|||
|
||||
namespace {
|
||||
|
||||
constinit util::TinyMT g_random;
|
||||
constinit util::TinyMT g_random{util::ConstantInitialize};
|
||||
constinit os::SdkMutex g_random_mutex;
|
||||
constinit bool g_initialized_random;
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#pragma once
|
||||
#include <vapours/common.hpp>
|
||||
#include <vapours/assert.hpp>
|
||||
#include <vapours/util/util_type_traits.hpp>
|
||||
|
||||
#pragma GCC push_options
|
||||
#pragma GCC optimize ("-O3")
|
||||
|
@ -57,11 +58,14 @@ namespace ams::freebsd {
|
|||
template<typename T>
|
||||
class RBEntry {
|
||||
private:
|
||||
T *m_rbe_left = nullptr;
|
||||
T *m_rbe_right = nullptr;
|
||||
T *m_rbe_parent = nullptr;
|
||||
RBColor m_rbe_color = RBColor::RB_BLACK;
|
||||
T *m_rbe_left ;
|
||||
T *m_rbe_right;
|
||||
T *m_rbe_parent;
|
||||
RBColor m_rbe_color;
|
||||
public:
|
||||
constexpr ALWAYS_INLINE explicit RBEntry(util::ConstantInitializeTag) : m_rbe_left(nullptr), m_rbe_right(nullptr), m_rbe_parent(nullptr), m_rbe_color(RBColor::RB_BLACK) { /* ... */ }
|
||||
explicit ALWAYS_INLINE RBEntry() { /* ... */ }
|
||||
|
||||
[[nodiscard]] constexpr ALWAYS_INLINE T *Left() { return m_rbe_left; }
|
||||
[[nodiscard]] constexpr ALWAYS_INLINE const T *Left() const { return m_rbe_left; }
|
||||
|
||||
|
|
|
@ -39,7 +39,8 @@ namespace ams::util {
|
|||
private:
|
||||
RBEntry m_entry;
|
||||
public:
|
||||
constexpr ALWAYS_INLINE IntrusiveRedBlackTreeNode() = default;
|
||||
constexpr explicit ALWAYS_INLINE IntrusiveRedBlackTreeNode(util::ConstantInitializeTag) : m_entry(util::ConstantInitialize) { /* ... */ }
|
||||
explicit ALWAYS_INLINE IntrusiveRedBlackTreeNode() { /* ... */ }
|
||||
|
||||
[[nodiscard]] constexpr ALWAYS_INLINE RBEntry &GetRBEntry() { return m_entry; }
|
||||
[[nodiscard]] constexpr ALWAYS_INLINE const RBEntry &GetRBEntry() const { return m_entry; }
|
||||
|
@ -544,6 +545,8 @@ namespace ams::util {
|
|||
template<class Derived>
|
||||
class alignas(void *) IntrusiveRedBlackTreeBaseNode : public IntrusiveRedBlackTreeNode {
|
||||
public:
|
||||
using IntrusiveRedBlackTreeNode::IntrusiveRedBlackTreeNode;
|
||||
|
||||
constexpr ALWAYS_INLINE Derived *GetPrev() { return static_cast< Derived *>(static_cast< IntrusiveRedBlackTreeBaseNode *>(impl::IntrusiveRedBlackTreeImpl::GetPrev(this))); }
|
||||
constexpr ALWAYS_INLINE const Derived *GetPrev() const { return static_cast<const Derived *>(static_cast<const IntrusiveRedBlackTreeBaseNode *>(impl::IntrusiveRedBlackTreeImpl::GetPrev(this))); }
|
||||
|
||||
|
|
|
@ -102,9 +102,8 @@ namespace ams::util {
|
|||
state2 ^= y;
|
||||
}
|
||||
public:
|
||||
constexpr TinyMT() : m_state() { /* ... */ }
|
||||
|
||||
/* Public API. */
|
||||
constexpr explicit TinyMT(util::ConstantInitializeTag) : m_state() { /* ... */ }
|
||||
explicit TinyMT() { /* ... */ }
|
||||
|
||||
/* Initialization. */
|
||||
void Initialize(u32 seed) {
|
||||
|
|
|
@ -23,4 +23,7 @@ namespace ams::util {
|
|||
template<typename T>
|
||||
using is_pod = std::bool_constant<std::is_standard_layout<T>::value && std::is_trivial<T>::value>;
|
||||
|
||||
struct ConstantInitializeTag final {};
|
||||
constexpr inline const ConstantInitializeTag ConstantInitialize{};
|
||||
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ namespace ams::kern {
|
|||
|
||||
/* Declare kernel data members in kernel TU. */
|
||||
constinit Kernel::State Kernel::s_state = Kernel::State::Invalid;
|
||||
constinit KResourceLimit Kernel::s_system_resource_limit;
|
||||
constinit KResourceLimit Kernel::s_system_resource_limit{util::ConstantInitialize};
|
||||
KMemoryManager Kernel::s_memory_manager;
|
||||
constinit KSupervisorPageTable Kernel::s_supervisor_page_table;
|
||||
constinit KUnsafeMemory Kernel::s_unsafe_memory;
|
||||
|
@ -33,8 +33,8 @@ namespace ams::kern {
|
|||
constinit KMemoryBlockSlabHeap Kernel::s_app_memory_block_heap;
|
||||
constinit KMemoryBlockSlabHeap Kernel::s_sys_memory_block_heap;
|
||||
constinit KBlockInfoSlabHeap Kernel::s_block_info_heap;
|
||||
constinit KPageTableManager Kernel::s_app_page_table_manager;
|
||||
constinit KPageTableManager Kernel::s_sys_page_table_manager;
|
||||
constinit KPageTableManager Kernel::s_app_page_table_manager{util::ConstantInitialize};
|
||||
constinit KPageTableManager Kernel::s_sys_page_table_manager{util::ConstantInitialize};
|
||||
constinit KMemoryBlockSlabManager Kernel::s_app_memory_block_manager;
|
||||
constinit KMemoryBlockSlabManager Kernel::s_sys_memory_block_manager;
|
||||
constinit KBlockInfoManager Kernel::s_app_block_info_manager;
|
||||
|
@ -42,11 +42,70 @@ namespace ams::kern {
|
|||
|
||||
namespace {
|
||||
|
||||
constinit std::array<KThread, cpu::NumCores> g_main_threads;
|
||||
constinit std::array<KThread, cpu::NumCores> g_idle_threads;
|
||||
template<size_t N> requires (N > 0)
|
||||
union KThreadArray {
|
||||
struct RecursiveHolder {
|
||||
KThread m_thread;
|
||||
KThreadArray<N - 1> m_next;
|
||||
|
||||
consteval RecursiveHolder() : m_thread{util::ConstantInitialize}, m_next() { /* ... */ }
|
||||
} m_holder;
|
||||
KThread m_arr[N];
|
||||
|
||||
consteval KThreadArray() : m_holder() { /* ... */ }
|
||||
};
|
||||
|
||||
template<>
|
||||
union KThreadArray<1>{
|
||||
struct RecursiveHolder {
|
||||
KThread m_thread;
|
||||
|
||||
consteval RecursiveHolder() : m_thread{util::ConstantInitialize} { /* ... */ }
|
||||
} m_holder;
|
||||
KThread m_arr[1];
|
||||
|
||||
consteval KThreadArray() : m_holder() { /* ... */ }
|
||||
};
|
||||
|
||||
template<size_t Ix>
|
||||
consteval bool IsKThreadArrayValid(const KThreadArray<Ix> &v, const KThread *thread) {
|
||||
if (std::addressof(v.m_holder.m_thread) != thread) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if constexpr (Ix == 1) {
|
||||
return true;
|
||||
} else {
|
||||
return IsKThreadArrayValid(v.m_holder.m_next, thread + 1);
|
||||
}
|
||||
}
|
||||
|
||||
template<size_t N>
|
||||
consteval bool IsKThreadArrayValid() {
|
||||
const KThreadArray<N> v{};
|
||||
|
||||
if (!IsKThreadArrayValid(v, v.m_arr)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if constexpr (N == 1) {
|
||||
return true;
|
||||
} else {
|
||||
return IsKThreadArrayValid<N - 1>();
|
||||
}
|
||||
}
|
||||
|
||||
static_assert(IsKThreadArrayValid<cpu::NumCores>());
|
||||
|
||||
constinit KThreadArray<cpu::NumCores> g_main_threads;
|
||||
constinit KThreadArray<cpu::NumCores> g_idle_threads;
|
||||
|
||||
static_assert(sizeof(g_main_threads) == cpu::NumCores * sizeof(KThread));
|
||||
static_assert(sizeof(g_main_threads.m_holder) == sizeof(g_main_threads.m_arr));
|
||||
|
||||
}
|
||||
|
||||
KThread &Kernel::GetMainThread(s32 core_id) { return g_main_threads[core_id]; }
|
||||
KThread &Kernel::GetIdleThread(s32 core_id) { return g_idle_threads[core_id]; }
|
||||
KThread &Kernel::GetMainThread(s32 core_id) { return g_main_threads.m_arr[core_id]; }
|
||||
KThread &Kernel::GetIdleThread(s32 core_id) { return g_idle_threads.m_arr[core_id]; }
|
||||
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@ namespace ams::dmnt::cheat::impl {
|
|||
u64 m_address;
|
||||
FrozenAddressValue m_value;
|
||||
public:
|
||||
constexpr FrozenAddressMapEntry(u64 address, FrozenAddressValue value) : m_address(address), m_value(value) { /* ... */ }
|
||||
FrozenAddressMapEntry(u64 address, FrozenAddressValue value) : m_address(address), m_value(value) { /* ... */ }
|
||||
|
||||
constexpr u64 GetAddress() const { return m_address; }
|
||||
|
||||
|
|
Loading…
Reference in a new issue