mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-09-11 10:43:46 +08:00
Galaxy: harden system monitor and optional chime
Keep the model-ready sound opt-in and return a controlled error when memory totals are unavailable.
This commit is contained in:
committed by
firestar5683
parent
1b1989f794
commit
a3d8c8948e
@@ -352,7 +352,7 @@ inline static std::unordered_map<std::string, ParamKeyAttributes> keys = {
|
||||
{"DrivingModelVersion", {PERSISTENT, STRING, "v15", "v15", 1}},
|
||||
{"DynamicPathWidth", {PERSISTENT, BOOL, "0", "0", 2, SETTINGS_SIMPLE}},
|
||||
{"DynamicPedalsOnUI", {PERSISTENT, BOOL, "1", "0", 1, SETTINGS_SIMPLE}},
|
||||
{"GpuModelReadySound", {PERSISTENT, BOOL, "1", "1", 2, SETTINGS_SIMPLE}},
|
||||
{"GpuModelReadySound", {PERSISTENT, BOOL, "0", "0", 2, SETTINGS_SIMPLE}},
|
||||
{"EngageVolume", {PERSISTENT, INT, "101", "101", 2, SETTINGS_SIMPLE}},
|
||||
{"EVTuning", {PERSISTENT, BOOL, "0", "0", 3}},
|
||||
{"Fahrenheit", {PERSISTENT, BOOL, "0", "0", 3}},
|
||||
|
||||
@@ -70,20 +70,20 @@ class SystemMonitor:
|
||||
user = pwd.getpwuid(uid).pw_name
|
||||
except KeyError:
|
||||
user = str(uid)
|
||||
# Only executable/module names: never expose arguments or environment secrets.
|
||||
info = {'name': name.removeprefix('/data/openpilot/'), 'user': user, 'kernel': not args}
|
||||
names[identity] = info
|
||||
cpu = None
|
||||
if cpu_capacity and identity in self.previous and current >= self.previous[identity]:
|
||||
# Same aggregate tick window as the total, including any core hotplug.
|
||||
# 100% means all measured CPU capacity, not one fully occupied core.
|
||||
cpu = round(min(100, (current - self.previous[identity]) / cpu_capacity * 100), 1)
|
||||
rows.append({'pid': identity[0], **info, 'state': fields[0], 'cpu': cpu,
|
||||
'memoryMiB': round(max(0, int(fields[21])) * self.page / 1048576, 1)})
|
||||
except (OSError, ValueError, IndexError):
|
||||
continue # Process exited or is inaccessible during this snapshot.
|
||||
continue
|
||||
memory = {line.split(':')[0]: int(line.split()[1]) for line in (self.root / 'meminfo').read_text().splitlines() if ':' in line}
|
||||
total = memory['MemTotal'] / 1024
|
||||
total_kib = memory.get('MemTotal')
|
||||
if total_kib is None or total_kib <= 0:
|
||||
raise OSError('MemTotal is unavailable')
|
||||
total = total_kib / 1024
|
||||
available = memory.get('MemAvailable', memory.get('MemFree', 0)) / 1024
|
||||
disk = shutil.disk_usage('/data' if Path('/data').exists() else '/')
|
||||
self.cached = {'sampledAt': time.time(), 'sampleSeconds': round(elapsed, 2) if elapsed else None,
|
||||
|
||||
@@ -60,7 +60,6 @@ def test_processes_use_same_total_capacity_as_overall(tmp_path, monkeypatch, cor
|
||||
capacity = core_count * 2 * monitor.hz
|
||||
used = capacity // 4
|
||||
fixture(tmp_path, active=100 + used, idle=900 + capacity - used)
|
||||
# /proc/stat has one row per currently online core.
|
||||
with (tmp_path / 'stat').open('a') as f:
|
||||
for i in range(1, core_count):
|
||||
f.write(f'cpu{i} 100 0 0 900 0 0 0 0\n')
|
||||
@@ -79,7 +78,6 @@ def test_cpu_capacity_is_measured_across_core_hotplug(tmp_path, monkeypatch):
|
||||
fixture(tmp_path); proc(tmp_path)
|
||||
monitor = SystemMonitor(tmp_path); monitor.sample()
|
||||
now[0] = 2
|
||||
# Four cores for one second, then eight for one second: 12 core-seconds.
|
||||
capacity = 12 * monitor.hz
|
||||
fixture(tmp_path, active=100 + monitor.hz, idle=900 + capacity - monitor.hz)
|
||||
with (tmp_path / 'stat').open('a') as f:
|
||||
@@ -101,3 +99,11 @@ def test_missing_or_reset_capacity_has_no_process_percentage(tmp_path, monkeypat
|
||||
sample = monitor.sample()
|
||||
assert sample['cpuPercent'] is None
|
||||
assert sample['processes'][0]['cpu'] is None
|
||||
|
||||
|
||||
def test_missing_total_memory_fails_closed(tmp_path):
|
||||
fixture(tmp_path)
|
||||
(tmp_path / 'meminfo').write_text('MemAvailable: 512000 kB\n')
|
||||
|
||||
with pytest.raises(OSError, match='MemTotal'):
|
||||
SystemMonitor(tmp_path).sample()
|
||||
|
||||
Reference in New Issue
Block a user