mirror of
https://github.com/boykopovar/AnyPS5.git
synced 2026-10-22 16:43:05 -05:00
A sleep of 1 ms or less returns once the AGC driver sees a GPU batch complete (a thread waits on the recorder's timeline semaphore), runs a batch's completion actions, or VideoOut completes a flip. A thread returns early at most 8 times in a run of back-to-back sleeps; the run restarts when the thread submits AGC work or did not sleep for the requested time. APS5_NO_SLEEP_WAKE=1 keeps every sleep in full. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
58 lines
1.4 KiB
C++
58 lines
1.4 KiB
C++
#include "prx/libkernel/Time/include/SleepWake.hpp"
|
|
#include "prx/libkernel/Time/include/TimedWait.hpp"
|
|
|
|
#include <atomic>
|
|
#include <cstdlib>
|
|
|
|
namespace SleepWake {
|
|
|
|
namespace {
|
|
|
|
struct ThreadState {
|
|
unsigned earlyWakes = 0;
|
|
std::uint64_t lastSleepEndNanos = 0;
|
|
bool sleeping = false;
|
|
};
|
|
|
|
thread_local ThreadState state;
|
|
|
|
std::atomic<std::uint64_t> completions{0};
|
|
|
|
bool Enabled() {
|
|
static const bool enabled = std::getenv("APS5_NO_SLEEP_WAKE") == nullptr;
|
|
return enabled;
|
|
}
|
|
|
|
}
|
|
|
|
void Sleep(std::uint64_t nanos) {
|
|
bool woken = false;
|
|
if (nanos != 0 && nanos <= MAX_WAKEABLE_NANOS && !state.sleeping && Enabled()) {
|
|
if (TimedWait::NowNanos() - state.lastSleepEndNanos >= nanos) state.earlyWakes = 0;
|
|
if (state.earlyWakes < EARLY_WAKES_PER_RUN) {
|
|
state.sleeping = true;
|
|
const bool early = TimedWait::SleepNanosUnlessChanged(nanos, completions, completions.load(std::memory_order_seq_cst));
|
|
state.sleeping = false;
|
|
if (early) ++state.earlyWakes;
|
|
woken = true;
|
|
}
|
|
}
|
|
if (!woken) TimedWait::SleepNanos(nanos);
|
|
state.lastSleepEndNanos = TimedWait::NowNanos();
|
|
}
|
|
|
|
}
|
|
|
|
extern "C" {
|
|
|
|
void KernelWakeSleepers_nid_no_patch() {
|
|
SleepWake::completions.fetch_add(1, std::memory_order_seq_cst);
|
|
TimedWait::WakeChangeSleepers();
|
|
}
|
|
|
|
void KernelNoteGpuSubmit_nid_no_patch() {
|
|
SleepWake::state.earlyWakes = 0;
|
|
}
|
|
|
|
}
|