kern: correct thread termination atomicity

This commit is contained in:
Michael Scire 2020-08-15 03:02:09 -07:00 committed by SciresM
parent e5d30217d3
commit a75c16226e

View file

@ -1099,13 +1099,7 @@ namespace ams::kern {
const bool first_request = [&] ALWAYS_INLINE_LAMBDA () -> bool { const bool first_request = [&] ALWAYS_INLINE_LAMBDA () -> bool {
/* Perform an atomic compare-and-swap from false to true. */ /* Perform an atomic compare-and-swap from false to true. */
bool expected = false; bool expected = false;
do { return this->termination_requested.compare_exchange_strong(expected, true);
if (expected) {
return false;
}
} while (!this->termination_requested.compare_exchange_weak(expected, true));
return true;
}(); }();
/* If this is the first request, start termination procedure. */ /* If this is the first request, start termination procedure. */
@ -1133,6 +1127,7 @@ namespace ams::kern {
/* If the thread is runnable, send a termination interrupt to other cores. */ /* If the thread is runnable, send a termination interrupt to other cores. */
if (this->GetState() == ThreadState_Runnable) { if (this->GetState() == ThreadState_Runnable) {
if (const u64 core_mask = this->affinity_mask.GetAffinityMask() & ~(1ul << GetCurrentCoreId()); core_mask != 0) { if (const u64 core_mask = this->affinity_mask.GetAffinityMask() & ~(1ul << GetCurrentCoreId()); core_mask != 0) {
cpu::DataSynchronizationBarrier();
Kernel::GetInterruptManager().SendInterProcessorInterrupt(KInterruptName_ThreadTerminate, core_mask); Kernel::GetInterruptManager().SendInterProcessorInterrupt(KInterruptName_ThreadTerminate, core_mask);
} }
} }