mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2025-06-04 16:53:48 -04: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
|
@ -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; }
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue