util: better match true std::atomic semantics

This commit is contained in:
Michael Scire 2021-10-20 11:02:17 -07:00
parent c6d7174dd3
commit aed9d3f535
12 changed files with 102 additions and 53 deletions

View file

@ -66,7 +66,7 @@ namespace ams::kern {
KSlabHeapImpl::Free(allocated + i);
}
m_count.FetchAdd(sizeof(PageBuffer) / sizeof(T));
m_count += sizeof(PageBuffer) / sizeof(T);
}
}
@ -89,7 +89,7 @@ namespace ams::kern {
for (size_t i = 1; i < sizeof(PageBuffer) / sizeof(T); i++) {
KSlabHeapImpl::Free(allocated + i);
}
m_count.FetchAdd(sizeof(PageBuffer) / sizeof(T));
m_count += sizeof(PageBuffer) / sizeof(T);
}
}
}
@ -99,7 +99,7 @@ namespace ams::kern {
std::construct_at(allocated);
/* Update our tracking. */
size_t used = m_used.FetchAdd(1) + 1;
const size_t used = ++m_used;
size_t peak = m_peak.Load();
while (peak < used) {
if (m_peak.CompareExchangeWeak<std::memory_order_relaxed>(peak, used)) {
@ -113,7 +113,7 @@ namespace ams::kern {
ALWAYS_INLINE void Free(T *t) {
KSlabHeapImpl::Free(t);
m_used.FetchSub(1);
--m_used;
}
};

View file

@ -288,7 +288,7 @@ namespace ams::kern {
KThread *GetExceptionThread() const { return m_exception_thread; }
void AddCpuTime(s64 diff) { m_cpu_time.FetchAdd(diff); }
void AddCpuTime(s64 diff) { m_cpu_time += diff; }
s64 GetCpuTime() { return m_cpu_time.Load(); }
constexpr s64 GetScheduledCount() const { return m_schedule_count; }

View file

@ -176,8 +176,6 @@ namespace ams::kern {
};
static_assert(ams::util::HasRedBlackKeyType<ConditionVariableComparator>);
static_assert(std::same_as<ams::util::RedBlackKeyType<ConditionVariableComparator, void>, ConditionVariableComparator::RedBlackKeyType>);
private:
static constinit inline util::Atomic<u64> s_next_thread_id{0};
private:
util::IntrusiveListNode m_process_list_node{};
util::IntrusiveRedBlackTreeNode m_condvar_arbiter_tree_node{};
@ -348,11 +346,11 @@ namespace ams::kern {
#endif
ALWAYS_INLINE void RegisterDpc(DpcFlag flag) {
this->GetStackParameters().dpc_flags.FetchOr(flag);
this->GetStackParameters().dpc_flags |= flag;
}
ALWAYS_INLINE void ClearDpc(DpcFlag flag) {
this->GetStackParameters().dpc_flags.FetchAnd(~flag);
this->GetStackParameters().dpc_flags &= ~flag;
}
ALWAYS_INLINE u8 GetDpc() const {
@ -544,7 +542,7 @@ namespace ams::kern {
constexpr bool IsAttachedToDebugger() const { return m_debug_attached; }
void AddCpuTime(s32 core_id, s64 amount) {
m_cpu_time.FetchAdd(amount);
m_cpu_time += amount;
/* TODO: Debug kernels track per-core tick counts. Should we? */
MESOSPHERE_UNUSED(core_id);
}

View file

@ -287,7 +287,7 @@ namespace ams::kern::arch::arm64::cpu {
break;
}
m_target_cores.FetchAnd(~(1ul << GetCurrentCoreId()));
m_target_cores &= (~(1ul << GetCurrentCoreId()));
}
ALWAYS_INLINE void SetEventLocally() {

View file

@ -28,7 +28,7 @@ namespace ams::kern {
void KClientPort::OnSessionFinalized() {
KScopedSchedulerLock sl;
if (m_num_sessions.FetchSub(1) == m_max_sessions) {
if (const auto prev = m_num_sessions--; prev == m_max_sessions) {
this->NotifyAvailable();
}
}

View file

@ -25,8 +25,8 @@ namespace ams::kern {
constexpr u64 ProcessIdMin = InitialProcessIdMax + 1;
constexpr u64 ProcessIdMax = std::numeric_limits<u64>::max();
constinit util::Atomic<u64> g_initial_process_id{InitialProcessIdMin};
constinit util::Atomic<u64> g_process_id{ProcessIdMin};
constinit util::Atomic<u64> g_initial_process_id = InitialProcessIdMin;
constinit util::Atomic<u64> g_process_id = ProcessIdMin;
Result TerminateChildren(KProcess *process, const KThread *thread_to_not_terminate) {
/* Request that all children threads terminate. */
@ -299,7 +299,7 @@ namespace ams::kern {
R_TRY(m_capabilities.Initialize(caps, num_caps, std::addressof(m_page_table)));
/* Initialize the process id. */
m_process_id = g_initial_process_id.FetchAdd(1);
m_process_id = g_initial_process_id++;
MESOSPHERE_ABORT_UNLESS(InitialProcessIdMin <= m_process_id);
MESOSPHERE_ABORT_UNLESS(m_process_id <= InitialProcessIdMax);
@ -409,7 +409,7 @@ namespace ams::kern {
R_TRY(m_capabilities.Initialize(user_caps, num_caps, std::addressof(m_page_table)));
/* Initialize the process id. */
m_process_id = g_process_id.FetchAdd(1);
m_process_id = g_process_id++;
MESOSPHERE_ABORT_UNLESS(ProcessIdMin <= m_process_id);
MESOSPHERE_ABORT_UNLESS(m_process_id <= ProcessIdMax);
@ -791,13 +791,13 @@ namespace ams::kern {
void KProcess::IncrementRunningThreadCount() {
MESOSPHERE_ASSERT(m_num_running_threads.Load() >= 0);
m_num_running_threads.FetchAdd(1);
++m_num_running_threads;
}
void KProcess::DecrementRunningThreadCount() {
MESOSPHERE_ASSERT(m_num_running_threads.Load() > 0);
if (m_num_running_threads.FetchSub(1) == 1) {
if (const auto prev = m_num_running_threads--; prev == 1) {
this->Terminate();
}
}

View file

@ -21,6 +21,8 @@ namespace ams::kern {
constexpr inline s32 TerminatingThreadPriority = ams::svc::SystemThreadPriorityHighest - 1;
constinit util::Atomic<u64> g_thread_id = 0;
constexpr ALWAYS_INLINE bool IsKernelAddressKey(KProcessAddress key) {
const uintptr_t key_uptr = GetInteger(key);
return KernelVirtualAddressSpaceBase <= key_uptr && key_uptr <= KernelVirtualAddressSpaceLast && (key_uptr & 1) == 0;
@ -219,7 +221,7 @@ namespace ams::kern {
this->SetInExceptionHandler();
/* Set thread ID. */
m_thread_id = s_next_thread_id.FetchAdd(1);
m_thread_id = g_thread_id++;
/* We initialized! */
m_initialized = true;

View file

@ -42,15 +42,15 @@ namespace ams::kern {
return arr;
}();
constinit util::Atomic<s32> g_next_ticket{0};
constinit util::Atomic<s32> g_current_ticket{0};
constinit util::Atomic<s32> g_next_ticket = 0;
constinit util::Atomic<s32> g_current_ticket = 0;
constinit std::array<s32, cpu::NumCores> g_core_tickets = NegativeArray;
s32 GetCoreTicket() {
const s32 core_id = GetCurrentCoreId();
if (g_core_tickets[core_id] == -1) {
g_core_tickets[core_id] = 2 * g_next_ticket.FetchAdd(1);
g_core_tickets[core_id] = 2 * (g_next_ticket++);
}
return g_core_tickets[core_id];
}