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