feat: power down dGPUs on hybrid graphics laptops
This commit is contained in:
1 parent
7f12e1a150
commit
24f88ec4c6
23 files changed
+4325
-1130
No files matched your search
@@ -365,6 +365,35 @@ namespace Timekeeping {
|
||||
Hal::HaltWithInterruptsDisabled();
|
||||
}
|
||||
|
||||
void BusyWaitUs(uint64_t us) {
|
||||
// An I/O write to port 0x80 is an ISA-bus cycle of roughly a
|
||||
// microsecond on every chipset since the 486, and never shorter.
|
||||
for (uint64_t i = 0; i < us; i++)
|
||||
Io::IoPortWait();
|
||||
}
|
||||
|
||||
void BusyWaitMs(uint64_t ms) {
|
||||
if (ms == 0) return;
|
||||
|
||||
uint64_t flags;
|
||||
asm volatile("pushfq; pop %0" : "=r"(flags));
|
||||
bool ticking = g_ticksPerMs != 0 && (flags & (1 << 9));
|
||||
|
||||
// Either clock alone is long enough, so stop at whichever says so
|
||||
// first. The tick is the accurate one; the port writes bound the wait
|
||||
// when the tick is not running yet (or is masked), so this can never
|
||||
// hang on a timer that does not fire. One extra tick of slack because
|
||||
// the first may already be nearly over.
|
||||
uint64_t start = g_tickCount.load(std::memory_order_relaxed);
|
||||
uint64_t portBudget = (ms + 1) * 1000;
|
||||
for (uint64_t spins = 0; spins < portBudget; spins++) {
|
||||
if (ticking &&
|
||||
g_tickCount.load(std::memory_order_relaxed) - start >= ms + 1)
|
||||
return;
|
||||
Io::IoPortWait();
|
||||
}
|
||||
}
|
||||
|
||||
void Sleep(uint64_t ms) {
|
||||
if (ms == 0) return;
|
||||
// Use BlockForSleep to properly deschedule the process instead
|
||||
|
||||
Reference in new issue
Block a user