Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add teeos std impl #116565

Merged
merged 1 commit into from
Dec 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ pub fn target() -> Target {
let mut base = base::teeos::opts();
base.features = "+strict-align,+neon,+fp-armv8".into();
base.max_atomic_width = Some(128);
base.linker = Some("aarch64-linux-gnu-ld".into());

Target {
llvm_target: "aarch64-unknown-none".into(),
Expand Down
10 changes: 10 additions & 0 deletions library/panic_abort/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,16 @@ pub unsafe fn __rust_start_panic(_payload: &mut dyn PanicPayload) -> u32 {
}
core::intrinsics::unreachable();
}
} else if #[cfg(target_os = "teeos")] {
mod teeos {
extern "C" {
pub fn TEE_Panic(code: u32) -> !;
}
}

unsafe fn abort() -> ! {
teeos::TEE_Panic(1);
}
} else {
unsafe fn abort() -> ! {
core::intrinsics::abort();
Expand Down
1 change: 1 addition & 0 deletions library/std/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ fn main() {
|| target.contains("xous")
|| target.contains("hurd")
|| target.contains("uefi")
|| target.contains("teeos")
// See src/bootstrap/synthetic_targets.rs
|| env::var("RUSTC_BOOTSTRAP_SYNTHETIC_TARGET").is_ok()
{
Expand Down
3 changes: 3 additions & 0 deletions library/std/src/sys/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ cfg_if::cfg_if! {
} else if #[cfg(all(target_vendor = "fortanix", target_env = "sgx"))] {
mod sgx;
pub use self::sgx::*;
} else if #[cfg(target_os = "teeos")] {
mod teeos;
pub use self::teeos::*;
} else {
mod unsupported;
pub use self::unsupported::*;
Expand Down
57 changes: 57 additions & 0 deletions library/std/src/sys/teeos/alloc.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
use crate::alloc::{GlobalAlloc, Layout, System};
use crate::ptr;
use crate::sys::common::alloc::{realloc_fallback, MIN_ALIGN};

#[stable(feature = "alloc_system_type", since = "1.28.0")]
unsafe impl GlobalAlloc for System {
#[inline]
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
// jemalloc provides alignment less than MIN_ALIGN for small allocations.
// So only rely on MIN_ALIGN if size >= align.
// Also see <https://github.com/rust-lang/rust/issues/45955> and
// <https://github.com/rust-lang/rust/issues/62251#issuecomment-507580914>.
if layout.align() <= MIN_ALIGN && layout.align() <= layout.size() {
libc::malloc(layout.size()) as *mut u8
} else {
aligned_malloc(&layout)
}
}

#[inline]
unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 {
// See the comment above in `alloc` for why this check looks the way it does.
if layout.align() <= MIN_ALIGN && layout.align() <= layout.size() {
libc::calloc(layout.size(), 1) as *mut u8
} else {
let ptr = self.alloc(layout);
if !ptr.is_null() {
ptr::write_bytes(ptr, 0, layout.size());
}
ptr
}
}

#[inline]
unsafe fn dealloc(&self, ptr: *mut u8, _layout: Layout) {
libc::free(ptr as *mut libc::c_void)
}

#[inline]
unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 {
if layout.align() <= MIN_ALIGN && layout.align() <= new_size {
libc::realloc(ptr as *mut libc::c_void, new_size) as *mut u8
} else {
realloc_fallback(self, ptr, layout, new_size)
}
}
}

#[inline]
unsafe fn aligned_malloc(layout: &Layout) -> *mut u8 {
let mut out = ptr::null_mut();
// posix_memalign requires that the alignment be a multiple of `sizeof(void*)`.
// Since these are all powers of 2, we can just use max.
let align = layout.align().max(crate::mem::size_of::<usize>());
let ret = libc::posix_memalign(&mut out, align, layout.size());
if ret != 0 { ptr::null_mut() } else { out as *mut u8 }
}
100 changes: 100 additions & 0 deletions library/std/src/sys/teeos/locks/condvar.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
use crate::cell::UnsafeCell;
use crate::ptr;
use crate::sync::atomic::{AtomicPtr, Ordering::Relaxed};
use crate::sys::locks::mutex::{self, Mutex};
use crate::sys::time::TIMESPEC_MAX;
use crate::sys_common::lazy_box::{LazyBox, LazyInit};
use crate::time::Duration;

extern "C" {
pub fn pthread_cond_timedwait(
cond: *mut libc::pthread_cond_t,
lock: *mut libc::pthread_mutex_t,
adstime: *const libc::timespec,
) -> libc::c_int;
}

struct AllocatedCondvar(UnsafeCell<libc::pthread_cond_t>);

pub struct Condvar {
inner: LazyBox<AllocatedCondvar>,
mutex: AtomicPtr<libc::pthread_mutex_t>,
}

#[inline]
fn raw(c: &Condvar) -> *mut libc::pthread_cond_t {
c.inner.0.get()
}

unsafe impl Send for AllocatedCondvar {}
unsafe impl Sync for AllocatedCondvar {}

impl LazyInit for AllocatedCondvar {
fn init() -> Box<Self> {
let condvar = Box::new(AllocatedCondvar(UnsafeCell::new(libc::PTHREAD_COND_INITIALIZER)));

let r = unsafe { libc::pthread_cond_init(condvar.0.get(), crate::ptr::null()) };
assert_eq!(r, 0);

condvar
}
}

impl Drop for AllocatedCondvar {
#[inline]
fn drop(&mut self) {
let r = unsafe { libc::pthread_cond_destroy(self.0.get()) };
debug_assert_eq!(r, 0);
}
}

impl Condvar {
pub const fn new() -> Condvar {
Condvar { inner: LazyBox::new(), mutex: AtomicPtr::new(ptr::null_mut()) }
}

#[inline]
fn verify(&self, mutex: *mut libc::pthread_mutex_t) {
match self.mutex.compare_exchange(ptr::null_mut(), mutex, Relaxed, Relaxed) {
Ok(_) => {} // Stored the address
Err(n) if n == mutex => {} // Lost a race to store the same address
_ => panic!("attempted to use a condition variable with two mutexes"),
}
}

#[inline]
pub fn notify_one(&self) {
let r = unsafe { libc::pthread_cond_signal(raw(self)) };
debug_assert_eq!(r, 0);
}

#[inline]
pub fn notify_all(&self) {
let r = unsafe { libc::pthread_cond_broadcast(raw(self)) };
debug_assert_eq!(r, 0);
}

#[inline]
pub unsafe fn wait(&self, mutex: &Mutex) {
let mutex = mutex::raw(mutex);
self.verify(mutex);
let r = libc::pthread_cond_wait(raw(self), mutex);
debug_assert_eq!(r, 0);
}

pub unsafe fn wait_timeout(&self, mutex: &Mutex, dur: Duration) -> bool {
use crate::sys::time::Timespec;

let mutex = mutex::raw(mutex);
self.verify(mutex);

let timeout = Timespec::now(libc::CLOCK_MONOTONIC)
.checked_add_duration(&dur)
.and_then(|t| t.to_timespec())
.unwrap_or(TIMESPEC_MAX);

let r = pthread_cond_timedwait(raw(self), mutex, &timeout);
assert!(r == libc::ETIMEDOUT || r == 0);
r == 0
}
}
8 changes: 8 additions & 0 deletions library/std/src/sys/teeos/locks/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
pub mod condvar;
#[path = "../../unix/locks/pthread_mutex.rs"]
pub mod mutex;
pub mod rwlock;

pub(crate) use condvar::Condvar;
pub(crate) use mutex::Mutex;
pub(crate) use rwlock::RwLock;
44 changes: 44 additions & 0 deletions library/std/src/sys/teeos/locks/rwlock.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
use crate::sys::locks::mutex::Mutex;

/// we do not supported rwlock, so use mutex to simulate rwlock.
/// it's useful because so many code in std will use rwlock.
pub struct RwLock {
inner: Mutex,
}

impl RwLock {
#[inline]
pub const fn new() -> RwLock {
RwLock { inner: Mutex::new() }
}

#[inline]
pub fn read(&self) {
unsafe { self.inner.lock() };
}

#[inline]
pub fn try_read(&self) -> bool {
unsafe { self.inner.try_lock() }
}

#[inline]
pub fn write(&self) {
unsafe { self.inner.lock() };
}

#[inline]
pub unsafe fn try_write(&self) -> bool {
unsafe { self.inner.try_lock() }
}

#[inline]
pub unsafe fn read_unlock(&self) {
unsafe { self.inner.unlock() };
}

#[inline]
pub unsafe fn write_unlock(&self) {
unsafe { self.inner.unlock() };
}
}
Loading
Loading