| Index: chrome/test/vr/perf/latency/motopho_thread.py
|
| diff --git a/chrome/test/vr/perf/latency/motopho_thread.py b/chrome/test/vr/perf/latency/motopho_thread.py
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..aca45614e432af1c90d83f38fa79ff85c6a0cf70
|
| --- /dev/null
|
| +++ b/chrome/test/vr/perf/latency/motopho_thread.py
|
| @@ -0,0 +1,83 @@
|
| +# Copyright 2017 The Chromium Authors. All rights reserved.
|
| +# Use of this source code is governed by a BSD-style license that can be
|
| +# found in the LICENSE file.
|
| +
|
| +import logging
|
| +import subprocess
|
| +import threading
|
| +
|
| +
|
| +class MotophoThread(threading.Thread):
|
| + """Handles the running of the Motopho script and extracting results."""
|
| + def __init__(self, num_samples):
|
| + threading.Thread.__init__(self)
|
| + self._num_samples = num_samples
|
| + self._latencies = []
|
| + self._correlations = []
|
| + # Threads can't be restarted, so in order to gather multiple samples, we
|
| + # need to either re-create the thread for every iteration or use a loop
|
| + # and locks in a single thread -> use the latter solution
|
| + self._start_lock = threading.Event()
|
| + self._finish_lock = threading.Event()
|
| + self.BlockNextIteration()
|
| +
|
| + def run(self):
|
| + for _ in xrange(self._num_samples):
|
| + self._WaitForIterationStart()
|
| + self._ResetEndLock()
|
| + motopho_output = ""
|
| + try:
|
| + motopho_output = subprocess.check_output(["./motophopro_nograph"],
|
| + stderr=subprocess.STDOUT)
|
| + except subprocess.CalledProcessError as e:
|
| + logging.error('Failed to run Motopho script: %s', e.output)
|
| + raise e
|
| +
|
| + if "FAIL" in motopho_output:
|
| + logging.error('Failed to get latency, logging raw output: %s',
|
| + motopho_output)
|
| + raise RuntimeError('Failed to get latency - correlation likely too low')
|
| +
|
| + current_num_samples = len(self._latencies)
|
| + for line in motopho_output.split("\n"):
|
| + if 'Motion-to-photon latency:' in line:
|
| + self._latencies.append(float(line.split(" ")[-2]))
|
| + if 'Max correlation is' in line:
|
| + self._correlations.append(float(line.split(' ')[-1]))
|
| + if (len(self._latencies) > current_num_samples and
|
| + len(self._correlations) > current_num_samples):
|
| + break;
|
| + self._EndIteration()
|
| +
|
| + def _WaitForIterationStart(self):
|
| + self._start_lock.wait()
|
| +
|
| + def StartIteration(self):
|
| + """Tells the thread to start its next test iteration."""
|
| + self._start_lock.set()
|
| +
|
| + def BlockNextIteration(self):
|
| + """Blocks the thread from starting the next iteration without a signal."""
|
| + self._start_lock.clear()
|
| +
|
| + def _EndIteration(self):
|
| + self._finish_lock.set()
|
| +
|
| + def _ResetEndLock(self):
|
| + self._finish_lock.clear()
|
| +
|
| + def WaitForIterationEnd(self, timeout):
|
| + """Waits until the thread says it's finished or times out.
|
| +
|
| + Returns:
|
| + Whether the iteration ended within the given timeout
|
| + """
|
| + return self._finish_lock.wait(timeout)
|
| +
|
| + @property
|
| + def latencies(self):
|
| + return self._latencies
|
| +
|
| + @property
|
| + def correlations(self):
|
| + return self._correlations
|
|
|