From 8a19766278b634ead6724ed2e76aa05ef358adb6 Mon Sep 17 00:00:00 2001 From: Sebastien Bourdeauducq Date: Tue, 28 Apr 2015 01:31:55 +0800 Subject: [PATCH] runtime,comm_generic: improve and fix list encoding --- artiq/coredevice/comm_generic.py | 37 ++++++---- soc/runtime/session.c | 117 ++++++++++++++++++------------- 2 files changed, 91 insertions(+), 63 deletions(-) diff --git a/artiq/coredevice/comm_generic.py b/artiq/coredevice/comm_generic.py index 6f6fa35ba..e1e0fbe47 100644 --- a/artiq/coredevice/comm_generic.py +++ b/artiq/coredevice/comm_generic.py @@ -120,27 +120,34 @@ class CommGeneric: self.write(bytes(kname, "ascii")) logger.debug("running kernel: %s", kname) + def _receive_rpc_value(self, type_tag): + if type_tag == "n": + return None + if type_tag == "b": + return bool(struct.unpack("B", self.read(1))[0]) + if type_tag == "i": + return struct.unpack(">l", self.read(4))[0] + if type_tag == "I": + return struct.unpack(">q", self.read(8))[0] + if type_tag == "f": + return struct.unpack(">d", self.read(8))[0] + if type_tag == "F": + n, d = struct.unpack(">qq", self.read(16)) + return Fraction(n, d) + def _receive_rpc_values(self): r = [] while True: type_tag = chr(struct.unpack("B", self.read(1))[0]) if type_tag == "\x00": return r - if type_tag == "n": - r.append(None) - if type_tag == "b": - r.append(bool(struct.unpack("B", self.read(1))[0])) - if type_tag == "i": - r.append(struct.unpack(">l", self.read(4))[0]) - if type_tag == "I": - r.append(struct.unpack(">q", self.read(8))[0]) - if type_tag == "f": - r.append(struct.unpack(">d", self.read(8))[0]) - if type_tag == "F": - n, d = struct.unpack(">qq", self.read(16)) - r.append(Fraction(n, d)) - if type_tag == "l": - r.append(self._receive_rpc_values()) + elif type_tag == "l": + elt_type_tag = chr(struct.unpack("B", self.read(1))[0]) + length = struct.unpack(">l", self.read(4))[0] + r.append([self._receive_rpc_value(elt_type_tag) + for i in range(length)]) + else: + r.append(self._receive_rpc_value(type_tag)) def _serve_rpc(self, rpc_wrapper, rpc_map, user_exception_map): rpc_num = struct.unpack(">l", self.read(4))[0] diff --git a/soc/runtime/session.c b/soc/runtime/session.c index 8b6c1097a..21f22bc69 100644 --- a/soc/runtime/session.c +++ b/soc/runtime/session.c @@ -1,4 +1,5 @@ #include +#include #include #include @@ -105,12 +106,44 @@ enum { REMOTEMSG_TYPE_RPC_REQUEST, }; +static int add_base_rpc_value(char base_type, void *value, char *buffer_out, int available_space) +{ + switch(base_type) { + case 'n': + return 0; + case 'b': + if(available_space < 1) + return -1; + if(*(char *)value) + buffer_out[0] = 1; + else + buffer_out[0] = 0; + return 1; + case 'i': + if(available_space < 4) + return -1; + memcpy(buffer_out, value, 4); + return 4; + case 'I': + case 'f': + if(available_space < 8) + return -1; + memcpy(buffer_out, value, 8); + return 8; + case 'F': + if(available_space < 16) + return -1; + memcpy(buffer_out, value, 16); + return 16; + default: + return -1; + } +} + static int add_rpc_value(int bi, int type_tag, void *value) { char base_type; int obi, r; - int i, p; - int len; obi = bi; base_type = type_tag; @@ -119,52 +152,40 @@ static int add_rpc_value(int bi, int type_tag, void *value) return -1; buffer_out[bi++] = base_type; - switch(base_type) { - case 'n': - return bi - obi; - case 'b': - if((bi + 1) > BUFFER_OUT_SIZE) - return -1; - if(*(char *)value) - buffer_out[bi++] = 1; - else - buffer_out[bi++] = 0; - return bi - obi; - case 'i': - if((bi + 4) > BUFFER_OUT_SIZE) - return -1; - memcpy(&buffer_out[bi], value, 4); - bi += 4; - return bi - obi; - case 'I': - case 'f': - if((bi + 8) > BUFFER_OUT_SIZE) - return -1; - memcpy(&buffer_out[bi], value, 8); - bi += 8; - return bi - obi; - case 'F': - if((bi + 16) > BUFFER_OUT_SIZE) - return -1; - memcpy(&buffer_out[bi], value, 16); - bi += 16; - return bi - obi; - case 'l': - len = *(int *)value; - p = 4; - for(i=0;i> 8, (char *)value + p); - if(r < 0) - return r; - bi += r; - p += r; - } - if((bi + 1) > BUFFER_OUT_SIZE) - return -1; - buffer_out[bi++] = 0; - return bi - obi; + if(base_type == 'l') { + char elt_type; + int len; + int i, p; + + elt_type = type_tag >> 8; + if((bi + 1) > BUFFER_OUT_SIZE) + return -1; + buffer_out[bi++] = elt_type; + + len = *(int *)value; + if((bi + 4) > BUFFER_OUT_SIZE) + return -1; + memcpy(&buffer_out[bi], &len, 4); + bi += 4; + + p = 4; + for(i=0;i