# IN THE SOFTWARE.
import argparse
+import queue
import re
from serial_buffer import SerialBuffer
import sys
+import threading
class CrosServoRun:
def __init__(self, cpu, ec):
- self.ec_ser = SerialBuffer(ec, "artifacts/serial-ec.txt", "R SERIAL-EC> ")
- self.cpu_ser = SerialBuffer(cpu, "artifacts/serial.txt", "R SERIAL-CPU> ")
+ # Merged FIFO for the two serial buffers, fed by threads.
+ self.serial_queue = queue.Queue()
+ self.sentinel = object()
+ self.threads_done = 0
+
+ self.ec_ser = SerialBuffer(ec, "results/serial-ec.txt", "R SERIAL-EC> ")
+ self.cpu_ser = SerialBuffer(cpu, "results/serial.txt", "R SERIAL-CPU> ")
+
+ self.iter_feed_ec = threading.Thread(target=self.iter_feed_queue, daemon=True, args=(self.ec_ser.lines(),))
+ self.iter_feed_ec.start()
+
+ self.iter_feed_cpu = threading.Thread(target=self.iter_feed_queue, daemon=True, args=(self.cpu_ser.lines(),))
+ self.iter_feed_cpu.start()
+
+ # Feed lines from our serial queues into the merged queue, marking when our
+ # input is done.
+ def iter_feed_queue(self, it):
+ for i in it:
+ self.serial_queue.put(i)
+ self.serial_queue.put(sentinel)
+
+ # Return the next line from the queue, counting how many threads have
+ # terminated and joining when done
+ def get_serial_queue_line(self):
+ line = self.serial_queue.get()
+ if line == self.sentinel:
+ self.threads_done = self.threads_done + 1
+ if self.threads_done == 2:
+ self.iter_feed_cpu.join()
+ self.iter_feed_ec.join()
+ return line
+
+ # Returns an iterator for getting the next line.
+ def serial_queue_lines(self):
+ return iter(self.get_serial_queue_line, self.sentinel)
def ec_write(self, s):
print("W SERIAL-EC> %s" % s)
# This is emitted right when the bootloader pauses to check for input.
# Emit a ^N character to request network boot, because we don't have a
# direct-to-netboot firmware on cheza.
- for line in self.cpu_ser.lines():
- if re.match("load_archive: loading locale_en.bin", line):
+ for line in self.serial_queue_lines():
+ if re.search("load_archive: loading locale_en.bin", line):
self.cpu_write("\016")
break
tftp_failures = 0
- for line in self.cpu_ser.lines():
- if re.match("---. end Kernel panic", line):
+ for line in self.serial_queue_lines():
+ if re.search("---. end Kernel panic", line):
return 1
# The Cheza boards have issues with failing to bring up power to
# the system sometimes, possibly dependent on ambient temperature
# in the farm.
- if re.match("POWER_GOOD not seen in time", line):
+ if re.search("POWER_GOOD not seen in time", line):
+ print("Detected intermittent poweron failure, restarting run...")
return 2
# The Cheza firmware seems to occasionally get stuck looping in
# this error state during TFTP booting, possibly based on amount of
# network traffic around it, but it'll usually recover after a
# reboot.
- if re.match("R8152: Bulk read error 0xffffffbf", line):
+ if re.search("R8152: Bulk read error 0xffffffbf", line):
tftp_failures += 1
if tftp_failures >= 100:
+ print("Detected intermittent tftp failure, restarting run...")
return 2
- result = re.match("bare-metal result: (\S*)", line)
+ result = re.search("bare-metal result: (\S*)", line)
if result:
if result.group(1) == "pass":
return 0