Source code for crash.types.cpu

#!/usr/bin/python3
# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:
"""
The crash.types.cpu module offers helpers to work with the state of CPUs.
"""

from typing import Iterable, List

from crash.util.symbols import SymbolCallbacks
from crash.types.bitmap import for_each_set_bit
from crash.exceptions import DelayedAttributeError

import gdb

# this wraps no particular type, rather it's a placeholder for
# functions to iterate over online cpu's etc.
[docs]class TypesCPUClass: """A state holder class for handling CPUs. Not meant to be instantiated. Attributes: cpus_online (:obj:`list` of :obj:`int`): A list of the IDs of all online CPUs. cpus_possible (:obj:`list` of :obj:`int`): A list of the IDs of all possible CPUs. """ cpus_online: List[int] = list() cpus_possible: List[int] = list() _cpu_online_mask: gdb.Value _cpu_possible_mask: gdb.Value def __init__(self) -> None: raise NotImplementedError("This class is not meant to be instantiated")
[docs] @classmethod def setup_online_mask(cls, symbol: gdb.Symbol) -> None: """ Translate the ``cpu_online_mask`` bitmap into a list of online CPU numbers. Meant to be used as a SymbolCallback. Args: symbol: The symbol for ``cpu_online_mask`` or ``__cpu_online_mask``, depending on kernel version. """ cls._cpu_online_mask = symbol.value() bits = cls._cpu_online_mask["bits"] cls.cpus_online = list(for_each_set_bit(bits))
[docs] @classmethod def setup_possible_mask(cls, cpu_mask: gdb.Symbol) -> None: """ Translate the ``cpu_possible_mask`` bitmap into a list of possible CPU numbers. Meant to be used as a SymbolCallback. Args: cpu_mask: The symbol for ``cpu_possible_mask`` or ``__cpu_possible_mask``, depending on kernel version. """ cls._cpu_possible_mask = cpu_mask.value() bits = cls._cpu_possible_mask["bits"] cls.cpus_possible = list(for_each_set_bit(bits))
[docs]def for_each_online_cpu() -> Iterable[int]: """ Yield CPU numbers of all online CPUs Yields: :obj:`int`: Number of an online CPU location """ for cpu in TypesCPUClass.cpus_online: yield cpu
[docs]def highest_online_cpu_nr() -> int: """ Return The highest online CPU number Returns: :obj:`int`: The highest online CPU number """ if not TypesCPUClass.cpus_online: raise DelayedAttributeError('cpus_online') return TypesCPUClass.cpus_online[-1]
[docs]def for_each_possible_cpu() -> Iterable[int]: """ Yield CPU numbers of all possible CPUs Yields: :obj:`int`: Number of a possible CPU location """ for cpu in TypesCPUClass.cpus_possible: yield cpu
[docs]def highest_possible_cpu_nr() -> int: """ Return The highest possible CPU number Returns: :obj:`int`: The highest possible CPU number """ if not TypesCPUClass.cpus_possible: raise DelayedAttributeError('cpus_possible') return TypesCPUClass.cpus_possible[-1]
symbol_cbs = SymbolCallbacks([('cpu_online_mask', TypesCPUClass.setup_online_mask), ('__cpu_online_mask', TypesCPUClass.setup_online_mask), ('cpu_possible_mask', TypesCPUClass.setup_possible_mask), ('__cpu_possible_mask', TypesCPUClass.setup_possible_mask)])