Sergei Trofimov | 4e6afe9 | 2015-10-09 09:30:04 +0100 | [diff] [blame^] | 1 | import logging |
| 2 | |
| 3 | |
| 4 | class Platform(object): |
| 5 | |
| 6 | @property |
| 7 | def number_of_clusters(self): |
| 8 | return len(set(self.core_clusters)) |
| 9 | |
| 10 | def __init__(self, |
| 11 | name=None, |
| 12 | core_names=None, |
| 13 | core_clusters=None, |
| 14 | big_core=None, |
| 15 | model=None, |
| 16 | modules=None, |
| 17 | ): |
| 18 | self.name = name |
| 19 | self.core_names = core_names or [] |
| 20 | self.core_clusters = core_clusters or [] |
| 21 | self.big_core = big_core |
| 22 | self.little_core = None |
| 23 | self.model = model |
| 24 | self.modules = modules or [] |
| 25 | self.logger = logging.getLogger(self.name) |
| 26 | if not self.core_clusters and self.core_names: |
| 27 | self._set_core_clusters_from_core_names() |
| 28 | self._validate() |
| 29 | |
| 30 | def init_target_connection(self, target): |
| 31 | # May be ovewritten by subclasses to provide target-specific |
| 32 | # connection initialisation. |
| 33 | pass |
| 34 | |
| 35 | def update_from_target(self, target): |
| 36 | if not self.core_names: |
| 37 | self.core_names = target.cpuinfo.cpu_names |
| 38 | self._set_core_clusters_from_core_names() |
| 39 | if not self.big_core and self.number_of_clusters == 2: |
| 40 | big_idx = self.core_clusters.index(max(self.core_clusters)) |
| 41 | self.big_core = self.core_names[big_idx] |
| 42 | if not self.core_clusters and self.core_names: |
| 43 | self._set_core_clusters_from_core_names() |
| 44 | if not self.model: |
| 45 | self._set_model_from_target(target) |
| 46 | if not self.name: |
| 47 | self.name = self.model |
| 48 | self._validate() |
| 49 | |
| 50 | def _set_core_clusters_from_core_names(self): |
| 51 | self.core_clusters = [] |
| 52 | clusters = [] |
| 53 | for cn in self.core_names: |
| 54 | if cn not in clusters: |
| 55 | clusters.append(cn) |
| 56 | self.core_clusters.append(clusters.index(cn)) |
| 57 | |
| 58 | def _set_model_from_target(self, target): |
| 59 | if target.os == 'android': |
| 60 | self.model = target.getprop('ro.product.model') |
| 61 | elif target.is_rooted: |
| 62 | try: |
| 63 | self.model = target.execute('dmidecode -s system-version', |
| 64 | as_root=True).strip() |
| 65 | except Exception: # pylint: disable=broad-except |
| 66 | pass # this is best-effort |
| 67 | |
| 68 | def _validate(self): |
| 69 | if len(self.core_names) != len(self.core_clusters): |
| 70 | raise ValueError('core_names and core_clusters are of different lengths.') |
| 71 | if self.big_core and self.number_of_clusters != 2: |
| 72 | raise ValueError('attempting to set big_core on non-big.LITTLE device. ' |
| 73 | '(number of clusters is not 2)') |
| 74 | if self.big_core and self.big_core not in self.core_names: |
| 75 | message = 'Invalid big_core value "{}"; must be in [{}]' |
| 76 | raise ValueError(message.format(self.big_core, |
| 77 | ', '.join(set(self.core_names)))) |
| 78 | if self.big_core: |
| 79 | little_idx = self.core_clusters.index(min(self.core_clusters)) |
| 80 | self.little_core = self.core_names[little_idx] |
| 81 | |