forked from M-Labs/artiq
1
0
Fork 0

coredevice,runtime,language: add parameters to runtime exceptions, include information with RTIO errors

This commit is contained in:
Sebastien Bourdeauducq 2015-03-13 14:55:18 +01:00
parent 84732a469d
commit 7a1d60ee15
8 changed files with 62 additions and 9 deletions

View File

@ -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:

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -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 */

View File

@ -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);
}
}
}