Fix MulticoreRunHaltStepiTest
authorTim Newsome <tim@sifive.com>
Sat, 19 May 2018 01:12:00 +0000 (18:12 -0700)
committerTim Newsome <tim@sifive.com>
Sat, 19 May 2018 01:12:00 +0000 (18:12 -0700)
The test actually wasn't checking interrupt counts at all. Fixing it
required some other changes:
Make sure all harts get to run
Add some retries, since on a loaded machine against spike both harts
might not get to run, even if you give spike a generous amount of time
to do so.

debug/gdbserver.py
debug/testlib.py

index be89d19157b07789be13bad5a105091b393569c5..257f8d409db6a10e12347f451fe9d612c20751bc 100755 (executable)
@@ -562,30 +562,48 @@ class MulticoreRunHaltStepiTest(GdbTest):
         self.gdb.load()
         for hart in self.target.harts:
             self.gdb.select_hart(hart)
+            self.gdb.p("$mhartid")
             self.gdb.p("$pc=_start")
 
     def test(self):
         previous_hart_count = [0 for h in self.target.harts]
         previous_interrupt_count = [0 for h in self.target.harts]
-        for _ in range(10):
-            self.gdb.c(wait=False)
-            time.sleep(2)
-            self.gdb.interrupt()
-            self.gdb.p("$mie")
-            self.gdb.p("$mip")
-            self.gdb.p("$mstatus")
-            self.gdb.p("$priv")
-            self.gdb.p("buf", fmt="")
-            hart_count = self.gdb.p("hart_count")
-            interrupt_count = self.gdb.p("interrupt_count")
-            for i, h in enumerate(self.target.harts):
-                assertGreater(hart_count[i], previous_hart_count[i])
-                assertGreater(interrupt_count[i], previous_interrupt_count[i])
-                self.gdb.select_hart(h)
-                pc = self.gdb.p("$pc")
-                self.gdb.stepi()
-                stepped_pc = self.gdb.p("$pc")
-                assertNotEqual(pc, stepped_pc)
+        # Check 10 times
+        for i in range(10):
+            # 3 attempts for each time we want the check to pass
+            for attempt in range(3):
+                self.gdb.global_command("echo round %d attempt %d\\n" % (i,
+                    attempt))
+                self.gdb.c_all(wait=False)
+                time.sleep(2)
+                self.gdb.interrupt_all()
+                hart_count = self.gdb.p("hart_count")
+                interrupt_count = self.gdb.p("interrupt_count")
+                ok = True
+                for i, h in enumerate(self.target.harts):
+                    if hart_count[i] <= previous_hart_count[i]:
+                        ok = False
+                        break
+                    if interrupt_count[i] <= previous_interrupt_count[i]:
+                        ok = False
+                        break
+                    self.gdb.p("$mie")
+                    self.gdb.p("$mip")
+                    self.gdb.p("$mstatus")
+                    self.gdb.p("$priv")
+                    self.gdb.p("buf", fmt="")
+                    self.gdb.select_hart(h)
+                    pc = self.gdb.p("$pc")
+                    self.gdb.stepi()
+                    stepped_pc = self.gdb.p("$pc")
+                    assertNotEqual(pc, stepped_pc)
+                previous_hart_count = hart_count
+                previous_interrupt_count = interrupt_count
+                if ok:
+                    break
+            else:
+                assert False, \
+                        "hart count or interrupt didn't increment as expected"
 
 class MulticoreRunAllHaltOne(GdbTest):
     compile_args = ("programs/multicore.c", "-DMULTICORE")
index fb5bee33b1284b36ecafe918821a979ad1cf738c..2fd978cc283f5dbc502c32cdb96efb82302d33da 100644 (file)
@@ -477,7 +477,7 @@ class Gdb(object):
             self.active_child.sendline("c%s" % async)
             self.active_child.expect("Continuing", timeout=ops * self.timeout)
 
-    def c_all(self):
+    def c_all(self, wait=True):
         """
         Resume every hart.
 
@@ -494,15 +494,20 @@ class Gdb(object):
                 child.sendline("c")
                 child.expect("Continuing")
 
-            # Now wait for them all to halt
-            for child in self.children:
-                child.expect(r"\(gdb\)")
+            if wait:
+                for child in self.children:
+                    child.expect(r"\(gdb\)")
 
     def interrupt(self):
         self.active_child.send("\003")
         self.active_child.expect(r"\(gdb\)", timeout=6000)
         return self.active_child.before.strip()
 
+    def interrupt_all(self):
+        for child in self.children:
+            self.select_child(child)
+            self.interrupt()
+
     def x(self, address, size='w'):
         output = self.command("x/%s %s" % (size, address))
         value = int(output.split(':')[1].strip(), 0)