kern: use new AtomicRef, use Atomic<bool>
This commit is contained in:
@@ -39,13 +39,13 @@ namespace ams::kern {
|
||||
static_assert(ams::svc::HighestThreadPriority <= HighestCoreMigrationAllowedPriority);
|
||||
|
||||
struct SchedulingState {
|
||||
util::Atomic<u8> needs_scheduling{false};
|
||||
util::Atomic<bool> needs_scheduling{false};
|
||||
bool interrupt_task_runnable{false};
|
||||
bool should_count_idle{false};
|
||||
u64 idle_count{0};
|
||||
KThread *highest_priority_thread{nullptr};
|
||||
void *idle_thread_stack{nullptr};
|
||||
util::Atomic<KThread *> prev_thread{nullptr};
|
||||
KThread *prev_thread{nullptr};
|
||||
KInterruptTaskManager *interrupt_task_manager{nullptr};
|
||||
|
||||
constexpr SchedulingState() = default;
|
||||
@@ -100,7 +100,7 @@ namespace ams::kern {
|
||||
}
|
||||
|
||||
ALWAYS_INLINE KThread *GetPreviousThread() const {
|
||||
return m_state.prev_thread.Load<std::memory_order_relaxed>();
|
||||
return m_state.prev_thread;
|
||||
}
|
||||
|
||||
ALWAYS_INLINE KThread *GetSchedulerCurrentThread() const {
|
||||
|
||||
@@ -76,18 +76,20 @@ namespace ams::kern {
|
||||
NON_MOVEABLE(KSlabHeapBase);
|
||||
private:
|
||||
size_t m_obj_size{};
|
||||
util::Atomic<uintptr_t> m_peak{0};
|
||||
uintptr_t m_peak{};
|
||||
uintptr_t m_start{};
|
||||
uintptr_t m_end{};
|
||||
private:
|
||||
ALWAYS_INLINE void UpdatePeakImpl(uintptr_t obj) {
|
||||
const util::AtomicRef<uintptr_t> peak_ref(m_peak);
|
||||
|
||||
const uintptr_t alloc_peak = obj + this->GetObjectSize();
|
||||
uintptr_t cur_peak = m_peak.Load<std::memory_order_relaxed>();
|
||||
uintptr_t cur_peak = m_peak;
|
||||
do {
|
||||
if (alloc_peak <= cur_peak) {
|
||||
break;
|
||||
}
|
||||
} while (!m_peak.CompareExchangeStrong(cur_peak, alloc_peak));
|
||||
} while (!peak_ref.CompareExchangeStrong(cur_peak, alloc_peak));
|
||||
}
|
||||
public:
|
||||
constexpr KSlabHeapBase() = default;
|
||||
@@ -110,8 +112,7 @@ namespace ams::kern {
|
||||
const size_t num_obj = (memory_size / obj_size);
|
||||
m_start = reinterpret_cast<uintptr_t>(memory);
|
||||
m_end = m_start + num_obj * obj_size;
|
||||
|
||||
m_peak.Store<std::memory_order_relaxed>(m_start);
|
||||
m_peak = m_start;
|
||||
|
||||
/* Free the objects. */
|
||||
u8 *cur = reinterpret_cast<u8 *>(m_end);
|
||||
@@ -175,7 +176,7 @@ namespace ams::kern {
|
||||
}
|
||||
|
||||
ALWAYS_INLINE size_t GetPeakIndex() const {
|
||||
return this->GetObjectIndex(reinterpret_cast<const void *>(m_peak.Load<std::memory_order_relaxed>()));
|
||||
return this->GetObjectIndex(reinterpret_cast<const void *>(m_peak));
|
||||
}
|
||||
|
||||
ALWAYS_INLINE uintptr_t GetSlabHeapAddress() const {
|
||||
|
||||
@@ -225,7 +225,7 @@ namespace ams::kern {
|
||||
s32 m_original_physical_ideal_core_id{};
|
||||
s32 m_num_core_migration_disables{};
|
||||
ThreadState m_thread_state{};
|
||||
util::Atomic<u8> m_termination_requested{false};
|
||||
util::Atomic<bool> m_termination_requested{false};
|
||||
bool m_wait_cancelled{};
|
||||
bool m_cancellable{};
|
||||
bool m_signaled{};
|
||||
|
||||
@@ -246,9 +246,9 @@ namespace ams::kern {
|
||||
if (cur_process != nullptr) {
|
||||
/* NOTE: Combining this into AMS_LIKELY(!... && ...) triggers an internal compiler error: Segmentation fault in GCC 9.2.0. */
|
||||
if (AMS_LIKELY(!cur_thread->IsTerminationRequested()) && AMS_LIKELY(cur_thread->GetActiveCore() == m_core_id)) {
|
||||
m_state.prev_thread.Store<std::memory_order_relaxed>(cur_thread);
|
||||
m_state.prev_thread = cur_thread;
|
||||
} else {
|
||||
m_state.prev_thread.Store<std::memory_order_relaxed>(nullptr);
|
||||
m_state.prev_thread =nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -270,9 +270,12 @@ namespace ams::kern {
|
||||
void KScheduler::ClearPreviousThread(KThread *thread) {
|
||||
MESOSPHERE_ASSERT(IsSchedulerLockedByCurrentThread());
|
||||
for (size_t i = 0; i < cpu::NumCores; ++i) {
|
||||
/* Get an atomic reference to the core scheduler's previous thread. */
|
||||
const util::AtomicRef<KThread *> prev_thread(Kernel::GetScheduler(static_cast<s32>(i)).m_state.prev_thread);
|
||||
|
||||
/* Atomically clear the previous thread if it's our target. */
|
||||
KThread *compare = thread;
|
||||
Kernel::GetScheduler(static_cast<s32>(i)).m_state.prev_thread.CompareExchangeStrong(compare, nullptr);
|
||||
prev_thread.CompareExchangeStrong(compare, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1184,7 +1184,7 @@ namespace ams::kern {
|
||||
/* Determine if this is the first termination request. */
|
||||
const bool first_request = [&] ALWAYS_INLINE_LAMBDA () -> bool {
|
||||
/* Perform an atomic compare-and-swap from false to true. */
|
||||
u8 expected = false;
|
||||
bool expected = false;
|
||||
return m_termination_requested.CompareExchangeStrong(expected, true);
|
||||
}();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user