From 2095d01b84ebc018f2bd438dd8da5a8d846eb9fa Mon Sep 17 00:00:00 2001 From: whitequark Date: Tue, 1 Nov 2016 08:55:49 +0000 Subject: [PATCH] runtime: dirty hacks to remove allocations in ksupport. --- artiq/runtime.rs/Cargo.toml | 2 +- artiq/runtime.rs/libksupport/lib.rs | 2 +- artiq/runtime.rs/liblwip/Cargo.toml | 2 +- artiq/runtime.rs/libstd_artiq/Cargo.toml | 3 ++ artiq/runtime.rs/libstd_artiq/io/error.rs | 45 +++++++++++++++++++++-- artiq/runtime.rs/libstd_artiq/lib.rs | 13 ++++++- artiq/runtime.rs/src/proto.rs | 3 +- 7 files changed, 62 insertions(+), 8 deletions(-) diff --git a/artiq/runtime.rs/Cargo.toml b/artiq/runtime.rs/Cargo.toml index 1355f7a4e..146ff9089 100644 --- a/artiq/runtime.rs/Cargo.toml +++ b/artiq/runtime.rs/Cargo.toml @@ -13,7 +13,7 @@ crate-type = ["staticlib"] path = "src/lib.rs" [dependencies] -std_artiq = { path = "libstd_artiq" } +std_artiq = { path = "libstd_artiq", features = ["alloc"] } lwip = { path = "liblwip", default-features = false } fringe = { version = "= 1.1.0", default-features = false, features = ["alloc"] } log = { version = "0.3", default-features = false, features = [] } diff --git a/artiq/runtime.rs/libksupport/lib.rs b/artiq/runtime.rs/libksupport/lib.rs index 53e62f4e5..73b35c4bc 100644 --- a/artiq/runtime.rs/libksupport/lib.rs +++ b/artiq/runtime.rs/libksupport/lib.rs @@ -127,7 +127,7 @@ extern fn send_async_rpc(service: u32, tag: *const u8, data: *const *const ()) { }; proto::write_u32(&mut slice, length as u32) }).unwrap_or_else(|err| { - assert!(err.kind() == std::io::ErrorKind::UnexpectedEof); + assert!(err.kind() == std::io::ErrorKind::WriteZero); send(&RpcSend { async: true, diff --git a/artiq/runtime.rs/liblwip/Cargo.toml b/artiq/runtime.rs/liblwip/Cargo.toml index 886f69415..8d00166eb 100644 --- a/artiq/runtime.rs/liblwip/Cargo.toml +++ b/artiq/runtime.rs/liblwip/Cargo.toml @@ -9,7 +9,7 @@ path = "lib.rs" [dependencies] lwip-sys = { path = "../liblwip-sys" } -std_artiq = { path = "../libstd_artiq" } +std_artiq = { path = "../libstd_artiq", features = ["alloc"] } [features] default = ["preemption"] diff --git a/artiq/runtime.rs/libstd_artiq/Cargo.toml b/artiq/runtime.rs/libstd_artiq/Cargo.toml index dfd38df4a..a6435b1f5 100644 --- a/artiq/runtime.rs/libstd_artiq/Cargo.toml +++ b/artiq/runtime.rs/libstd_artiq/Cargo.toml @@ -9,3 +9,6 @@ path = "lib.rs" [dependencies] alloc_artiq = { path = "../liballoc_artiq" } + +[features] +alloc = [] diff --git a/artiq/runtime.rs/libstd_artiq/io/error.rs b/artiq/runtime.rs/libstd_artiq/io/error.rs index f8684a4ec..37ecc4507 100644 --- a/artiq/runtime.rs/libstd_artiq/io/error.rs +++ b/artiq/runtime.rs/libstd_artiq/io/error.rs @@ -8,7 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. - use alloc::boxed::Box; +#[cfg(feature="alloc")] use alloc::boxed::Box; +#[cfg(not(feature="alloc"))] use ::FakeBox as Box; use core::convert::Into; use core::fmt; use core::marker::{Send, Sync}; @@ -62,13 +63,19 @@ pub struct Error { enum Repr { Os(i32), + #[cfg(feature="alloc")] Custom(Box), + #[cfg(not(feature="alloc"))] + Custom(Custom), } #[derive(Debug)] struct Custom { kind: ErrorKind, + #[cfg(feature="alloc")] error: Box, + #[cfg(not(feature="alloc"))] + error: &'static str } /// A list specifying general categories of I/O error. @@ -162,12 +169,21 @@ impl Error { /// // errors can also be created from other errors /// let custom_error2 = Error::new(ErrorKind::Interrupted, custom_error); /// ``` + #[cfg(feature="alloc")] pub fn new(kind: ErrorKind, error: E) -> Error where E: Into> { Self::_new(kind, error.into()) } + #[cfg(not(feature="alloc"))] + pub fn new(kind: ErrorKind, error: E) -> Error + where E: Into<&'static str> + { + Self::_new(kind, error.into()) + } + + #[cfg(feature="alloc")] fn _new(kind: ErrorKind, error: Box) -> Error { Error { repr: Repr::Custom(Box::new(Custom { @@ -177,6 +193,16 @@ impl Error { } } + #[cfg(not(feature="alloc"))] + fn _new(kind: ErrorKind, error: &'static str) -> Error { + Error { + repr: Repr::Custom(Box::new(Custom { + kind: kind, + error: error, + })) + } + } + /// Creates a new instance of an `Error` from a particular OS error code. pub fn from_raw_os_error(code: i32) -> Error { Error { repr: Repr::Os(code) } @@ -198,6 +224,7 @@ impl Error { /// /// If this `Error` was constructed via `new` then this function will /// return `Some`, otherwise it will return `None`. + #[cfg(feature="alloc")] pub fn get_ref(&self) -> Option<&(error::Error+Send+Sync+'static)> { match self.repr { Repr::Os(..) => None, @@ -210,6 +237,7 @@ impl Error { /// /// If this `Error` was constructed via `new` then this function will /// return `Some`, otherwise it will return `None`. + #[cfg(feature="alloc")] pub fn get_mut(&mut self) -> Option<&mut (error::Error+Send+Sync+'static)> { match self.repr { Repr::Os(..) => None, @@ -221,6 +249,7 @@ impl Error { /// /// If this `Error` was constructed via `new` then this function will /// return `Some`, otherwise it will return `None`. + #[cfg(feature="alloc")] pub fn into_inner(self) -> Option> { match self.repr { Repr::Os(..) => None, @@ -282,14 +311,24 @@ impl error::Error for Error { ErrorKind::UnexpectedEof => "unexpected end of file", ErrorKind::__Nonexhaustive => unreachable!() }, - Repr::Custom(ref c) => c.error.description(), + Repr::Custom(ref c) => { + #[cfg(feature="alloc")] + { c.error.description() } + #[cfg(not(feature="alloc"))] + { c.error } + }, } } fn cause(&self) -> Option<&error::Error> { match self.repr { Repr::Os(..) => None, - Repr::Custom(ref c) => c.error.cause(), + Repr::Custom(ref _c) => { + #[cfg(feature="alloc")] + { _c.error.cause() } + #[cfg(not(feature="alloc"))] + { None } + } } } } diff --git a/artiq/runtime.rs/libstd_artiq/lib.rs b/artiq/runtime.rs/libstd_artiq/lib.rs index dafffbc9f..648baa61e 100644 --- a/artiq/runtime.rs/libstd_artiq/lib.rs +++ b/artiq/runtime.rs/libstd_artiq/lib.rs @@ -1,6 +1,7 @@ #![feature(lang_items, asm, alloc, collections, libc, needs_panic_runtime, question_mark, unicode, reflect_marker, raw, int_error_internals, - try_from, try_borrow, macro_reexport, allow_internal_unstable)] + try_from, try_borrow, macro_reexport, allow_internal_unstable, + stmt_expr_attributes)] #![no_std] #![needs_panic_runtime] @@ -31,3 +32,13 @@ pub mod prelude { pub mod error; pub mod io; + +// Provide Box::new wrapper +#[cfg(not(feature="alloc"))] +struct FakeBox(core::marker::PhantomData); +#[cfg(not(feature="alloc"))] +impl FakeBox { + fn new(val: T) -> T { + val + } +} diff --git a/artiq/runtime.rs/src/proto.rs b/artiq/runtime.rs/src/proto.rs index e3b40c3c1..9d59b6ad6 100644 --- a/artiq/runtime.rs/src/proto.rs +++ b/artiq/runtime.rs/src/proto.rs @@ -67,7 +67,8 @@ pub fn write_bytes(writer: &mut Write, value: &[u8]) -> io::Result<()> { pub fn read_string(reader: &mut Read) -> io::Result { let bytes = try!(read_bytes(reader)); - String::from_utf8(bytes).map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e)) + String::from_utf8(bytes) + .map_err(|_| io::Error::new(io::ErrorKind::InvalidData, "invalid UTF-8")) } pub fn write_string(writer: &mut Write, value: &str) -> io::Result<()> {