From af263ffe1fa5fcc94e4a55a068ce525de720724e Mon Sep 17 00:00:00 2001 From: occheung Date: Tue, 24 Aug 2021 17:15:16 +0800 Subject: [PATCH] ksupport: fix rpc, cache signature (FFI) The reason of the borrow stuff is explained in https://git.m-labs.hk/M-Labs/artiq-zynq/issues/76 (artiq-zyna repo). As for `cache_get()`, compiler will perform stack allocation to pre-allocate the returned structure, and pass to cache_get alongside the `key`. However, ksupport fails to recognize the passed memory, so it will always assume the passed memory as the key. --- artiq/firmware/ksupport/lib.rs | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/artiq/firmware/ksupport/lib.rs b/artiq/firmware/ksupport/lib.rs index 13f9d0518..cf030b3a7 100644 --- a/artiq/firmware/ksupport/lib.rs +++ b/artiq/firmware/ksupport/lib.rs @@ -122,7 +122,7 @@ pub extern fn send_to_rtio_log(text: CSlice) { } #[unwind(aborts)] -extern fn rpc_send(service: u32, tag: CSlice, data: *const *const ()) { +extern fn rpc_send(service: u32, tag: &CSlice, data: *const *const ()) { while !rpc_queue::empty() {} send(&RpcSend { async: false, @@ -133,7 +133,7 @@ extern fn rpc_send(service: u32, tag: CSlice, data: *const *const ()) { } #[unwind(aborts)] -extern fn rpc_send_async(service: u32, tag: CSlice, data: *const *const ()) { +extern fn rpc_send_async(service: u32, tag: &CSlice, data: *const *const ()) { while rpc_queue::full() {} rpc_queue::enqueue(|mut slice| { let length = { @@ -203,15 +203,20 @@ fn terminate(exception: &eh_artiq::Exception, backtrace: &mut [usize]) -> ! { } #[unwind(aborts)] -extern fn cache_get(key: CSlice) -> CSlice<'static, i32> { - send(&CacheGetRequest { - key: str::from_utf8(key.as_ref()).unwrap() - }); - recv!(&CacheGetReply { value } => value.as_c_slice()) +extern fn cache_get<'a>(ret: &'a mut CSlice, key: &CSlice) -> &'a CSlice<'a, i32> { + unsafe { + send(&CacheGetRequest { + key: str::from_utf8(key.as_ref()).unwrap() + }); + recv!(&CacheGetReply { value } => { + *ret = value.as_c_slice(); + ret + }) + } } #[unwind(allowed)] -extern fn cache_put(key: CSlice, list: CSlice) { +extern fn cache_put(key: &CSlice, list: &CSlice) { send(&CachePutRequest { key: str::from_utf8(key.as_ref()).unwrap(), value: list.as_ref() @@ -456,7 +461,7 @@ unsafe fn attribute_writeback(typeinfo: *const ()) { attributes = attributes.offset(1); if (*attribute).tag.len() > 0 { - rpc_send_async(0, (*attribute).tag, [ + rpc_send_async(0, &(*attribute).tag, [ &object as *const _ as *const (), &(*attribute).name as *const _ as *const (), (object as usize + (*attribute).offset) as *const ()