diff --git a/simplyblock_core/utils.py b/simplyblock_core/utils.py index 7cd00d82d..e21d8aad6 100644 --- a/simplyblock_core/utils.py +++ b/simplyblock_core/utils.py @@ -871,9 +871,7 @@ def parse_thread_siblings(): cpu_id = int(cpu[3:]) try: with open(f"/sys/devices/system/cpu/{cpu}/topology/thread_siblings_list") as f: - siblings[cpu_id] = [ - int(x) for x in f.read().strip().split(",") - ] + siblings[cpu_id] = parse_thread_siblings_list(f.read().strip()) except FileNotFoundError: siblings[cpu_id] = [cpu_id] # No siblings for this CPU return siblings @@ -890,6 +888,41 @@ def is_hyperthreading_enabled_via_siblings(): return False +def parse_thread_siblings_list(siblings: str) -> list[int]: + if not siblings or not siblings.strip(): + return [] + + cpus = set() + token_re = re.compile(r"^\s*(?P\d+)(?:\s*-\s*(?P\d+)(?:\s*(?:[:\/])\s*(?P\d+))?)?\s*$", re.X) + + for raw in siblings.split(","): + part = raw.strip() + if not part: + continue + m = token_re.match(part) + if not m: + raise ValueError(f"Invalid token in CPU list: {part!r}") + + start = int(m.group("start")) + end = m.group("end") + step = m.group("step") + + if end is None: + cpus.add(start) + else: + end = int(end) + if start > end: + raise ValueError(f"Range start > end in token: {part!r}") + step = int(step) if step is not None else 1 + if step <= 0: + raise ValueError(f"Step must be positive in token: {part!r}") + for v in range(start, end + 1, step): + cpus.add(v) + + return sorted(cpus) + + + def load_core_distribution_from_file(file_path, number_of_cores): """Load core distribution from the configuration file or use default.""" # Check if the file exists