148f512ceSopenharmony_ci#!/usr/bin/env python 248f512ceSopenharmony_ci# -*- coding: utf-8 -*- 348f512ceSopenharmony_ci# Copyright (c) 2021 Huawei Device Co., Ltd. 448f512ceSopenharmony_ci# Licensed under the Apache License, Version 2.0 (the "License"); 548f512ceSopenharmony_ci# you may not use this file except in compliance with the License. 648f512ceSopenharmony_ci# You may obtain a copy of the License at 748f512ceSopenharmony_ci# 848f512ceSopenharmony_ci# http://www.apache.org/licenses/LICENSE-2.0 948f512ceSopenharmony_ci# 1048f512ceSopenharmony_ci# Unless required by applicable law or agreed to in writing, software 1148f512ceSopenharmony_ci# distributed under the License is distributed on an "AS IS" BASIS, 1248f512ceSopenharmony_ci# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1348f512ceSopenharmony_ci# See the License for the specific language governing permissions and 1448f512ceSopenharmony_ci# limitations under the License. 1548f512ceSopenharmony_ci 1648f512ceSopenharmony_ciimport sys 1748f512ceSopenharmony_ciimport subprocess 1848f512ceSopenharmony_ciimport argparse 1948f512ceSopenharmony_ciimport time 2048f512ceSopenharmony_ciimport os 2148f512ceSopenharmony_ciimport shutil 2248f512ceSopenharmony_ciimport platform 2348f512ceSopenharmony_cifrom ctypes import c_char_p 2448f512ceSopenharmony_cifrom ctypes import cdll 2548f512ceSopenharmony_ci 2648f512ceSopenharmony_ciIS_DEBUG = False 2748f512ceSopenharmony_ciHDC_NAME = "hdc" 2848f512ceSopenharmony_ciSYMBOL_FILES_DIR = '/data/local/tmp/local_libs/' 2948f512ceSopenharmony_ciBUILD_ID_FILE = "build_id_list" 3048f512ceSopenharmony_ciEXPECTED_TOOLS = { 3148f512ceSopenharmony_ci HDC_NAME: { 3248f512ceSopenharmony_ci 'is_binutils': False, 3348f512ceSopenharmony_ci 'test_option': 'version', 3448f512ceSopenharmony_ci 'path_in_tool': '../platform-tools/hdc', 3548f512ceSopenharmony_ci } 3648f512ceSopenharmony_ci} 3748f512ceSopenharmony_ci 3848f512ceSopenharmony_ci 3948f512ceSopenharmony_cidef get_lib(): 4048f512ceSopenharmony_ci script_dir = os.path.dirname(os.path.realpath(__file__)) 4148f512ceSopenharmony_ci system_type = platform.system().lower() 4248f512ceSopenharmony_ci if system_type == "windows": 4348f512ceSopenharmony_ci lib_path = os.path.join(script_dir, "bin", system_type, 4448f512ceSopenharmony_ci "x86_64", "libhiperf_report.dll") 4548f512ceSopenharmony_ci elif system_type == "linux": 4648f512ceSopenharmony_ci lib_path = os.path.join(script_dir, "bin", system_type, 4748f512ceSopenharmony_ci "x86_64", "libhiperf_report.so") 4848f512ceSopenharmony_ci elif system_type == "darwin": 4948f512ceSopenharmony_ci lib_path = os.path.join(script_dir, "bin", system_type, 5048f512ceSopenharmony_ci "x86_64", "libhiperf_report.dylib") 5148f512ceSopenharmony_ci else: 5248f512ceSopenharmony_ci print("Un Support System Platform") 5348f512ceSopenharmony_ci raise RuntimeError 5448f512ceSopenharmony_ci if not os.path.exists(lib_path): 5548f512ceSopenharmony_ci print("{} does not exist!".format(lib_path)) 5648f512ceSopenharmony_ci raise RuntimeError 5748f512ceSopenharmony_ci return cdll.LoadLibrary(lib_path) 5848f512ceSopenharmony_ci 5948f512ceSopenharmony_ci 6048f512ceSopenharmony_cidef remove(files): 6148f512ceSopenharmony_ci if os.path.isfile(files): 6248f512ceSopenharmony_ci os.remove(files) 6348f512ceSopenharmony_ci elif os.path.isdir(files): 6448f512ceSopenharmony_ci shutil.rmtree(files, ignore_errors=True) 6548f512ceSopenharmony_ci 6648f512ceSopenharmony_ci 6748f512ceSopenharmony_cidef is_elf_file(path): 6848f512ceSopenharmony_ci if os.path.isfile(path): 6948f512ceSopenharmony_ci with open(path, 'rb') as file_bin: 7048f512ceSopenharmony_ci data = file_bin.read(4) 7148f512ceSopenharmony_ci if len(data) == 4 and bytes_to_str(data) == '\x7fELF': 7248f512ceSopenharmony_ci return True 7348f512ceSopenharmony_ci return False 7448f512ceSopenharmony_ci 7548f512ceSopenharmony_ci 7648f512ceSopenharmony_cidef get_architecture(elf_path): 7748f512ceSopenharmony_ci if is_elf_file(elf_path): 7848f512ceSopenharmony_ci my_lib = get_lib() 7948f512ceSopenharmony_ci my_lib.ReportGetElfArch.restype = c_char_p 8048f512ceSopenharmony_ci ret = my_lib.ReportGetElfArch(elf_path.encode()) 8148f512ceSopenharmony_ci return ret.decode() 8248f512ceSopenharmony_ci return 'unknown' 8348f512ceSopenharmony_ci 8448f512ceSopenharmony_ci 8548f512ceSopenharmony_cidef get_build_id(elf_path): 8648f512ceSopenharmony_ci if is_elf_file(elf_path): 8748f512ceSopenharmony_ci my_lib = get_lib() 8848f512ceSopenharmony_ci my_lib.ReportGetBuildId.restype = c_char_p 8948f512ceSopenharmony_ci ret = my_lib.ReportGetBuildId(elf_path.encode()) 9048f512ceSopenharmony_ci return ret.decode() 9148f512ceSopenharmony_ci return '' 9248f512ceSopenharmony_ci 9348f512ceSopenharmony_ci 9448f512ceSopenharmony_cidef get_hiperf_binary_path(arch, binary_name): 9548f512ceSopenharmony_ci if arch == 'aarch64': 9648f512ceSopenharmony_ci arch = 'arm64' 9748f512ceSopenharmony_ci script_dir = os.path.dirname(os.path.realpath(__file__)) 9848f512ceSopenharmony_ci arch_dir = os.path.join(script_dir, "bin", "ohos", arch) 9948f512ceSopenharmony_ci if not os.path.isdir(arch_dir): 10048f512ceSopenharmony_ci raise Exception("can't find arch directory: %s" % arch_dir) 10148f512ceSopenharmony_ci binary_path = os.path.join(arch_dir, binary_name) 10248f512ceSopenharmony_ci if not os.path.isfile(binary_path): 10348f512ceSopenharmony_ci raise Exception("can't find binary: %s" % binary_path) 10448f512ceSopenharmony_ci return binary_path 10548f512ceSopenharmony_ci 10648f512ceSopenharmony_ci 10748f512ceSopenharmony_cidef str_to_bytes(str_value): 10848f512ceSopenharmony_ci if not (sys.version_info >= (3, 0)): 10948f512ceSopenharmony_ci return str_value 11048f512ceSopenharmony_ci return str_value.encode('utf-8') 11148f512ceSopenharmony_ci 11248f512ceSopenharmony_ci 11348f512ceSopenharmony_cidef bytes_to_str(bytes_value): 11448f512ceSopenharmony_ci if not bytes_value: 11548f512ceSopenharmony_ci return '' 11648f512ceSopenharmony_ci if not (sys.version_info >= (3, 0)): 11748f512ceSopenharmony_ci return bytes_value 11848f512ceSopenharmony_ci return bytes_value.decode('utf-8') 11948f512ceSopenharmony_ci 12048f512ceSopenharmony_ci 12148f512ceSopenharmony_cidef executable_file_available(executable, option='--help'): 12248f512ceSopenharmony_ci try: 12348f512ceSopenharmony_ci print([executable, option]) 12448f512ceSopenharmony_ci subproc = subprocess.Popen([executable, option], 12548f512ceSopenharmony_ci stdout=subprocess.PIPE, 12648f512ceSopenharmony_ci stderr=subprocess.PIPE) 12748f512ceSopenharmony_ci subproc.communicate(timeout=5) 12848f512ceSopenharmony_ci return subproc.returncode == 0 12948f512ceSopenharmony_ci except OSError: 13048f512ceSopenharmony_ci return False 13148f512ceSopenharmony_ci 13248f512ceSopenharmony_ci 13348f512ceSopenharmony_cidef dir_check(arg): 13448f512ceSopenharmony_ci path = os.path.realpath(arg) 13548f512ceSopenharmony_ci if not os.path.isdir(path): 13648f512ceSopenharmony_ci raise argparse.ArgumentTypeError('{} is not a directory.'.format(path)) 13748f512ceSopenharmony_ci return path 13848f512ceSopenharmony_ci 13948f512ceSopenharmony_ci 14048f512ceSopenharmony_cidef file_check(arg): 14148f512ceSopenharmony_ci path = os.path.realpath(arg) 14248f512ceSopenharmony_ci if not os.path.isfile(path): 14348f512ceSopenharmony_ci raise argparse.ArgumentTypeError('{} is not a file.'.format(path)) 14448f512ceSopenharmony_ci return path 14548f512ceSopenharmony_ci 14648f512ceSopenharmony_ci 14748f512ceSopenharmony_cidef get_arg_list(arg_list): 14848f512ceSopenharmony_ci res = [] 14948f512ceSopenharmony_ci if arg_list: 15048f512ceSopenharmony_ci for arg in arg_list: 15148f512ceSopenharmony_ci res += arg 15248f512ceSopenharmony_ci return res 15348f512ceSopenharmony_ci 15448f512ceSopenharmony_ci 15548f512ceSopenharmony_cidef get_arch(arch): 15648f512ceSopenharmony_ci if 'aarch64' in arch: 15748f512ceSopenharmony_ci return 'arm64' 15848f512ceSopenharmony_ci if 'arm' in arch: 15948f512ceSopenharmony_ci return 'arm' 16048f512ceSopenharmony_ci if 'x86_64' in arch or "amd64" in arch: 16148f512ceSopenharmony_ci return 'x86_64' 16248f512ceSopenharmony_ci if '86' in arch: 16348f512ceSopenharmony_ci return 'x86' 16448f512ceSopenharmony_ci raise Exception('unsupported architecture: %s' % arch.strip()) 16548f512ceSopenharmony_ci 16648f512ceSopenharmony_ci 16748f512ceSopenharmony_cidef find_tool_path(tool, tool_path=None): 16848f512ceSopenharmony_ci if tool not in EXPECTED_TOOLS: 16948f512ceSopenharmony_ci return None 17048f512ceSopenharmony_ci tool_info = EXPECTED_TOOLS[tool] 17148f512ceSopenharmony_ci test_option = tool_info.get('test_option', '--help') 17248f512ceSopenharmony_ci path_in_tool = tool_info['path_in_tool'] 17348f512ceSopenharmony_ci path_in_tool = path_in_tool.replace('/', os.sep) 17448f512ceSopenharmony_ci 17548f512ceSopenharmony_ci # 1. Find tool in the given tool path. 17648f512ceSopenharmony_ci if tool_path: 17748f512ceSopenharmony_ci path = os.path.join(tool_path, path_in_tool) 17848f512ceSopenharmony_ci if executable_file_available(path, test_option): 17948f512ceSopenharmony_ci return path 18048f512ceSopenharmony_ci 18148f512ceSopenharmony_ci # 2. Find tool in the tool directory containing hiperf scripts. 18248f512ceSopenharmony_ci path = os.path.join('../..', path_in_tool) 18348f512ceSopenharmony_ci if executable_file_available(path, test_option): 18448f512ceSopenharmony_ci return path 18548f512ceSopenharmony_ci 18648f512ceSopenharmony_ci # 3. Find tool in $PATH. 18748f512ceSopenharmony_ci if executable_file_available(tool, test_option): 18848f512ceSopenharmony_ci return tool 18948f512ceSopenharmony_ci 19048f512ceSopenharmony_ci return None 19148f512ceSopenharmony_ci 19248f512ceSopenharmony_ci 19348f512ceSopenharmony_ciclass HdcInterface: 19448f512ceSopenharmony_ci def __init__(self, root_authority=True): 19548f512ceSopenharmony_ci hdc_path = find_tool_path(HDC_NAME) 19648f512ceSopenharmony_ci if not hdc_path: 19748f512ceSopenharmony_ci raise Exception("Can't find hdc in PATH environment.") 19848f512ceSopenharmony_ci self.hdc_path = hdc_path 19948f512ceSopenharmony_ci self.root_authority = root_authority 20048f512ceSopenharmony_ci 20148f512ceSopenharmony_ci def run_hdc_cmd(self, hdc_args, log_output=True): 20248f512ceSopenharmony_ci hdc_args = [self.hdc_path] + hdc_args 20348f512ceSopenharmony_ci if IS_DEBUG: 20448f512ceSopenharmony_ci print('run hdc cmd: %s' % hdc_args) 20548f512ceSopenharmony_ci subproc = subprocess.Popen(hdc_args, stdout=subprocess.PIPE) 20648f512ceSopenharmony_ci (out, _) = subproc.communicate() 20748f512ceSopenharmony_ci out = bytes_to_str(out) 20848f512ceSopenharmony_ci return_code = subproc.returncode 20948f512ceSopenharmony_ci result = (return_code == 0) 21048f512ceSopenharmony_ci if out and hdc_args[1] != 'file send' and \ 21148f512ceSopenharmony_ci hdc_args[1] != 'file recv': 21248f512ceSopenharmony_ci if log_output: 21348f512ceSopenharmony_ci print(out) 21448f512ceSopenharmony_ci if IS_DEBUG: 21548f512ceSopenharmony_ci print('run hdc cmd: %s [result %s]' % (hdc_args, result)) 21648f512ceSopenharmony_ci return result, out 21748f512ceSopenharmony_ci 21848f512ceSopenharmony_ci def check_run(self, hdc_args): 21948f512ceSopenharmony_ci result, out = self.run_hdc_cmd(hdc_args) 22048f512ceSopenharmony_ci if not result: 22148f512ceSopenharmony_ci raise Exception('run "hdc %s" failed' % hdc_args) 22248f512ceSopenharmony_ci return out 22348f512ceSopenharmony_ci 22448f512ceSopenharmony_ci def _not_use_root(self): 22548f512ceSopenharmony_ci result, out = self.run_hdc_cmd(['shell', 'whoami']) 22648f512ceSopenharmony_ci if not result or 'root' not in out: 22748f512ceSopenharmony_ci return 22848f512ceSopenharmony_ci print('unroot hdc') 22948f512ceSopenharmony_ci self.run_hdc_cmd(['unroot']) 23048f512ceSopenharmony_ci time.sleep(1) 23148f512ceSopenharmony_ci self.run_hdc_cmd(['wait-for-device']) 23248f512ceSopenharmony_ci 23348f512ceSopenharmony_ci def switch_root(self): 23448f512ceSopenharmony_ci if not self.root_authority: 23548f512ceSopenharmony_ci self._not_use_root() 23648f512ceSopenharmony_ci return False 23748f512ceSopenharmony_ci result, out = self.run_hdc_cmd(['shell', 'whoami']) 23848f512ceSopenharmony_ci if not result: 23948f512ceSopenharmony_ci return False 24048f512ceSopenharmony_ci if 'root' in out: 24148f512ceSopenharmony_ci return True 24248f512ceSopenharmony_ci build_type = self.get_attribute('ro.build.type') 24348f512ceSopenharmony_ci if build_type == 'user': 24448f512ceSopenharmony_ci return False 24548f512ceSopenharmony_ci self.run_hdc_cmd(['root']) 24648f512ceSopenharmony_ci time.sleep(1) 24748f512ceSopenharmony_ci self.run_hdc_cmd(['wait-for-device']) 24848f512ceSopenharmony_ci result, out = self.run_hdc_cmd(['shell', 'whoami']) 24948f512ceSopenharmony_ci return result and 'root' in out 25048f512ceSopenharmony_ci 25148f512ceSopenharmony_ci def get_attribute(self, name): 25248f512ceSopenharmony_ci result, out = self.run_hdc_cmd(['shell', 'getprop', 25348f512ceSopenharmony_ci name]) 25448f512ceSopenharmony_ci if result: 25548f512ceSopenharmony_ci return out 25648f512ceSopenharmony_ci 25748f512ceSopenharmony_ci def get_device_architecture(self): 25848f512ceSopenharmony_ci output = self.check_run(['shell', 'uname', '-m']) 25948f512ceSopenharmony_ci return get_arch(output) 26048f512ceSopenharmony_ci 26148f512ceSopenharmony_ci 26248f512ceSopenharmony_ciclass ElfStruct: 26348f512ceSopenharmony_ci def __init__(self, path, lib_name): 26448f512ceSopenharmony_ci self.path = path 26548f512ceSopenharmony_ci self.name = lib_name 26648f512ceSopenharmony_ci 26748f512ceSopenharmony_ci 26848f512ceSopenharmony_ciclass LocalLibDownload: 26948f512ceSopenharmony_ci 27048f512ceSopenharmony_ci def __init__(self, device_arch, hdc): 27148f512ceSopenharmony_ci self.hdc = hdc 27248f512ceSopenharmony_ci self.device_arch = device_arch 27348f512ceSopenharmony_ci 27448f512ceSopenharmony_ci self.build_id_map_of_host = {} 27548f512ceSopenharmony_ci self.build_id_map_of_device = {} 27648f512ceSopenharmony_ci self.host_lib_count_map = {} 27748f512ceSopenharmony_ci self.request_architectures = self.__get_need_architectures(device_arch) 27848f512ceSopenharmony_ci 27948f512ceSopenharmony_ci def get_host_local_libs(self, local_lib_dir): 28048f512ceSopenharmony_ci self.build_id_map_of_host.clear() 28148f512ceSopenharmony_ci for root, dirs, files in os.walk(local_lib_dir): 28248f512ceSopenharmony_ci for name in files: 28348f512ceSopenharmony_ci if name.endswith('.so'): 28448f512ceSopenharmony_ci self.__append_host_local_lib(os.path.join(root, name), 28548f512ceSopenharmony_ci name) 28648f512ceSopenharmony_ci 28748f512ceSopenharmony_ci def get_device_local_libs(self): 28848f512ceSopenharmony_ci self.build_id_map_of_device.clear() 28948f512ceSopenharmony_ci if os.path.exists(BUILD_ID_FILE): 29048f512ceSopenharmony_ci remove(BUILD_ID_FILE) 29148f512ceSopenharmony_ci self.hdc.check_run(['shell', 'mkdir', '-p', SYMBOL_FILES_DIR]) 29248f512ceSopenharmony_ci self.hdc.run_hdc_cmd(['file recv', SYMBOL_FILES_DIR + BUILD_ID_FILE]) 29348f512ceSopenharmony_ci if os.path.isfile(BUILD_ID_FILE): 29448f512ceSopenharmony_ci with open(BUILD_ID_FILE, 'rb') as file_bin: 29548f512ceSopenharmony_ci for line in file_bin.readlines(): 29648f512ceSopenharmony_ci line = bytes_to_str(line).strip() 29748f512ceSopenharmony_ci items = line.split('=') 29848f512ceSopenharmony_ci if len(items) == 2: 29948f512ceSopenharmony_ci self.build_id_map_of_device[items[0]] = items[1] 30048f512ceSopenharmony_ci remove(BUILD_ID_FILE) 30148f512ceSopenharmony_ci 30248f512ceSopenharmony_ci def update_device_local_libs(self): 30348f512ceSopenharmony_ci # Send local libs to device. 30448f512ceSopenharmony_ci for build_id in self.build_id_map_of_host: 30548f512ceSopenharmony_ci if build_id not in self.build_id_map_of_device: 30648f512ceSopenharmony_ci elf_struct = self.build_id_map_of_host[build_id] 30748f512ceSopenharmony_ci self.hdc.check_run(['file send', elf_struct.path, 30848f512ceSopenharmony_ci SYMBOL_FILES_DIR + elf_struct.name]) 30948f512ceSopenharmony_ci 31048f512ceSopenharmony_ci # Remove Device lib while local libs not exist on host. 31148f512ceSopenharmony_ci for build_id in self.build_id_map_of_device: 31248f512ceSopenharmony_ci if build_id not in self.build_id_map_of_host: 31348f512ceSopenharmony_ci name = self.build_id_map_of_device[build_id] 31448f512ceSopenharmony_ci self.hdc.run_hdc_cmd(['shell', 'rm', SYMBOL_FILES_DIR + name]) 31548f512ceSopenharmony_ci 31648f512ceSopenharmony_ci # Send new build_id_list to device. 31748f512ceSopenharmony_ci with open(BUILD_ID_FILE, 'wb') as file_bin: 31848f512ceSopenharmony_ci for build_id in self.build_id_map_of_host: 31948f512ceSopenharmony_ci str_bytes = str_to_bytes('%s=%s\n' % (build_id, 32048f512ceSopenharmony_ci self.build_id_map_of_host[ 32148f512ceSopenharmony_ci build_id].name)) 32248f512ceSopenharmony_ci file_bin.write(str_bytes) 32348f512ceSopenharmony_ci 32448f512ceSopenharmony_ci self.hdc.check_run(['file send', BUILD_ID_FILE, 32548f512ceSopenharmony_ci SYMBOL_FILES_DIR + BUILD_ID_FILE]) 32648f512ceSopenharmony_ci remove(BUILD_ID_FILE) 32748f512ceSopenharmony_ci 32848f512ceSopenharmony_ci def __append_host_local_lib(self, path, name): 32948f512ceSopenharmony_ci build_id = get_build_id(path) 33048f512ceSopenharmony_ci if not build_id: 33148f512ceSopenharmony_ci return 33248f512ceSopenharmony_ci arch = get_architecture(path) 33348f512ceSopenharmony_ci if arch not in self.request_architectures: 33448f512ceSopenharmony_ci return 33548f512ceSopenharmony_ci 33648f512ceSopenharmony_ci elf_struct = self.build_id_map_of_host.get(build_id) 33748f512ceSopenharmony_ci if not elf_struct: 33848f512ceSopenharmony_ci count = self.host_lib_count_map.get(name, 0) 33948f512ceSopenharmony_ci self.host_lib_count_map[name] = count + 1 34048f512ceSopenharmony_ci if count == 0: 34148f512ceSopenharmony_ci unique_name = name 34248f512ceSopenharmony_ci else: 34348f512ceSopenharmony_ci unique_name = name + '_' + count 34448f512ceSopenharmony_ci self.build_id_map_of_host[build_id] = ElfStruct(path, 34548f512ceSopenharmony_ci unique_name) 34648f512ceSopenharmony_ci else: 34748f512ceSopenharmony_ci elf_struct.path = path 34848f512ceSopenharmony_ci 34948f512ceSopenharmony_ci @classmethod 35048f512ceSopenharmony_ci def __get_need_architectures(self, device_arch): 35148f512ceSopenharmony_ci if device_arch == 'x86_64': 35248f512ceSopenharmony_ci return ['x86', 'x86_64'] 35348f512ceSopenharmony_ci if device_arch == 'x86': 35448f512ceSopenharmony_ci return ['x86'] 35548f512ceSopenharmony_ci if device_arch == 'arm64': 35648f512ceSopenharmony_ci return ['arm', 'arm64'] 35748f512ceSopenharmony_ci if device_arch == 'arm': 35848f512ceSopenharmony_ci return ['arm'] 35948f512ceSopenharmony_ci return [] 36048f512ceSopenharmony_ci 36148f512ceSopenharmony_ci 36248f512ceSopenharmony_ciclass PerformanceProfile: 36348f512ceSopenharmony_ci """Class of all Profilers.""" 36448f512ceSopenharmony_ci 36548f512ceSopenharmony_ci def __init__(self, args, control_module=""): 36648f512ceSopenharmony_ci self.args = args 36748f512ceSopenharmony_ci self.hdc = HdcInterface(root_authority=not args.not_hdc_root) 36848f512ceSopenharmony_ci self.device_root = self.hdc.switch_root() 36948f512ceSopenharmony_ci self.device_arch = self.hdc.get_device_architecture() 37048f512ceSopenharmony_ci self.record_subproc = None 37148f512ceSopenharmony_ci self.is_control = bool(control_module) 37248f512ceSopenharmony_ci self.control_mode = control_module 37348f512ceSopenharmony_ci 37448f512ceSopenharmony_ci def profile(self): 37548f512ceSopenharmony_ci if not self.is_control or self.control_mode == "prepare": 37648f512ceSopenharmony_ci print('prepare profiling') 37748f512ceSopenharmony_ci self.download() 37848f512ceSopenharmony_ci print('start profiling') 37948f512ceSopenharmony_ci if not self.combine_args(): 38048f512ceSopenharmony_ci return 38148f512ceSopenharmony_ci else: 38248f512ceSopenharmony_ci self.exec_control() 38348f512ceSopenharmony_ci self.profiling() 38448f512ceSopenharmony_ci 38548f512ceSopenharmony_ci if not self.is_control: 38648f512ceSopenharmony_ci print('pull profiling data') 38748f512ceSopenharmony_ci self.get_profiling_data() 38848f512ceSopenharmony_ci if self.control_mode == "stop": 38948f512ceSopenharmony_ci self.wait_data_generate_done() 39048f512ceSopenharmony_ci print('profiling is finished.') 39148f512ceSopenharmony_ci 39248f512ceSopenharmony_ci def download(self): 39348f512ceSopenharmony_ci """Prepare recording. """ 39448f512ceSopenharmony_ci if self.args.local_lib_dir: 39548f512ceSopenharmony_ci self.download_libs() 39648f512ceSopenharmony_ci 39748f512ceSopenharmony_ci def download_libs(self): 39848f512ceSopenharmony_ci executor = LocalLibDownload(self.device_arch, self.hdc) 39948f512ceSopenharmony_ci executor.get_host_local_libs(self.args.local_lib_dir) 40048f512ceSopenharmony_ci executor.get_device_local_libs() 40148f512ceSopenharmony_ci executor.update_device_local_libs() 40248f512ceSopenharmony_ci 40348f512ceSopenharmony_ci def combine_args(self): 40448f512ceSopenharmony_ci if self.args.package_name: 40548f512ceSopenharmony_ci if self.args.ability: 40648f512ceSopenharmony_ci self.kill_process() 40748f512ceSopenharmony_ci self.start_profiling(['--app', self.args.package_name]) 40848f512ceSopenharmony_ci if self.args.ability: 40948f512ceSopenharmony_ci ability = self.args.package_name + '/' + self.args.ability 41048f512ceSopenharmony_ci start_cmd = ['shell', 'aa', 'start', '-a', ability] 41148f512ceSopenharmony_ci result = self.hdc.run_hdc_cmd(start_cmd) 41248f512ceSopenharmony_ci if not result: 41348f512ceSopenharmony_ci self.record_subproc.terminate() 41448f512ceSopenharmony_ci print("Can't start ability %s" % ability) 41548f512ceSopenharmony_ci return False 41648f512ceSopenharmony_ci # else: no need to start an ability. 41748f512ceSopenharmony_ci elif self.args.local_program: 41848f512ceSopenharmony_ci pid = self.hdc.check_run(['shell', 'pidof', 41948f512ceSopenharmony_ci self.args.local_program]) 42048f512ceSopenharmony_ci if not pid: 42148f512ceSopenharmony_ci print("Can't find pid of %s" % self.args.local_program) 42248f512ceSopenharmony_ci return False 42348f512ceSopenharmony_ci pid = int(pid) 42448f512ceSopenharmony_ci self.start_profiling(['-p', str(pid)]) 42548f512ceSopenharmony_ci elif self.args.cmd: 42648f512ceSopenharmony_ci cmds = self.args.cmd.split(' ') 42748f512ceSopenharmony_ci cmd = [cmd.replace("'", "") for cmd in cmds] 42848f512ceSopenharmony_ci self.start_profiling(cmd) 42948f512ceSopenharmony_ci elif self.args.pid: 43048f512ceSopenharmony_ci self.start_profiling(['-p', ','.join(self.args.pid)]) 43148f512ceSopenharmony_ci elif self.args.tid: 43248f512ceSopenharmony_ci self.start_profiling(['-t', ','.join(self.args.tid)]) 43348f512ceSopenharmony_ci elif self.args.system_wide: 43448f512ceSopenharmony_ci self.start_profiling(['-a']) 43548f512ceSopenharmony_ci return True 43648f512ceSopenharmony_ci 43748f512ceSopenharmony_ci def kill_process(self): 43848f512ceSopenharmony_ci if self.get_app_process(): 43948f512ceSopenharmony_ci self.hdc.check_run(['shell', 'aa', 'force-stop', self.args.app]) 44048f512ceSopenharmony_ci count = 0 44148f512ceSopenharmony_ci while True: 44248f512ceSopenharmony_ci time.sleep(1) 44348f512ceSopenharmony_ci pid = self.get_app_process() 44448f512ceSopenharmony_ci if not pid: 44548f512ceSopenharmony_ci break 44648f512ceSopenharmony_ci count += 1 44748f512ceSopenharmony_ci # 3 seconds exec kill 44848f512ceSopenharmony_ci if count >= 3: 44948f512ceSopenharmony_ci self.run_in_app_dir(['kill', '-9', str(pid)]) 45048f512ceSopenharmony_ci 45148f512ceSopenharmony_ci def get_app_process(self): 45248f512ceSopenharmony_ci result, output = self.hdc.run_hdc_cmd( 45348f512ceSopenharmony_ci ['shell', 'pidof', self.args.package_name]) 45448f512ceSopenharmony_ci return int(output) if result else None 45548f512ceSopenharmony_ci 45648f512ceSopenharmony_ci def run_in_app_dir(self, args): 45748f512ceSopenharmony_ci if self.device_root: 45848f512ceSopenharmony_ci hdc_args = ['shell', 'cd /data/data/' + self.args.package_name + 45948f512ceSopenharmony_ci ' && ' + (' '.join(args))] 46048f512ceSopenharmony_ci else: 46148f512ceSopenharmony_ci hdc_args = ['shell', 'run-as', self.args.package_name] + args 46248f512ceSopenharmony_ci return self.hdc.run_hdc_cmd(hdc_args, log_output=False) 46348f512ceSopenharmony_ci 46448f512ceSopenharmony_ci def start_profiling(self, selected_args): 46548f512ceSopenharmony_ci """Start hiperf reocrd process on device.""" 46648f512ceSopenharmony_ci record_options = self.args.record_options.split(' ') 46748f512ceSopenharmony_ci record_options = [cmd.replace("'", "") for cmd in record_options] 46848f512ceSopenharmony_ci if self.is_control: 46948f512ceSopenharmony_ci args = ['hiperf', 'record', 47048f512ceSopenharmony_ci '--control', self.control_mode, '-o', 47148f512ceSopenharmony_ci '/data/local/tmp/perf.data'] + record_options 47248f512ceSopenharmony_ci else: 47348f512ceSopenharmony_ci args = ['hiperf', 'record', '-o', 47448f512ceSopenharmony_ci '/data/local/tmp/perf.data'] + record_options 47548f512ceSopenharmony_ci if self.args.local_lib_dir and self.hdc.run_hdc_cmd( 47648f512ceSopenharmony_ci ['shell', 'ls', SYMBOL_FILES_DIR]): 47748f512ceSopenharmony_ci args += ['--symbol-dir', SYMBOL_FILES_DIR] 47848f512ceSopenharmony_ci args += selected_args 47948f512ceSopenharmony_ci hdc_args = [self.hdc.hdc_path, 'shell'] + args 48048f512ceSopenharmony_ci print('run hdc cmd: %s' % hdc_args) 48148f512ceSopenharmony_ci self.record_subproc = subprocess.Popen(hdc_args) 48248f512ceSopenharmony_ci 48348f512ceSopenharmony_ci def profiling(self): 48448f512ceSopenharmony_ci """ 48548f512ceSopenharmony_ci Wait until profiling finishes, or stop profiling when user 48648f512ceSopenharmony_ci presses Ctrl-C. 48748f512ceSopenharmony_ci """ 48848f512ceSopenharmony_ci 48948f512ceSopenharmony_ci try: 49048f512ceSopenharmony_ci return_code = self.record_subproc.wait() 49148f512ceSopenharmony_ci except KeyboardInterrupt: 49248f512ceSopenharmony_ci self.end_profiling() 49348f512ceSopenharmony_ci self.record_subproc = None 49448f512ceSopenharmony_ci return_code = 0 49548f512ceSopenharmony_ci print('profiling result [%s]' % (return_code == 0)) 49648f512ceSopenharmony_ci if return_code != 0: 49748f512ceSopenharmony_ci raise Exception('Failed to record profiling data.') 49848f512ceSopenharmony_ci 49948f512ceSopenharmony_ci def end_profiling(self): 50048f512ceSopenharmony_ci """ 50148f512ceSopenharmony_ci Stop profiling by sending SIGINT to hiperf, and wait until it exits 50248f512ceSopenharmony_ci to make sure perf.data is completely generated. 50348f512ceSopenharmony_ci """ 50448f512ceSopenharmony_ci has_killed = False 50548f512ceSopenharmony_ci while True: 50648f512ceSopenharmony_ci (result, out) = self.hdc.run_hdc_cmd( 50748f512ceSopenharmony_ci ['shell', 'pidof', 'hiperf']) 50848f512ceSopenharmony_ci if not out: 50948f512ceSopenharmony_ci break 51048f512ceSopenharmony_ci if not has_killed: 51148f512ceSopenharmony_ci has_killed = True 51248f512ceSopenharmony_ci self.hdc.run_hdc_cmd(['shell', 'pkill', 51348f512ceSopenharmony_ci '-l', '2', 'hiperf']) 51448f512ceSopenharmony_ci time.sleep(1) 51548f512ceSopenharmony_ci 51648f512ceSopenharmony_ci def get_profiling_data(self): 51748f512ceSopenharmony_ci current_path = os.getcwd() 51848f512ceSopenharmony_ci full_path = os.path.join(current_path, self.args.output_perf_data) 51948f512ceSopenharmony_ci self.hdc.check_run(['file recv', '/data/local/tmp/perf.data', 52048f512ceSopenharmony_ci full_path]) 52148f512ceSopenharmony_ci self.hdc.run_hdc_cmd(['shell', 'rm', 52248f512ceSopenharmony_ci '/data/local/tmp/perf.data']) 52348f512ceSopenharmony_ci 52448f512ceSopenharmony_ci def exec_control(self): 52548f512ceSopenharmony_ci hdc_args = [self.hdc.hdc_path, 'shell', 52648f512ceSopenharmony_ci 'hiperf', 'record', 52748f512ceSopenharmony_ci '--control', self.control_mode] 52848f512ceSopenharmony_ci print('run hdc cmd: %s' % hdc_args) 52948f512ceSopenharmony_ci self.record_subproc = subprocess.Popen(hdc_args) 53048f512ceSopenharmony_ci 53148f512ceSopenharmony_ci def wait_data_generate_done(self): 53248f512ceSopenharmony_ci last_size = 0 53348f512ceSopenharmony_ci while True: 53448f512ceSopenharmony_ci (result, out) = self.hdc.run_hdc_cmd( 53548f512ceSopenharmony_ci ['shell', 'du', 'data/local/tmp/perf.data']) 53648f512ceSopenharmony_ci if "du" not in out: 53748f512ceSopenharmony_ci current_size = out.split(" ")[0] 53848f512ceSopenharmony_ci if current_size == last_size: 53948f512ceSopenharmony_ci self.get_profiling_data() 54048f512ceSopenharmony_ci break 54148f512ceSopenharmony_ci else: 54248f512ceSopenharmony_ci last_size = current_size 54348f512ceSopenharmony_ci else: 54448f512ceSopenharmony_ci print("not generate perf.data") 54548f512ceSopenharmony_ci break 54648f512ceSopenharmony_ci 54748f512ceSopenharmony_ci time.sleep(1) 548