69 lines
1.7 KiB
Nim
69 lines
1.7 KiB
Nim
# SPDX-License-Identifier: LUL-1.0
|
|
# Copyright (c) 2026 Markus Maiwald
|
|
# Stewardship: Self Sovereign Society Foundation
|
|
#
|
|
# This file is part of the Nexus SDK.
|
|
# See legal/LICENSE_UNBOUND.md for license terms.
|
|
|
|
# Rumpk Adaptive I/O Governor
|
|
# War Mode (polling) ↔ Peace Mode (interrupts)
|
|
|
|
import ring
|
|
|
|
const
|
|
POLL_BUDGET* = 2000 ## Cycles before switching to peace mode
|
|
PEACE_TIMEOUT_NS* = 1_000_000 ## 1ms before checking again
|
|
|
|
type
|
|
GovernorMode* = enum
|
|
War, ## High load: 100% CPU polling
|
|
Peace ## Low load: Interrupt-driven
|
|
|
|
IoGovernor*[T; N: static[int]] = object
|
|
mode*: GovernorMode
|
|
budget: int
|
|
ring*: RingBuffer[T, N]
|
|
|
|
# Callbacks (set by driver)
|
|
hw_has_data*: proc(): bool {.nimcall.}
|
|
hw_fetch*: proc(): T {.nimcall.}
|
|
hw_enable_irq*: proc() {.nimcall.}
|
|
hw_disable_irq*: proc() {.nimcall.}
|
|
lwkt_yield*: proc() {.nimcall.}
|
|
|
|
proc init*[T; N: static[int]](gov: var IoGovernor[T, N]) =
|
|
gov.mode = Peace
|
|
gov.budget = POLL_BUDGET
|
|
gov.ring.init()
|
|
|
|
proc tick*[T; N: static[int]](gov: var IoGovernor[T, N]) =
|
|
## Main driver loop iteration
|
|
|
|
if gov.hw_has_data():
|
|
# WAR MODE: Data available, stay aggressive
|
|
let data = gov.hw_fetch()
|
|
discard gov.ring.push(data)
|
|
gov.budget = POLL_BUDGET
|
|
gov.mode = War
|
|
|
|
else:
|
|
# Speculation window
|
|
if gov.budget > 0:
|
|
dec gov.budget
|
|
# cpu_relax() equivalent - let other fibers run briefly
|
|
|
|
else:
|
|
# PEACE MODE: Budget exhausted, sleep
|
|
gov.mode = Peace
|
|
gov.hw_enable_irq()
|
|
gov.lwkt_yield()
|
|
|
|
# Woke up from interrupt
|
|
gov.hw_disable_irq()
|
|
gov.budget = POLL_BUDGET
|
|
|
|
proc run*[T; N: static[int]](gov: var IoGovernor[T, N]) {.noreturn.} =
|
|
## Infinite driver loop
|
|
while true:
|
|
gov.tick()
|