From 7a1d60ee15fd8c87c0de94bebdc0785656c4787c Mon Sep 17 00:00:00 2001 From: Sebastien Bourdeauducq Date: Fri, 13 Mar 2015 14:55:18 +0100 Subject: [PATCH] coredevice,runtime,language: add parameters to runtime exceptions, include information with RTIO errors --- artiq/coredevice/comm_serial.py | 6 ++++-- artiq/coredevice/core.py | 1 + artiq/coredevice/runtime_exceptions.py | 13 +++++++++++++ artiq/language/core.py | 8 ++++++-- soc/runtime/comm_serial.c | 12 ++++++++++++ soc/runtime/exceptions.c | 11 +++++++++++ soc/runtime/exceptions.h | 5 +++++ soc/runtime/rtio.c | 15 ++++++++++----- 8 files changed, 62 insertions(+), 9 deletions(-) diff --git a/artiq/coredevice/comm_serial.py b/artiq/coredevice/comm_serial.py index 46e59d14f..3d94f7a37 100644 --- a/artiq/coredevice/comm_serial.py +++ b/artiq/coredevice/comm_serial.py @@ -195,13 +195,15 @@ class Comm(AutoDB): rpc_num, args, r)) def _serve_exception(self, user_exception_map): - eid = struct.unpack(">l", _read_exactly(self.port, 4))[0] + eid, p0, p1, p2 = struct.unpack(">lqqq", + _read_exactly(self.port, 4+3*8)) self.rpc_wrapper.filter_rpc_exception(eid) if eid < core_language.first_user_eid: exception = runtime_exceptions.exception_map[eid] + raise exception(self.core, p0, p1, p2) else: exception = user_exception_map[eid] - raise exception + raise exception def serve(self, rpc_map, user_exception_map): while True: diff --git a/artiq/coredevice/core.py b/artiq/coredevice/core.py index 41181349e..80e41b260 100644 --- a/artiq/coredevice/core.py +++ b/artiq/coredevice/core.py @@ -52,6 +52,7 @@ class Core(AutoDB): def build(self): self.runtime_env = self.comm.get_runtime_env() self.core = self + self.comm.core = self if self.external_clock is None: self.ref_period = self.runtime_env.internal_ref_period diff --git a/artiq/coredevice/runtime_exceptions.py b/artiq/coredevice/runtime_exceptions.py index 45f912800..5a6fa0abc 100644 --- a/artiq/coredevice/runtime_exceptions.py +++ b/artiq/coredevice/runtime_exceptions.py @@ -25,6 +25,12 @@ class RTIOUnderflow(RuntimeException): """ eid = 3 + def __str__(self): + return "at {} on channel {}, violation {}".format( + self.p0*self.core.ref_period, + self.p1, + (self.p2 - self.p0)*self.core.ref_period) + class RTIOSequenceError(RuntimeException): """Raised when an event is submitted on a given channel with a timestamp @@ -35,6 +41,10 @@ class RTIOSequenceError(RuntimeException): """ eid = 4 + def __str__(self): + return "at {} on channel {}".format(self.p0*self.core.ref_period, + self.p1) + class RTIOOverflow(RuntimeException): """Raised when at least one event could not be registered into the RTIO @@ -47,6 +57,9 @@ class RTIOOverflow(RuntimeException): """ eid = 5 + def __str__(self): + return "on channel {}".format(self.p0) + exception_map = {e.eid: e for e in globals().values() if inspect.isclass(e) diff --git a/artiq/language/core.py b/artiq/language/core.py index 64e8e42aa..ec7d739ac 100644 --- a/artiq/language/core.py +++ b/artiq/language/core.py @@ -283,9 +283,13 @@ def EncodedException(eid): class RuntimeException(Exception): """Base class for all exceptions used by the device runtime. Those exceptions are defined in ``artiq.coredevice.runtime_exceptions``. - """ - pass + def __init__(self, core, p0, p1, p2): + Exception.__init__(self) + self.core = core + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 first_user_eid = 1024 diff --git a/soc/runtime/comm_serial.c b/soc/runtime/comm_serial.c index 6d322cbe4..35532a88f 100644 --- a/soc/runtime/comm_serial.c +++ b/soc/runtime/comm_serial.c @@ -55,6 +55,16 @@ static char receive_char(void) return uart_read(); } +static void send_llint(long long int x) +{ + int i; + + for(i=0;i<8;i++) { + uart_write((x & 0xff00000000000000LL) >> 56); + x <<= 8; + } +} + static void send_int(int x) { int i; @@ -140,6 +150,8 @@ static void receive_and_run_kernel(kernel_runner run_kernel) case KERNEL_RUN_EXCEPTION: send_char(MSGTYPE_KERNEL_EXCEPTION); send_int(eid); + for(i=0;i<3;i++) + send_llint(exception_params[i]); break; case KERNEL_RUN_STARTUP_FAILED: send_char(MSGTYPE_KERNEL_STARTUP_FAILED); diff --git a/soc/runtime/exceptions.c b/soc/runtime/exceptions.c index eb6e83c69..fc72d0ae9 100644 --- a/soc/runtime/exceptions.c +++ b/soc/runtime/exceptions.c @@ -10,6 +10,7 @@ struct exception_context { static struct exception_context exception_contexts[MAX_EXCEPTION_CONTEXTS]; static int ec_top; static int stored_id; +long long int exception_params[3]; void *exception_push(void) { @@ -29,9 +30,19 @@ int exception_getid(void) } void exception_raise(int id) +{ + exception_raise_params(id, 0, 0, 0); +} + +void exception_raise_params(int id, + long long int p0, long long int p1, + long long int p2) { if(ec_top > 0) { stored_id = id; + exception_params[0] = p0; + exception_params[1] = p1; + exception_params[2] = p2; exception_longjmp(exception_contexts[--ec_top].jb); } else { comm_log("ERROR: uncaught exception, ID=%d\n", id); diff --git a/soc/runtime/exceptions.h b/soc/runtime/exceptions.h index d55d6cfe5..f3ebacd55 100644 --- a/soc/runtime/exceptions.h +++ b/soc/runtime/exceptions.h @@ -10,6 +10,8 @@ enum { EID_RTIO_OVERFLOW = 5, }; +extern long long int exception_params[3]; + int exception_setjmp(void *jb) __attribute__((returns_twice)); void exception_longjmp(void *jb) __attribute__((noreturn)); @@ -17,5 +19,8 @@ void *exception_push(void); void exception_pop(int levels); int exception_getid(void); void exception_raise(int id) __attribute__((noreturn)); +void exception_raise_params(int id, + long long int p0, long long int p1, + long long int p2) __attribute__((noreturn)); #endif /* __EXCEPTIONS_H */ diff --git a/soc/runtime/rtio.c b/soc/runtime/rtio.c index f09ce03ce..300cfcc04 100644 --- a/soc/runtime/rtio.c +++ b/soc/runtime/rtio.c @@ -38,11 +38,13 @@ void rtio_set(long long int timestamp, int channel, int value) while(rtio_o_status_read() & RTIO_O_STATUS_FULL); if(status & RTIO_O_STATUS_UNDERFLOW) { rtio_o_underflow_reset_write(1); - exception_raise(EID_RTIO_UNDERFLOW); + exception_raise_params(EID_RTIO_UNDERFLOW, + timestamp, channel, rtio_get_counter()); } if(status & RTIO_O_STATUS_SEQUENCE_ERROR) { rtio_o_sequence_error_reset_write(1); - exception_raise(EID_RTIO_SEQUENCE_ERROR); + exception_raise_params(EID_RTIO_SEQUENCE_ERROR, + timestamp, channel, 0); } } } @@ -62,7 +64,8 @@ long long int rtio_get(int channel, long long int time_limit) while((status = rtio_i_status_read())) { if(rtio_i_status_read() & RTIO_I_STATUS_OVERFLOW) { rtio_i_overflow_reset_write(1); - exception_raise(EID_RTIO_OVERFLOW); + exception_raise_params(EID_RTIO_OVERFLOW, + channel, 0, 0); } if(rtio_get_counter() >= time_limit) { /* check empty flag again to prevent race condition. @@ -114,11 +117,13 @@ void rtio_fud(long long int fud_time) if(status) { if(status & RTIO_O_STATUS_UNDERFLOW) { rtio_o_underflow_reset_write(1); - exception_raise(EID_RTIO_UNDERFLOW); + exception_raise_params(EID_RTIO_UNDERFLOW, + fud_time, RTIO_FUD_CHANNEL, rtio_get_counter()); } if(status & RTIO_O_STATUS_SEQUENCE_ERROR) { rtio_o_sequence_error_reset_write(1); - exception_raise(EID_RTIO_SEQUENCE_ERROR); + exception_raise_params(EID_RTIO_SEQUENCE_ERROR, + fud_time, RTIO_FUD_CHANNEL, 0); } } }