forked from M-Labs/artiq-zynq
runtime: use &CSlice for lists
This commit is contained in:
parent
6c834899e9
commit
ae0d724bf8
@ -1,26 +1,26 @@
|
|||||||
use alloc::string::String;
|
use alloc::{string::String, boxed::Box};
|
||||||
use cslice::{CSlice, AsCSlice};
|
use cslice::{CSlice, AsCSlice};
|
||||||
use core::mem::{transmute, forget};
|
use core::mem::{transmute, forget};
|
||||||
use super::{KERNEL_CHANNEL_0TO1, KERNEL_CHANNEL_1TO0, Message};
|
use super::{KERNEL_CHANNEL_0TO1, KERNEL_CHANNEL_1TO0, Message};
|
||||||
|
|
||||||
pub extern fn get(key: CSlice<u8>) -> CSlice<'static, i32> {
|
pub extern fn get(key: CSlice<u8>) -> &CSlice<'static, i32> {
|
||||||
let key = String::from_utf8(key.as_ref().to_vec()).unwrap();
|
let key = String::from_utf8(key.as_ref().to_vec()).unwrap();
|
||||||
unsafe {
|
unsafe {
|
||||||
KERNEL_CHANNEL_1TO0.as_mut().unwrap().send(Message::CacheGetRequest(key));
|
KERNEL_CHANNEL_1TO0.as_mut().unwrap().send(Message::CacheGetRequest(key));
|
||||||
let msg = KERNEL_CHANNEL_0TO1.as_mut().unwrap().recv();
|
let msg = KERNEL_CHANNEL_0TO1.as_mut().unwrap().recv();
|
||||||
if let Message::CacheGetReply(v) = msg {
|
if let Message::CacheGetReply(v) = msg {
|
||||||
let slice = transmute(v.as_c_slice());
|
let leaked = Box::new(v.as_c_slice());
|
||||||
// we intentionally leak the memory here,
|
let reference = transmute(leaked.as_ref());
|
||||||
// which does not matter as core1 would restart
|
forget(leaked);
|
||||||
forget(v);
|
forget(v);
|
||||||
slice
|
reference
|
||||||
} else {
|
} else {
|
||||||
panic!("Expected CacheGetReply for CacheGetRequest");
|
panic!("Expected CacheGetReply for CacheGetRequest");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub extern fn put(key: CSlice<u8>, list: CSlice<i32>) {
|
pub extern fn put(key: CSlice<u8>, list: &CSlice<i32>) {
|
||||||
let key = String::from_utf8(key.as_ref().to_vec()).unwrap();
|
let key = String::from_utf8(key.as_ref().to_vec()).unwrap();
|
||||||
let value = list.as_ref().to_vec();
|
let value = list.as_ref().to_vec();
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -82,19 +82,22 @@ async unsafe fn recv_value<F>(stream: &TcpStream, tag: Tag<'async_recursion>, da
|
|||||||
Tag::List(it) => {
|
Tag::List(it) => {
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
struct List { elements: *mut (), length: u32 }
|
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;
|
let length = proto_async::read_i32(stream).await? as usize;
|
||||||
(*ptr).length = length as u32;
|
|
||||||
let tag = it.clone().next().expect("truncated tag");
|
let tag = it.clone().next().expect("truncated tag");
|
||||||
let data_size = tag.size() * length as usize +
|
let data_size = tag.size() * length as usize +
|
||||||
match tag {
|
match tag {
|
||||||
Tag::Int64 | Tag::Float64 => 4,
|
Tag::Int64 | Tag::Float64 => 4,
|
||||||
_ => 0
|
_ => 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();
|
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;
|
(*ptr).elements = data;
|
||||||
match tag {
|
match tag {
|
||||||
Tag::Bool => {
|
Tag::Bool => {
|
||||||
@ -250,11 +253,11 @@ unsafe fn send_value<W>(writer: &mut W, tag: Tag, data: &mut *const ())
|
|||||||
Tag::List(it) => {
|
Tag::List(it) => {
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
struct List { elements: *const (), length: u32 }
|
struct List { elements: *const (), length: u32 }
|
||||||
consume_value!(List, |ptr| {
|
consume_value!(&List, |ptr| {
|
||||||
let length = (*ptr).length as isize;
|
let length = (**ptr).length as isize;
|
||||||
writer.write_u32((*ptr).length)?;
|
writer.write_u32((*ptr).length)?;
|
||||||
let tag = it.clone().next().expect("truncated tag");
|
let tag = it.clone().next().expect("truncated tag");
|
||||||
let mut data = (*ptr).elements;
|
let mut data = (**ptr).elements;
|
||||||
writer.write_u8(tag.as_u8())?;
|
writer.write_u8(tag.as_u8())?;
|
||||||
match tag {
|
match tag {
|
||||||
Tag::Bool => {
|
Tag::Bool => {
|
||||||
@ -446,10 +449,10 @@ mod tag {
|
|||||||
it.take(3).map(|t| t.alignment()).max().unwrap()
|
it.take(3).map(|t| t.alignment()).max().unwrap()
|
||||||
}
|
}
|
||||||
// CSlice basically
|
// CSlice basically
|
||||||
Tag::Bytes | Tag::String | Tag::ByteArray | Tag::List(_) =>
|
Tag::Bytes | Tag::String | Tag::ByteArray =>
|
||||||
core::mem::align_of::<CSlice<()>>(),
|
core::mem::align_of::<CSlice<()>>(),
|
||||||
// array buffer is allocated, so no need for alignment first
|
// 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
|
// will not be sent from the host
|
||||||
_ => unreachable!("unexpected tag from host")
|
_ => unreachable!("unexpected tag from host")
|
||||||
}
|
}
|
||||||
@ -477,7 +480,7 @@ mod tag {
|
|||||||
}
|
}
|
||||||
size
|
size
|
||||||
}
|
}
|
||||||
Tag::List(_) => 8,
|
Tag::List(_) => 4,
|
||||||
Tag::Array(_, num_dims) => 4 * (1 + num_dims as usize),
|
Tag::Array(_, num_dims) => 4 * (1 + num_dims as usize),
|
||||||
Tag::Range(it) => {
|
Tag::Range(it) => {
|
||||||
let tag = it.clone().next().expect("truncated tag");
|
let tag = it.clone().next().expect("truncated tag");
|
||||||
|
Loading…
Reference in New Issue
Block a user