Index: tools/skpbench/_hardware.py |
diff --git a/tools/skpbench/_hardware.py b/tools/skpbench/_hardware.py |
index 23cfc827bc97ccf44f98dee0549e7a04c564a8c6..f1c8c2684358301a4bb3d64b59d2c273866a8078 100644 |
--- a/tools/skpbench/_hardware.py |
+++ b/tools/skpbench/_hardware.py |
@@ -5,12 +5,21 @@ |
import time |
-class HardwareException(Exception): |
- def __init__(self, message, sleeptime=60): |
- Exception.__init__(self, message) |
- self.sleeptime = sleeptime |
- |
class Hardware: |
+ """Locks down and monitors hardware for benchmarking. |
+ |
+ This is a common base for classes that can control the specific hardware |
+ we are running on. Its purpose is to lock the hardware into a constant |
+ benchmarking mode for the duration of a 'with' block. e.g.: |
+ |
+ with hardware: |
+ run_benchmark() |
+ |
+ While benchmarking, the caller must call sanity_check() frequently to verify |
+ the hardware state has not changed. |
+ |
+ """ |
+ |
def __init__(self): |
self.kick_in_time = 0 |
@@ -21,9 +30,60 @@ class Hardware: |
pass |
def sanity_check(self): |
- '''Raises a HardwareException if any hardware state is not as expected.''' |
+ """Raises a HardwareException if any hardware state is not as expected.""" |
pass |
def sleep(self, sleeptime): |
- '''Puts the hardware into a resting state for a fixed amount of time.''' |
+ """Puts the hardware into a resting state for a fixed amount of time.""" |
time.sleep(sleeptime) |
+ |
+ |
+class HardwareException(Exception): |
+ """Gets thrown when certain hardware state is not what we expect. |
+ |
+ Generally this happens because of thermal conditions or other variables beyond |
+ our control, and the appropriate course of action is to take a short nap |
+ before resuming the benchmark. |
+ |
+ """ |
+ |
+ def __init__(self, message, sleeptime=60): |
+ Exception.__init__(self, message) |
+ self.sleeptime = sleeptime |
+ |
+ |
+class Expectation: |
+ """Simple helper for checking the readings on hardware gauges.""" |
+ def __init__(self, value_type, min_value=None, max_value=None, |
+ exact_value=None, name=None, sleeptime=60): |
+ self.value_type = value_type |
+ self.min_value = min_value |
+ self.max_value = max_value |
+ self.exact_value = exact_value |
+ self.name = name |
+ self.sleeptime = sleeptime |
+ |
+ def check(self, stringvalue): |
+ typedvalue = self.value_type(stringvalue) |
+ if self.min_value is not None and typedvalue < self.min_value: |
+ raise HardwareException("%s is too low (%s, min=%s)" % |
+ (self.name, stringvalue, str(self.min_value)), |
+ sleeptime=self.sleeptime) |
+ if self.max_value is not None and typedvalue > self.max_value: |
+ raise HardwareException("%s is too high (%s, max=%s)" % |
+ (self.name, stringvalue, str(self.max_value)), |
+ sleeptime=self.sleeptime) |
+ if self.exact_value is not None and typedvalue != self.exact_value: |
+ raise HardwareException("unexpected %s (%s, expected=%s)" % |
+ (self.name, stringvalue, str(self.exact_value)), |
+ sleeptime=self.sleeptime) |
+ |
+ @staticmethod |
+ def check_all(expectations, stringvalues): |
+ if len(stringvalues) != len(expectations): |
+ raise Exception("unexpected reading from hardware gauges " |
+ "(expected %i values):\n%s" % |
+ (len(expectations), '\n'.join(stringvalues))) |
+ |
+ for value, expected in zip(stringvalues, expectations): |
+ expected.check(value) |