OLD | NEW |
---|---|
(Empty) | |
1 # Copyright 2017 The Chromium 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 logging | |
6 import subprocess | |
7 import threading | |
8 | |
Nico
2017/04/20 17:51:21
likewise
bsheedy
2017/04/20 20:05:00
Done.
| |
9 class MotophoThread(threading.Thread): | |
10 """Handles the running of the Motopho script and extracting results.""" | |
11 def __init__(self, num_samples): | |
12 threading.Thread.__init__(self) | |
13 self._num_samples = num_samples | |
14 self._latencies = [] | |
15 self._correlations = [] | |
16 # Threads can't be restarted, so in order to gather multiple samples, we | |
17 # need to either re-create the thread for every iteration or use a loop | |
18 # and locks in a single thread -> use the latter solution | |
19 self._start_lock = threading.Event() | |
20 self._finish_lock = threading.Event() | |
21 self.BlockNextIteration() | |
22 | |
23 def run(self): | |
24 for _ in xrange(self._num_samples): | |
25 self._WaitForIterationStart() | |
26 self._ResetEndLock() | |
27 motopho_output = "" | |
28 try: | |
29 motopho_output = subprocess.check_output(["./motophopro_nograph"], | |
30 stderr=subprocess.STDOUT) | |
31 except subprocess.CalledProcessError as e: | |
32 logging.error('Failed to run Motopho script: %s', e.output) | |
33 raise e | |
34 | |
35 if "FAIL" in motopho_output: | |
36 logging.error('Failed to get latency, logging raw output: %s', | |
37 motopho_output) | |
38 raise RuntimeError('Failed to get latency - correlation likely too low') | |
39 | |
40 current_num_samples = len(self._latencies) | |
41 for line in motopho_output.split("\n"): | |
42 if 'Motion-to-photon latency:' in line: | |
43 self._latencies.append(float(line.split(" ")[-2])) | |
44 if 'Max correlation is' in line: | |
45 self._correlations.append(float(line.split(' ')[-1])) | |
46 if (len(self._latencies) > current_num_samples and | |
47 len(self._correlations) > current_num_samples): | |
48 break; | |
49 self._EndIteration() | |
50 | |
51 def _WaitForIterationStart(self): | |
52 self._start_lock.wait() | |
53 | |
54 def StartIteration(self): | |
55 """Tells the thread to start its next test iteration.""" | |
56 self._start_lock.set() | |
57 | |
58 def BlockNextIteration(self): | |
59 """Blocks the thread from starting the next iteration without a signal.""" | |
60 self._start_lock.clear() | |
61 | |
62 def _EndIteration(self): | |
63 self._finish_lock.set() | |
64 | |
65 def _ResetEndLock(self): | |
66 self._finish_lock.clear() | |
67 | |
68 def WaitForIterationEnd(self, timeout): | |
69 """Waits until the thread says it's finished or times out. | |
70 | |
71 Returns: | |
72 Whether the iteration ended within the given timeout | |
73 """ | |
74 return self._finish_lock.wait(timeout) | |
75 | |
76 @property | |
77 def latencies(self): | |
78 return self._latencies | |
79 | |
80 @property | |
81 def correlations(self): | |
82 return self._correlations | |
OLD | NEW |