Show a message when interrupting a running kernel (except idle kernel).

Fixes #625.
This commit is contained in:
whitequark 2017-01-31 22:53:38 +00:00
parent bc22d1c009
commit 6fd149f048
7 changed files with 35 additions and 19 deletions

View File

@ -17,7 +17,7 @@ class Comm:
def serve(self, embedding_map, symbolizer, demangler): def serve(self, embedding_map, symbolizer, demangler):
pass pass
def check_ident(self): def check_system_info(self):
pass pass
def get_log(self): def get_log(self):

View File

@ -17,7 +17,7 @@ class _H2DMsgType(Enum):
LOG_REQUEST = 1 LOG_REQUEST = 1
LOG_CLEAR = 2 LOG_CLEAR = 2
IDENT_REQUEST = 3 SYSTEM_INFO_REQUEST = 3
SWITCH_CLOCK = 4 SWITCH_CLOCK = 4
LOAD_KERNEL = 5 LOAD_KERNEL = 5
@ -35,7 +35,7 @@ class _H2DMsgType(Enum):
class _D2HMsgType(Enum): class _D2HMsgType(Enum):
LOG_REPLY = 1 LOG_REPLY = 1
IDENT_REPLY = 2 SYSTEM_INFO_REPLY = 2
CLOCK_SWITCH_COMPLETED = 3 CLOCK_SWITCH_COMPLETED = 3
CLOCK_SWITCH_FAILED = 4 CLOCK_SWITCH_FAILED = 4
@ -200,11 +200,11 @@ class CommGeneric:
def reset_session(self): def reset_session(self):
self.write(struct.pack(">ll", 0x5a5a5a5a, 0)) self.write(struct.pack(">ll", 0x5a5a5a5a, 0))
def check_ident(self): def check_system_info(self):
self._write_empty(_H2DMsgType.IDENT_REQUEST) self._write_empty(_H2DMsgType.SYSTEM_INFO_REQUEST)
self._read_header() self._read_header()
self._read_expect(_D2HMsgType.IDENT_REPLY) self._read_expect(_D2HMsgType.SYSTEM_INFO_REPLY)
runtime_id = self._read_chunk(4) runtime_id = self._read_chunk(4)
if runtime_id != b"AROR": if runtime_id != b"AROR":
raise UnsupportedDevice("Unsupported runtime ID: {}" raise UnsupportedDevice("Unsupported runtime ID: {}"
@ -215,6 +215,9 @@ class CommGeneric:
logger.warning("Mismatch between gateware (%s) " logger.warning("Mismatch between gateware (%s) "
"and software (%s) versions", "and software (%s) versions",
gateware_version, software_version) gateware_version, software_version)
finished_cleanly = self._read_bool()
if not finished_cleanly:
logger.warning("Interrupted a running kernel")
def switch_clock(self, external): def switch_clock(self, external):
self._write_header(_H2DMsgType.SWITCH_CLOCK) self._write_header(_H2DMsgType.SWITCH_CLOCK)

View File

@ -115,7 +115,7 @@ class Core:
self.compile(function, args, kwargs, set_result) self.compile(function, args, kwargs, set_result)
if self.first_run: if self.first_run:
self.comm.check_ident() self.comm.check_system_info()
self.comm.switch_clock(self.external_clock) self.comm.switch_clock(self.external_clock)
self.first_run = False self.first_run = False

View File

@ -1,6 +1,6 @@
use std::prelude::v1::*; use std::prelude::v1::*;
use std::{mem, str}; use std::{mem, str};
use std::cell::RefCell; use std::cell::{Cell, RefCell};
use std::io::{self, Read, Write}; use std::io::{self, Read, Write};
use std::error::Error; use std::error::Error;
use std::btree_set::BTreeSet; use std::btree_set::BTreeSet;
@ -34,14 +34,16 @@ fn io_error(msg: &str) -> io::Error {
#[derive(Debug)] #[derive(Debug)]
struct Congress { struct Congress {
now: u64, now: u64,
cache: Cache cache: Cache,
finished_cleanly: Cell<bool>
} }
impl Congress { impl Congress {
fn new() -> Congress { fn new() -> Congress {
Congress { Congress {
now: 0, now: 0,
cache: Cache::new() cache: Cache::new(),
finished_cleanly: Cell::new(true)
} }
} }
} }
@ -204,8 +206,14 @@ fn process_host_message(io: &Io,
stream: &mut TcpStream, stream: &mut TcpStream,
session: &mut Session) -> io::Result<()> { session: &mut Session) -> io::Result<()> {
match host_read(stream)? { match host_read(stream)? {
host::Request::Ident => host::Request::SystemInfo => {
host_write(stream, host::Reply::Ident(board::ident(&mut [0; 64]))), host_write(stream, host::Reply::SystemInfo {
ident: board::ident(&mut [0; 64]),
finished_cleanly: session.congress.finished_cleanly.get()
})?;
session.congress.finished_cleanly.set(true);
Ok(())
}
// artiq_corelog // artiq_corelog
host::Request::Log => { host::Request::Log => {
@ -628,7 +636,6 @@ fn respawn<F>(io: &Io, handle: &mut Option<ThreadHandle>, f: F)
None => (), None => (),
Some(handle) => { Some(handle) => {
if !handle.terminated() { if !handle.terminated() {
info!("terminating running kernel");
handle.interrupt(); handle.interrupt();
io.join(handle).expect("cannot join interrupt thread") io.join(handle).expect("cannot join interrupt thread")
} }
@ -659,6 +666,7 @@ pub fn thread(io: Io) {
if err.kind() == io::ErrorKind::NotFound { if err.kind() == io::ErrorKind::NotFound {
info!("no startup kernel found") info!("no startup kernel found")
} else { } else {
congress.finished_cleanly.set(false);
error!("startup kernel aborted: {}", err); error!("startup kernel aborted: {}", err);
} }
} }
@ -690,6 +698,7 @@ pub fn thread(io: Io) {
if err.kind() == io::ErrorKind::UnexpectedEof { if err.kind() == io::ErrorKind::UnexpectedEof {
info!("connection closed"); info!("connection closed");
} else { } else {
congress.finished_cleanly.set(false);
error!("session aborted: {}", err); error!("session aborted: {}", err);
} }
} }

View File

@ -20,7 +20,7 @@ pub enum Request {
Log, Log,
LogClear, LogClear,
Ident, SystemInfo,
SwitchClock(u8), SwitchClock(u8),
LoadKernel(Vec<u8>), LoadKernel(Vec<u8>),
@ -49,7 +49,7 @@ impl Request {
Ok(match read_u8(reader)? { Ok(match read_u8(reader)? {
1 => Request::Log, 1 => Request::Log,
2 => Request::LogClear, 2 => Request::LogClear,
3 => Request::Ident, 3 => Request::SystemInfo,
4 => Request::SwitchClock(read_u8(reader)?), 4 => Request::SwitchClock(read_u8(reader)?),
5 => Request::LoadKernel(read_bytes(reader)?), 5 => Request::LoadKernel(read_bytes(reader)?),
6 => Request::RunKernel, 6 => Request::RunKernel,
@ -87,7 +87,10 @@ impl Request {
pub enum Reply<'a> { pub enum Reply<'a> {
Log(&'a str), Log(&'a str),
Ident(&'a str), SystemInfo {
ident: &'a str,
finished_cleanly: bool
},
ClockSwitchCompleted, ClockSwitchCompleted,
ClockSwitchFailed, ClockSwitchFailed,
@ -126,10 +129,11 @@ impl<'a> Reply<'a> {
write_string(writer, log)?; write_string(writer, log)?;
}, },
Reply::Ident(ident) => { Reply::SystemInfo { ident, finished_cleanly } => {
write_u8(writer, 2)?; write_u8(writer, 2)?;
writer.write(b"AROR")?; writer.write(b"AROR")?;
write_string(writer, ident)?; write_string(writer, ident)?;
write_u8(writer, finished_cleanly as u8)?;
}, },
Reply::ClockSwitchCompleted => { Reply::ClockSwitchCompleted => {
write_u8(writer, 3)?; write_u8(writer, 3)?;

View File

@ -53,7 +53,7 @@ def main():
device_mgr = DeviceManager(DeviceDB(args.device_db)) device_mgr = DeviceManager(DeviceDB(args.device_db))
try: try:
comm = device_mgr.get("comm") comm = device_mgr.get("comm")
comm.check_ident() comm.check_system_info()
if args.action == "read": if args.action == "read":
value = comm.flash_storage_read(args.key) value = comm.flash_storage_read(args.key)

View File

@ -22,7 +22,7 @@ def main():
device_mgr = DeviceManager(DeviceDB(args.device_db)) device_mgr = DeviceManager(DeviceDB(args.device_db))
try: try:
comm = device_mgr.get("comm") comm = device_mgr.get("comm")
comm.check_ident() comm.check_system_info()
print(comm.get_log(), end="") print(comm.get_log(), end="")
finally: finally:
device_mgr.close_devices() device_mgr.close_devices()