1# Lint as: python2, python3 2# Copyright (c) 2010 The Chromium OS Authors. All rights reserved. 3# Use of this source code is governed by a BSD-style license that can be 4# found in the LICENSE file. 5 6import glob, logging, os, time 7from autotest_lib.client.bin import test 8from autotest_lib.client.common_lib import error 9 10# choosing a (very) conservative threshold for now to help catch 11# major breakages 12percent_idle_time_threshold = 20 13 14class power_CPUIdle(test.test): 15 version = 1 16 17 def run_once(self, sleep_time=5): 18 all_cpus = cpus() 19 20 idle_time_at_start, active_time_at_start = all_cpus.idle_time() 21 logging.info('idle_time_at_start: %d', idle_time_at_start) 22 logging.info('active_time_at_start: %d', active_time_at_start) 23 24 # sleep for some time to allow the CPUs to drop into idle states 25 time.sleep(sleep_time) 26 27 idle_time_at_end, active_time_at_end = all_cpus.idle_time() 28 logging.info('idle_time_at_end: %d', idle_time_at_end) 29 logging.info('active_time_at_end: %d', idle_time_at_end) 30 31 idle_time_delta_ms = (idle_time_at_end - idle_time_at_start) / 1000 32 logging.info('idle_time_delta_ms: %d', idle_time_delta_ms) 33 34 active_time_delta_ms = (active_time_at_end - active_time_at_start) \ 35 / 1000 36 logging.info('active_time_delta_ms: %d', active_time_delta_ms) 37 38 total_time_delta_ms = active_time_delta_ms + idle_time_delta_ms 39 logging.info('total_time_delta_ms: %d', total_time_delta_ms) 40 41 percent_active_time = active_time_delta_ms * 100.0 / total_time_delta_ms 42 logging.info('percent active time : %.2f', percent_active_time) 43 44 percent_idle_time = idle_time_delta_ms * 100.0 / total_time_delta_ms 45 logging.info('percent idle time : %.2f', percent_idle_time) 46 47 keyvals = {} 48 keyvals['ms_active_time_delta'] = active_time_delta_ms 49 keyvals['ms_idle_time_delta'] = idle_time_delta_ms 50 keyvals['percent_active_time'] = percent_active_time 51 keyvals['percent_idle_time'] = percent_idle_time 52 self.write_perf_keyval(keyvals) 53 54 if percent_idle_time < percent_idle_time_threshold: 55 raise error.TestFail('Idle percent below threshold') 56 57 58 59class cpus(object): 60 def __init__(self): 61 self.__base_path = '/sys/devices/system/cpu/cpu*/cpuidle' 62 self.__cpus = [] 63 64 dirs = glob.glob(self.__base_path) 65 if not dirs: 66 raise error.TestError('cpuidle not supported') 67 68 for dir in dirs: 69 cpu = cpuidle(dir) 70 self.__cpus.append(cpu) 71 72 73 def idle_time(self): 74 total_idle_time = 0 75 total_active_time = 0 76 for cpu in self.__cpus: 77 idle_time, active_time = cpu.idle_time() 78 total_idle_time += idle_time 79 total_active_time += active_time 80 return total_idle_time, total_active_time 81 82 83 84class cpuidle(object): 85 def __init__(self, path): 86 self.__base_path = path 87 self.__states = [] 88 89 dirs = glob.glob(os.path.join(self.__base_path, 'state*')) 90 if not dirs: 91 raise error.TestError('cpuidle states missing') 92 93 for dir in dirs: 94 state = cpuidle_state(dir) 95 self.__states.append(state) 96 97 98 def idle_time(self): 99 total_idle_time = 0 100 total_active_time = 0 101 for state in self.__states: 102 total_idle_time += state.idle_time() 103 total_active_time += state.active_time() 104 105 return total_idle_time, total_active_time 106 107 108 109class cpuidle_state(object): 110 def __init__(self, path): 111 self.__base_path = path 112 self.__name = self.__read_file('name').split()[0] 113 self.__latency = int(self.__read_file('latency').split()[0]) 114 115 116 def __read_file(self, file_name): 117 path = os.path.join(self.__base_path, file_name) 118 f = open(path, 'r') 119 data = f.read() 120 f.close() 121 return data 122 123 124 def __is_idle_state(self): 125 if self.__latency: 126 # non-zero latency indicates non-C0 state 127 return True 128 return False 129 130 131 def idle_time(self): 132 time = 0 133 if self.__is_idle_state(): 134 time = int(self.__read_file('time')) 135 logging.info('idle_time(%s): %d', self.__name, time) 136 return time 137 138 139 def active_time(self): 140 time = 0 141 if not self.__is_idle_state(): 142 time = int(self.__read_file('time')) 143 logging.info('active_time(%s): %d', self.__name, time) 144 return time 145