Home | History | Annotate | Download | only in power_CPUIdle
      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 
      5 import glob, logging, os, time
      6 from autotest_lib.client.bin import test
      7 from autotest_lib.client.common_lib import error
      8 
      9 # choosing a (very) conservative threshold for now to help catch
     10 # major breakages
     11 percent_idle_time_threshold = 20
     12 
     13 class 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 
     58 class 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 
     83 class 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 
    108 class 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