amanusk / amanusk/s-tui

Util shows N/A on online cores when taskset is combined with offlined CPUs

未关闭 适合新手
#304 0 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看
主要语言
Python
星标
5.1k
派生
181
平均合并
30 分钟
30 天内合并 PR
2

描述

Follow-up to #303. The fix for #303 handles `taskset` (all CPUs online) and pure `chcpu -d` (no taskset) correctly, but the combination of the two still misreports online cores as N/A.

## Repro

On an 8-core machine:

```
sudo chcpu -d 4
taskset -c 3-6 s-tui
```

Cores actually online: 0, 1, 2, 3, 5, 6, 7. Only core 4 is offline.
s-tui displays: cores 3, 5, 6 with values; cores 0, 1, 2, 4, 7 as N/A.
Expected: only core 4 as N/A.

## Root cause

In `s_tui/sources/util_source.py::update()`, when `len(per_cpu) < total_cores` we fall back to `_get_online_cpu_ids()`, which calls `psutil.Process().cpu_affinity()`. Under taskset that returns the intersection of the taskset mask and the online set (here `[3, 5, 6]`), not the full online set (`[0, 1, 2, 3, 5, 6, 7]`).

`psutil.cpu_percent(percpu=True)` returns 7 values (one per online CPU) but we only know the real IDs of 3 of them, so `zip(online_ids, per_cpu)` truncates and every non-affinity core is marked N/A.

## Why psutil can't answer this

psutil has no API that returns "online CPU IDs" independent of process affinity. `cpu_affinity()` always intersects with the caller's mask; `cpu_count()` gives a number, not IDs; `cpu_percent(percpu=True)` gives values indexed 0..N-1 that don't map to real CPU IDs when there are gaps.

## Proposed fix

Read `/sys/devices/system/cpu/online` (Linux-only, but so is chcpu). Parse the cpulist format (`0-3,5,7`) into the online-ID list. Cadence stays the same as today — we only refresh `_cached_online_ids` when `len(per_cpu)` changes, so this is one file read at startup plus one on each hotplug event, not per update cycle.

Sketch:

```python
def _get_online_cpu_ids() -> list[int] | None:
try:
with open("/sys/devices/system/cpu/online") as f:
raw = f.read().strip()
except OSError:
return None
ids = []
for chunk in raw.split(","):
if "-" in chunk:
a, b = chunk.split("-")
ids.extend(range(int(a), int(b) + 1))
else:
ids.append(int(chunk))
return ids
```

## Scope note

This is a rare combination and was equally broken before 1.4.0 (offline detection didn't exist), so it's not a regression — just a limitation of the offline-detection feature added in #262.

贡献指南

打开贡献指南

调研方向

Start in s_tui/sources/util_source.py, especially update() and _get_online_cpu_ids(), and reproduce the issue with chcpu and taskset on Linux if available. Verify that online CPU IDs remain distinct from the process affinity mask and that only offline CPUs display N/A; add or update focused tests if the existing source tests cover this path.

由索引模型根据 Issue 内容生成。

评估

技术栈
linux, python
领域
cli, operating-systems
Issue 类型
缺陷
难度
2/5
预计耗时
1-3 小时
活跃度
活跃
描述清晰度
描述清楚
新手友好度
84/100

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。