runtime: use correct ABI when accepting ARTIQ lists.

This commit is contained in:
whitequark 2016-11-23 16:28:05 +00:00
parent 95c885b580
commit 79e70fa465
5 changed files with 30 additions and 15 deletions

View File

@ -118,6 +118,22 @@ extern fn panic_fmt(args: core::fmt::Arguments, file: &'static str, line: u32) -
loop {} loop {}
} }
#[repr(C)]
pub struct ArtiqList<T> {
len: usize,
ptr: *const T
}
impl<T> ArtiqList<T> {
pub fn from_slice(slice: &'static [T]) -> ArtiqList<T> {
ArtiqList { ptr: slice.as_ptr(), len: slice.len() }
}
pub unsafe fn as_slice(&self) -> &[T] {
slice::from_raw_parts(self.ptr, self.len)
}
}
static mut NOW: u64 = 0; static mut NOW: u64 = 0;
#[no_mangle] #[no_mangle]
@ -221,7 +237,7 @@ extern fn watchdog_clear(id: usize) {
send(&WatchdogClear { id: id }) send(&WatchdogClear { id: id })
} }
extern fn cache_get(key: *const u8) -> (usize, *const u32) { extern fn cache_get(key: *const u8) -> (usize, *const i32) {
extern { fn strlen(s: *const c_char) -> size_t; } extern { fn strlen(s: *const c_char) -> size_t; }
let key = unsafe { slice::from_raw_parts(key, strlen(key as *const c_char)) }; let key = unsafe { slice::from_raw_parts(key, strlen(key as *const c_char)) };
let key = unsafe { str::from_utf8_unchecked(key) }; let key = unsafe { str::from_utf8_unchecked(key) };
@ -230,13 +246,12 @@ extern fn cache_get(key: *const u8) -> (usize, *const u32) {
recv!(&CacheGetReply { value } => (value.len(), value.as_ptr())) recv!(&CacheGetReply { value } => (value.len(), value.as_ptr()))
} }
extern fn cache_put(key: *const u8, &(len, ptr): &(usize, *const u32)) { extern fn cache_put(key: *const u8, list: ArtiqList<i32>) {
extern { fn strlen(s: *const c_char) -> size_t; } extern { fn strlen(s: *const c_char) -> size_t; }
let key = unsafe { slice::from_raw_parts(key, strlen(key as *const c_char)) }; let key = unsafe { slice::from_raw_parts(key, strlen(key as *const c_char)) };
let key = unsafe { str::from_utf8_unchecked(key) }; let key = unsafe { str::from_utf8_unchecked(key) };
let value = unsafe { slice::from_raw_parts(ptr, len) }; send(&CachePutRequest { key: key, value: unsafe { list.as_slice() } });
send(&CachePutRequest { key: key, value: value });
recv!(&CachePutReply { succeeded } => { recv!(&CachePutReply { succeeded } => {
if !succeeded { if !succeeded {
artiq_raise!("CacheError", "cannot put into a busy cache row") artiq_raise!("CacheError", "cannot put into a busy cache row")

View File

@ -1,6 +1,7 @@
use board::csr; use board::csr;
use core::ptr::{read_volatile, write_volatile}; use core::ptr::{read_volatile, write_volatile};
use core::slice; use core::slice;
use ::ArtiqList;
const RTIO_O_STATUS_FULL: u32 = 1; const RTIO_O_STATUS_FULL: u32 = 1;
const RTIO_O_STATUS_UNDERFLOW: u32 = 2; const RTIO_O_STATUS_UNDERFLOW: u32 = 2;
@ -83,17 +84,16 @@ pub extern fn output(timestamp: i64, channel: u32, addr: u32, data: u32) {
} }
} }
pub extern fn output_list(timestamp: i64, channel: u32, addr: u32, pub extern fn output_list(timestamp: i64, channel: u32, addr: u32, list: ArtiqList<i32>) {
&(len, ptr): &(usize, *const u32)) {
unsafe { unsafe {
csr::rtio::chan_sel_write(channel); csr::rtio::chan_sel_write(channel);
csr::rtio::o_timestamp_write(timestamp as u64); csr::rtio::o_timestamp_write(timestamp as u64);
csr::rtio::o_address_write(addr); csr::rtio::o_address_write(addr);
let data = slice::from_raw_parts(ptr, len); let data = list.as_slice();
for i in 0..data.len() { for i in 0..data.len() {
write_volatile( write_volatile(
csr::rtio::O_DATA_ADDR.offset((csr::rtio::O_DATA_SIZE - 1 - i) as isize), csr::rtio::O_DATA_ADDR.offset((csr::rtio::O_DATA_SIZE - 1 - i) as isize),
data[i]); data[i] as u32);
} }
csr::rtio::o_we_write(1); csr::rtio::o_we_write(1);
let status = csr::rtio::o_status_read(); let status = csr::rtio::o_status_read();

View File

@ -4,7 +4,7 @@ use std::btree_map::BTreeMap;
#[derive(Debug)] #[derive(Debug)]
struct Entry { struct Entry {
data: Vec<u32>, data: Vec<i32>,
borrowed: bool borrowed: bool
} }
@ -18,7 +18,7 @@ impl Cache {
Cache { entries: BTreeMap::new() } Cache { entries: BTreeMap::new() }
} }
pub fn get(&mut self, key: &str) -> *const [u32] { pub fn get(&mut self, key: &str) -> *const [i32] {
match self.entries.get_mut(key) { match self.entries.get_mut(key) {
None => &[], None => &[],
Some(ref mut entry) => { Some(ref mut entry) => {
@ -28,7 +28,7 @@ impl Cache {
} }
} }
pub fn put(&mut self, key: &str, data: &[u32]) -> Result<(), ()> { pub fn put(&mut self, key: &str, data: &[i32]) -> Result<(), ()> {
match self.entries.get_mut(key) { match self.entries.get_mut(key) {
None => (), None => (),
Some(ref mut entry) => { Some(ref mut entry) => {

View File

@ -51,8 +51,8 @@ pub enum Message<'a> {
RpcRecvReply(Result<usize, Exception<'a>>), RpcRecvReply(Result<usize, Exception<'a>>),
CacheGetRequest { key: &'a str }, CacheGetRequest { key: &'a str },
CacheGetReply { value: &'static [u32] }, CacheGetReply { value: &'static [i32] },
CachePutRequest { key: &'a str, value: &'static [u32] }, CachePutRequest { key: &'a str, value: &'a [i32] },
CachePutReply { succeeded: bool }, CachePutReply { succeeded: bool },
Log(fmt::Arguments<'a>), Log(fmt::Arguments<'a>),

View File

@ -406,7 +406,7 @@ fn process_kern_message(waiter: Waiter,
&kern::CacheGetRequest { key } => { &kern::CacheGetRequest { key } => {
let value = session.congress.cache.get(key); let value = session.congress.cache.get(key);
kern_send(waiter, &kern::CacheGetReply { kern_send(waiter, &kern::CacheGetReply {
value: unsafe { mem::transmute::<*const [u32], &'static [u32]>(value) } value: unsafe { mem::transmute::<*const [i32], &'static [i32]>(value) }
}) })
} }
@ -470,7 +470,7 @@ fn process_kern_message(waiter: Waiter,
} }
fn process_kern_queued_rpc(stream: &mut TcpStream, fn process_kern_queued_rpc(stream: &mut TcpStream,
session: &mut Session) -> io::Result<()> { _session: &mut Session) -> io::Result<()> {
rpc_queue::dequeue(|slice| { rpc_queue::dequeue(|slice| {
trace!("comm<-kern (async RPC)"); trace!("comm<-kern (async RPC)");
let length = NetworkEndian::read_u32(slice) as usize; let length = NetworkEndian::read_u32(slice) as usize;