fix: reduce idle CPU wakeups and deferred-work polling
This commit is contained in:
1 parent
f7677ac3f1
commit
788b662d44
10 files changed
+109
-14
No files matched your search
@@ -440,6 +440,29 @@ namespace Drivers::Net::Wifi {
|
||||
static void ServiceAsync();
|
||||
static void ServiceRecovery();
|
||||
|
||||
bool HasDeferredWork() {
|
||||
if (g_initPending.load(std::memory_order_acquire) &&
|
||||
!g_initialized && Fs::Vfs::IsDriveRegistered(0)) {
|
||||
return true;
|
||||
}
|
||||
if (!g_iwx.Mmio) return false;
|
||||
if (g_iwx.WorkPending) return true;
|
||||
|
||||
uint64_t now = Timekeeping::GetMilliseconds();
|
||||
if (g_scanDeadline != 0 && now >= g_scanDeadline) return true;
|
||||
// The MLME/WPA state machine owns sub-second retransmission timers in
|
||||
// addition to the overall async deadline. Service it until ServiceAsync
|
||||
// observes Connected/Failed/Idle and clears this flag.
|
||||
if (g_asyncConnect) return true;
|
||||
if (g_iwx.State == IwxFwState::Error && g_initialized &&
|
||||
!g_recoveryGaveUp &&
|
||||
(g_lastRecoveryMs == 0 ||
|
||||
now - g_lastRecoveryMs >= RECOVERY_BACKOFF_MS)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void ServiceEvents() {
|
||||
if (!g_iwx.Mmio) return;
|
||||
if (g_iwx.WorkPending) IwxProcessEvents();
|
||||
|
||||
@@ -21,6 +21,10 @@ namespace Drivers::Net::Wifi {
|
||||
// Steady-state event pump (RX ring, notifications). Idle-loop callback.
|
||||
void ServiceEvents();
|
||||
|
||||
// True when firmware initialization, an RX notification, an expired async
|
||||
// deadline, or a due recovery attempt needs idle-context servicing.
|
||||
bool HasDeferredWork();
|
||||
|
||||
bool IsInitialized();
|
||||
bool IsPresent();
|
||||
|
||||
|
||||
@@ -419,6 +419,14 @@ namespace Drivers::USB::Bluetooth {
|
||||
// ServiceEvents — steady-state event pump (idle loop)
|
||||
// =========================================================================
|
||||
|
||||
bool HasDeferredWork() {
|
||||
if (g_initPending.load(std::memory_order_acquire) &&
|
||||
!g_initialized && Fs::Vfs::IsDriveRegistered(0)) {
|
||||
return true;
|
||||
}
|
||||
return g_initialized && Hci::HasPendingCommands();
|
||||
}
|
||||
|
||||
void ServiceEvents() {
|
||||
if (!g_initialized) return;
|
||||
if (Xhci::InPollContext()) return; // never nest under PollEvents
|
||||
|
||||
@@ -27,6 +27,11 @@ namespace Drivers::USB::Bluetooth {
|
||||
// (PollEvents/DrainEvents/ProcessPendingCommands all self-serialize).
|
||||
void ServiceEvents();
|
||||
|
||||
// True when boot-deferred initialization or queued HCI control work needs
|
||||
// an idle-context service pass. USB receive events are signaled separately
|
||||
// by xHCI and cause the dispatcher to service Bluetooth in the same pass.
|
||||
bool HasDeferredWork();
|
||||
|
||||
// Query adapter state
|
||||
bool IsInitialized();
|
||||
uint8_t GetSlotId();
|
||||
|
||||
@@ -1719,6 +1719,11 @@ namespace Drivers::USB::Bluetooth::Hci {
|
||||
s_active.store(false, std::memory_order_release);
|
||||
}
|
||||
|
||||
bool HasPendingCommands() {
|
||||
return g_pendingTail.load(std::memory_order_acquire) !=
|
||||
g_pendingHead.load(std::memory_order_acquire);
|
||||
}
|
||||
|
||||
bool WaitSecureSendResult(uint32_t timeoutMs, uint8_t* outResult, uint8_t* outStatus) {
|
||||
uint64_t start = Timekeeping::GetMilliseconds();
|
||||
while (Timekeeping::GetMilliseconds() - start < timeoutMs) {
|
||||
|
||||
@@ -331,6 +331,7 @@ namespace Drivers::USB::Bluetooth::Hci {
|
||||
// real confirmed transfers. Call from top-level (e.g. the connect loop),
|
||||
// NOT from an event handler -- event handlers only enqueue.
|
||||
void ProcessPendingCommands();
|
||||
bool HasPendingCommands();
|
||||
|
||||
// ACL TX flow control: outstanding (un-acked) ACL packets, and the
|
||||
// controller's ACL buffer count (Number-Of-Completed-Packets credits). The
|
||||
|
||||
Reference in new issue
Block a user