feat: further kernel power and power optimizations
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user