feat: further kernel power and power optimizations

This commit is contained in:
daniel committed 2026-04-21 20:51:12 +02:00
1 parent 7d6f001659
commit 38b1f8a7ef
31 files changed
+895 -52

No files matched your search

+70
View File
@@ -0,0 +1,70 @@
/*
* InputEvents.cpp
* Shared input activity event source
* Copyright (c) 2026 Daniel Hammer
*/
#include "InputEvents.hpp"
#include <atomic>
#include <Sched/Scheduler.hpp>
#include <Timekeeping/ApicTimer.hpp>
namespace Drivers::InputEvents {
static std::atomic<uint64_t> g_serial{1};
static uint8_t g_waitObject;
struct WaitContext {
uint64_t observedSerial;
};
static bool SerialStillObserved(void* rawContext) {
auto* context = static_cast<WaitContext*>(rawContext);
return context != nullptr &&
g_serial.load(std::memory_order_acquire) == context->observedSerial;
}
uint64_t GetSerial() {
return g_serial.load(std::memory_order_acquire);
}
void NotifyActivity() {
Timekeeping::NoteInteractiveActivity();
g_serial.fetch_add(1, std::memory_order_release);
Sched::WakeObjectWaiters(&g_waitObject);
}
uint64_t WaitForChange(uint64_t observedSerial, uint64_t timeoutMs) {
uint64_t current = GetSerial();
if (current != observedSerial || timeoutMs == 0) {
return current;
}
WaitContext context{observedSerial};
uint64_t start = Timekeeping::GetMilliseconds();
for (;;) {
current = GetSerial();
if (current != observedSerial) {
return current;
}
uint64_t waitMs = 0;
if (timeoutMs == UINT64_MAX) {
waitMs = 0;
} else {
uint64_t elapsed = Timekeeping::GetMilliseconds() - start;
if (elapsed >= timeoutMs) {
return current;
}
waitMs = timeoutMs - elapsed;
if (waitMs == 0) {
waitMs = 1;
}
}
Sched::BlockOnObjectIf(&g_waitObject, waitMs, SerialStillObserved, &context);
}
}
}
+22
View File
@@ -0,0 +1,22 @@
/*
* InputEvents.hpp
* Shared input activity event source
* Copyright (c) 2026 Daniel Hammer
*/
#pragma once
#include <cstdint>
namespace Drivers::InputEvents {
// Monotonic serial incremented after mouse or keyboard state changes.
uint64_t GetSerial();
// Notify latency-sensitive input activity and wake input waiters.
void NotifyActivity();
// Wait until the serial differs from observedSerial or timeoutMs elapses.
// timeoutMs == 0 is a poll; timeoutMs == UINT64_MAX waits indefinitely.
uint64_t WaitForChange(uint64_t observedSerial, uint64_t timeoutMs);
}