3
0
Fork 0
mirror of https://github.com/YosysHQ/sby.git synced 2025-08-10 07:10:54 +00:00

Intertask cancellation via database

Task checking via database rated limited to once every 10s.
Rename killer.sby to cancelledby.sby and add Makefile for testing.
This commit is contained in:
Krystine Sherwin 2025-07-09 10:03:54 +12:00
parent e7c756a43f
commit 5fc8df43f8
No known key found for this signature in database
4 changed files with 49 additions and 6 deletions

View file

@ -17,6 +17,7 @@
# #
import os, re, sys, signal, platform, click import os, re, sys, signal, platform, click
import time
if os.name == "posix": if os.name == "posix":
import resource, fcntl import resource, fcntl
import subprocess import subprocess
@ -98,6 +99,7 @@ class SbyProc:
self.silent = silent self.silent = silent
self.wait = False self.wait = False
self.job_lease = None self.job_lease = None
self.next_db = 0.0
self.task.update_proc_pending(self) self.task.update_proc_pending(self)
@ -183,6 +185,29 @@ class SbyProc:
self.task.cancel() self.task.cancel()
return return
if time.time() >= self.next_db:
tasks_status = self.task.status_db.all_tasks_status()
for task_status in tasks_status.values():
if (task_status["status"] in ["PASS", "FAIL", "CANCELLED"] and
task_status["name"] in self.task.cancelledby):
if not self.silent:
status_time = time.localtime(task_status["status_created"])
if status_time.tm_yday == time.localtime().tm_yday:
# same day, format time only
time_format = r"%H:%M:%S"
else:
time_format = r"%x %H:%M:%S"
self.task.log(
f'Cancelled by {task_status["name"]!r} task '
f'with status {task_status["status"]!r} '
f'at {time.strftime(time_format, status_time)} '
'(consider calling sby with --statusreset if this seems wrong)'
)
self.task.cancel()
return
# don't hit the database every poll
self.next_db = time.time() + 10
if not self.running: if not self.running:
for dep in self.deps: for dep in self.deps:
if not dep.finished: if not dep.finished:
@ -226,6 +251,10 @@ class SbyProc:
if self.job_lease: if self.job_lease:
self.job_lease.done() self.job_lease.done()
if self.terminated:
# task already terminated, do not finish
return
if not self.silent: if not self.silent:
self.task.log(f"{click.style(self.info, fg='magenta')}: finished (returncode={self.p.returncode})") self.task.log(f"{click.style(self.info, fg='magenta')}: finished (returncode={self.p.returncode})")

View file

@ -295,6 +295,18 @@ class SbyStatusDb:
return {row["id"]: dict(row) for row in rows} return {row["id"]: dict(row) for row in rows}
def all_tasks_status(self):
rows = self.db.execute(
"""
SELECT task.id, task.name, task.created,
task_status.status, task_status.created as 'status_created'
FROM task
INNER JOIN task_status ON task_status.task=task.id
"""
).fetchall()
return {row["id"]: dict(row) for row in rows}
def all_task_properties(self): def all_task_properties(self):
rows = self.db.execute( rows = self.db.execute(
""" """

2
tests/intertask/Makefile Normal file
View file

@ -0,0 +1,2 @@
SUBDIR=intertask
include ../make/subdir.mk

View file

@ -10,28 +10,28 @@ c: a
[options] [options]
mode bmc mode bmc
depth 100 depth 10000
expect fail,cancelled expect fail,cancelled
[engines] [engines]
btor btormc btor btormc
[script] [script]
a: read -define MAX=7 a: read -define MAX=9600
b: read -define MAX=14 b: read -define MAX=1267
c: read -define MAX=3 c: read -define MAX=7200
read -formal demo.sv read -formal demo.sv
prep -top demo prep -top demo
[file demo.sv] [file demo.sv]
module demo ( module demo (
input clk, input clk,
output reg [5:0] counter output reg [31:0] counter
); );
initial counter = 0; initial counter = 0;
always @(posedge clk) begin always @(posedge clk) begin
if (counter == 15) if (counter[31] == 1'b1)
counter <= 0; counter <= 0;
else else
counter <= counter + 1; counter <= counter + 1;