mirror of
				https://github.com/ARM-software/workload-automation.git
				synced 2025-10-31 07:04:17 +00:00 
			
		
		
		
	wa/types: Add cpu_mask type
Add a cpu_mask type to allow for users to use a consistent way of representing a cpus mask with properties to provide conversions between the various required forms. The mask can be specified directly as a mask, as a list of cpus indexes or a sysfs-style string. Also add support for the type to be serialized/deserialzed for the json and yaml serializers.
This commit is contained in:
		| @@ -52,7 +52,7 @@ import dateutil.parser | ||||
|  | ||||
| from wa.framework.exception import SerializerSyntaxError | ||||
| from wa.utils.misc import isiterable | ||||
| from wa.utils.types import regex_type, none_type, level | ||||
| from wa.utils.types import regex_type, none_type, level, cpu_mask | ||||
|  | ||||
|  | ||||
| __all__ = [ | ||||
| @@ -91,6 +91,8 @@ class WAJSONEncoder(_json.JSONEncoder): | ||||
|             return 'DATET:{}'.format(obj.isoformat()) | ||||
|         elif isinstance(obj, level): | ||||
|             return 'LEVEL:{}:{}'.format(obj.name, obj.value) | ||||
|         elif isinstance(obj, cpu_mask): | ||||
|             return 'CPUMASK:{}'.format(obj.mask()) | ||||
|         else: | ||||
|             return _json.JSONEncoder.default(self, obj) | ||||
|  | ||||
| @@ -111,6 +113,9 @@ class WAJSONDecoder(_json.JSONDecoder): | ||||
|                 elif v.startswith('LEVEL:'): | ||||
|                     _, name, value = v.split(':', 2) | ||||
|                     return level(name, value) | ||||
|                 elif v.startswith('CPUMASK:'): | ||||
|                     _, value = v.split(':', 1) | ||||
|                     return cpu_mask(value) | ||||
|  | ||||
|             return v | ||||
|  | ||||
| @@ -156,6 +161,7 @@ class json(object): | ||||
| _mapping_tag = _yaml.resolver.BaseResolver.DEFAULT_MAPPING_TAG | ||||
| _regex_tag = u'tag:wa:regex' | ||||
| _level_tag = u'tag:wa:level' | ||||
| _cpu_mask_tag = u'tag:wa:cpu_mask' | ||||
|  | ||||
|  | ||||
| def _wa_dict_representer(dumper, data): | ||||
| @@ -170,6 +176,9 @@ def _wa_level_representer(dumper, data): | ||||
|     text = '{}:{}'.format(data.name, data.level) | ||||
|     return dumper.represent_scalar(_level_tag, text) | ||||
|  | ||||
| def _wa_cpu_mask_representer(dumper, data): | ||||
|     return dumper.represent_scalar(_cpu_mask_tag, data.mask()) | ||||
|  | ||||
| def _wa_dict_constructor(loader, node): | ||||
|     pairs = loader.construct_pairs(node) | ||||
|     seen_keys = set() | ||||
| @@ -190,13 +199,19 @@ def _wa_level_constructor(loader, node): | ||||
|     name, value = value.split(':', 1) | ||||
|     return level(name, value) | ||||
|  | ||||
| def _wa_cpu_mask_constructor(loader, node): | ||||
|     value = loader.construct_scalar(node) | ||||
|     return cpu_mask(value) | ||||
|  | ||||
|  | ||||
| _yaml.add_representer(OrderedDict, _wa_dict_representer) | ||||
| _yaml.add_representer(regex_type, _wa_regex_representer) | ||||
| _yaml.add_representer(level, _wa_level_representer) | ||||
| _yaml.add_representer(cpu_mask, _wa_cpu_mask_representer) | ||||
| _yaml.add_constructor(_mapping_tag, _wa_dict_constructor) | ||||
| _yaml.add_constructor(_regex_tag, _wa_regex_constructor) | ||||
| _yaml.add_constructor(_level_tag, _wa_level_constructor) | ||||
| _yaml.add_constructor(_cpu_mask_tag, _wa_cpu_mask_constructor) | ||||
|  | ||||
|  | ||||
| class yaml(object): | ||||
|   | ||||
| @@ -36,7 +36,8 @@ from copy import copy | ||||
|  | ||||
| from devlib.utils.types import identifier, boolean, integer, numeric, caseless_string | ||||
|  | ||||
| from wa.utils.misc import isiterable | ||||
| from wa.utils.misc import (isiterable, list_to_ranges, list_to_mask, | ||||
|                            mask_to_list, ranges_to_list) | ||||
|  | ||||
|  | ||||
| def list_of_strs(value): | ||||
| @@ -741,3 +742,61 @@ class ParameterDict(dict): | ||||
|             else: | ||||
|                 for k, v in d.iteritems(): | ||||
|                     self[k] = v | ||||
|  | ||||
|  | ||||
| class cpu_mask(object): | ||||
|     """ | ||||
|     A class to allow for a consistent way of representing a cpus mask with | ||||
|     methods to provide conversions between the various required forms. The | ||||
|     mask can be specified directly as a mask, as a list of cpus indexes or a | ||||
|     sysfs-style string. | ||||
|     """ | ||||
|     @staticmethod | ||||
|     def from_pod(pod): | ||||
|         return cpu_mask(int(pod['cpu_mask'])) | ||||
|  | ||||
|     def __init__(self, cpus): | ||||
|         self._mask = 0 | ||||
|         if isinstance(cpus, int): | ||||
|             self._mask = cpus | ||||
|         elif isinstance(cpus, basestring): | ||||
|             if cpus[:2] == '0x' or cpus[:2] == '0X': | ||||
|                 self._mask = int(cpus, 16) | ||||
|             else: | ||||
|                 self._mask = list_to_mask(ranges_to_list(cpus)) | ||||
|         elif isinstance(cpus, list): | ||||
|             self._mask = list_to_mask(cpus) | ||||
|         elif isinstance(cpus, cpu_mask): | ||||
|             self._mask = cpus._mask | ||||
|         else: | ||||
|             msg = 'Unknown conversion from {} to cpu mask' | ||||
|             raise ValueError(msg.format(cpus)) | ||||
|  | ||||
|     def __bool__(self): | ||||
|         """Allow for use in comparisons to check if a mask has been set""" | ||||
|         return bool(self._mask) | ||||
|  | ||||
|     __nonzero__ = __bool__ | ||||
|  | ||||
|     def __repr__(self): | ||||
|         return 'cpu_mask: {}'.format(self.mask()) | ||||
|  | ||||
|     __str__ = __repr__ | ||||
|  | ||||
|     def list(self): | ||||
|         """Returns a list of the indexes of bits that are set in the mask.""" | ||||
|         return list(reversed(mask_to_list(self._mask))) | ||||
|  | ||||
|     def mask(self, prefix=True): | ||||
|         """Returns a hex representation of the mask with an optional prefix""" | ||||
|         if prefix: | ||||
|             return hex(self._mask) | ||||
|         else: | ||||
|             return hex(self._mask)[2:] | ||||
|  | ||||
|     def ranges(self): | ||||
|         """"Returns a sysfs-style ranges string""" | ||||
|         return list_to_ranges(self.list()) | ||||
|  | ||||
|     def to_pod(self): | ||||
|         return {'cpu_mask': self._mask} | ||||
|   | ||||
		Reference in New Issue
	
	Block a user