From ae0d724bf802d17b67e2032e00abb83d2ff79b66 Mon Sep 17 00:00:00 2001 From: pca006132 Date: Thu, 10 Mar 2022 16:09:19 +0800 Subject: [PATCH] runtime: use &CSlice for lists --- src/runtime/src/kernel/cache.rs | 14 +++++++------- src/runtime/src/rpc.rs | 23 +++++++++++++---------- 2 files changed, 20 insertions(+), 17 deletions(-) diff --git a/src/runtime/src/kernel/cache.rs b/src/runtime/src/kernel/cache.rs index 89df157b..b7433c79 100644 --- a/src/runtime/src/kernel/cache.rs +++ b/src/runtime/src/kernel/cache.rs @@ -1,26 +1,26 @@ -use alloc::string::String; +use alloc::{string::String, boxed::Box}; use cslice::{CSlice, AsCSlice}; use core::mem::{transmute, forget}; use super::{KERNEL_CHANNEL_0TO1, KERNEL_CHANNEL_1TO0, Message}; -pub extern fn get(key: CSlice) -> CSlice<'static, i32> { +pub extern fn get(key: CSlice) -> &CSlice<'static, i32> { let key = String::from_utf8(key.as_ref().to_vec()).unwrap(); unsafe { KERNEL_CHANNEL_1TO0.as_mut().unwrap().send(Message::CacheGetRequest(key)); let msg = KERNEL_CHANNEL_0TO1.as_mut().unwrap().recv(); if let Message::CacheGetReply(v) = msg { - let slice = transmute(v.as_c_slice()); - // we intentionally leak the memory here, - // which does not matter as core1 would restart + let leaked = Box::new(v.as_c_slice()); + let reference = transmute(leaked.as_ref()); + forget(leaked); forget(v); - slice + reference } else { panic!("Expected CacheGetReply for CacheGetRequest"); } } } -pub extern fn put(key: CSlice, list: CSlice) { +pub extern fn put(key: CSlice, list: &CSlice) { let key = String::from_utf8(key.as_ref().to_vec()).unwrap(); let value = list.as_ref().to_vec(); unsafe { diff --git a/src/runtime/src/rpc.rs b/src/runtime/src/rpc.rs index b7f5f010..3e413400 100644 --- a/src/runtime/src/rpc.rs +++ b/src/runtime/src/rpc.rs @@ -82,19 +82,22 @@ async unsafe fn recv_value(stream: &TcpStream, tag: Tag<'async_recursion>, da Tag::List(it) => { #[repr(C)] struct List { elements: *mut (), length: u32 } - consume_value!(List, |ptr| { + consume_value!(*mut List, |ptr| { let length = proto_async::read_i32(stream).await? as usize; - (*ptr).length = length as u32; let tag = it.clone().next().expect("truncated tag"); let data_size = tag.size() * length as usize + match tag { Tag::Int64 | Tag::Float64 => 4, _ => 0 }; - let mut data = alloc(data_size).await; + let data = alloc(data_size + 8).await as *mut u8; + *ptr = data as *mut List; + let ptr = data as *mut List; + let data = data.offset(8); let alignment = tag.alignment(); - data = data.offset(alignment_offset(alignment as isize, data as isize)); + let mut data = data.offset(alignment_offset(alignment as isize, data as isize)) as *mut (); + (*ptr).length = length as u32; (*ptr).elements = data; match tag { Tag::Bool => { @@ -250,11 +253,11 @@ unsafe fn send_value(writer: &mut W, tag: Tag, data: &mut *const ()) Tag::List(it) => { #[repr(C)] struct List { elements: *const (), length: u32 } - consume_value!(List, |ptr| { - let length = (*ptr).length as isize; + consume_value!(&List, |ptr| { + let length = (**ptr).length as isize; writer.write_u32((*ptr).length)?; let tag = it.clone().next().expect("truncated tag"); - let mut data = (*ptr).elements; + let mut data = (**ptr).elements; writer.write_u8(tag.as_u8())?; match tag { Tag::Bool => { @@ -446,10 +449,10 @@ mod tag { it.take(3).map(|t| t.alignment()).max().unwrap() } // CSlice basically - Tag::Bytes | Tag::String | Tag::ByteArray | Tag::List(_) => + Tag::Bytes | Tag::String | Tag::ByteArray => core::mem::align_of::>(), // array buffer is allocated, so no need for alignment first - Tag::Array(_, _) => 1, + Tag::List(_) | Tag::Array(_, _) => 1, // will not be sent from the host _ => unreachable!("unexpected tag from host") } @@ -477,7 +480,7 @@ mod tag { } size } - Tag::List(_) => 8, + Tag::List(_) => 4, Tag::Array(_, num_dims) => 4 * (1 + num_dims as usize), Tag::Range(it) => { let tag = it.clone().next().expect("truncated tag");