mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2024-11-24 07:40:26 +01:00
KScheduler big brain strat for mdscr_el1 cfg change
This commit is contained in:
parent
e256261b80
commit
09074798cd
@ -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;
|
||||
m_state.should_count_idle = false;
|
||||
|
@ -249,22 +249,18 @@ namespace ams::kern {
|
||||
|
||||
#if defined(MESOSPHERE_ENABLE_HARDWARE_SINGLE_STEP)
|
||||
/* Ensure the single-step bit in mdscr reflects the correct single-step state for the new thread. */
|
||||
/* NOTE: Per ARM docs, changing the single-step bit requires a "context synchronization event" to */
|
||||
/* be sure that our new configuration takes. However, there are three types of synchronization event: */
|
||||
/* Taking an exception, returning from an exception, and ISB. The single-step bit change only matters */
|
||||
/* in EL0...which implies a return-from-exception has occurred since we set the bit. Thus, forcing */
|
||||
/* an ISB is unnecessary, and we can modify the register safely and be confident it will affect the next */
|
||||
/* userland instruction executed. */
|
||||
cpu::MonitorDebugSystemControlRegisterAccessor().SetSoftwareStep(next_thread->IsSingleStep()).Store();
|
||||
#endif
|
||||
|
||||
/* Switch the current process, if we're switching processes. */
|
||||
if (KProcess *next_process = next_thread->GetOwnerProcess(); next_process != cur_process) {
|
||||
KProcess::Switch(cur_process, next_process);
|
||||
} else {
|
||||
/* The single-step bit set up above requires an instruction synchronization barrier, to ensure */
|
||||
/* the state change takes before we actually perform a return which might break-to-step. */
|
||||
/* KProcess::Switch performs an isb incidentally, and so when we're changing process we */
|
||||
/* can piggy-back off of that isb to avoid unnecessarily emptying the pipeline twice. */
|
||||
/* However, this means that when we're switching to thread in a different process, */
|
||||
/* we must ensure that we still isb. In practice, gcc will deduplicate into a single isb. */
|
||||
#if defined(MESOSPHERE_ENABLE_HARDWARE_SINGLE_STEP)
|
||||
cpu::InstructionMemoryBarrier();
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Set the new thread. */
|
||||
|
Loading…
Reference in New Issue
Block a user