Skip to content

Commit

Permalink
Rollup merge of rust-lang#123811 - joboet:queue_em_up, r=ChrisDenton
Browse files Browse the repository at this point in the history
Use queue-based `RwLock` on more platforms

This switches over Windows 7, SGX and Xous to the queue-based `RwLock` implementation added in rust-lang#110211, thereby fixing rust-lang#121949 for Windows 7 and partially resolving rust-lang#114581 on SGX. TEEOS can't currently be switched because it doesn't have a good thread parking implementation.

CC `@roblabla` `@raoulstrackx` `@xobs` Could you help me test this, please?
r? `@ChrisDenton` the Windows stuff should be familiar to you
  • Loading branch information
GuillaumeGomez committed Apr 16, 2024
2 parents 239b372 + 10b6ca1 commit 1176134
Show file tree
Hide file tree
Showing 8 changed files with 58 additions and 387 deletions.
46 changes: 46 additions & 0 deletions library/std/src/sys/pal/sgx/libunwind_integration.rs
@@ -0,0 +1,46 @@
//! The functions in this module are needed by libunwind. These symbols are named
//! in pre-link args for the target specification, so keep that in sync.

#![cfg(not(test))]

use crate::sys::sync::RwLock;

// Verify that the byte pattern libunwind uses to initialize an RwLock is
// equivalent to the value of RwLock::new(). If the value changes,
// `src/UnwindRustSgx.h` in libunwind needs to be changed too.
const _: () = unsafe {
let bits_rust: usize = crate::mem::transmute(RwLock::new());
assert!(bits_rust == 0);
};

const EINVAL: i32 = 22;

#[no_mangle]
pub unsafe extern "C" fn __rust_rwlock_rdlock(p: *mut RwLock) -> i32 {
if p.is_null() {
return EINVAL;
}

// We cannot differentiate between reads an writes in unlock and therefore
// always use a write-lock. Unwinding isn't really in the hot path anyway.
unsafe { (*p).write() };
return 0;
}

#[no_mangle]
pub unsafe extern "C" fn __rust_rwlock_wrlock(p: *mut RwLock) -> i32 {
if p.is_null() {
return EINVAL;
}
unsafe { (*p).write() };
return 0;
}

#[no_mangle]
pub unsafe extern "C" fn __rust_rwlock_unlock(p: *mut RwLock) -> i32 {
if p.is_null() {
return EINVAL;
}
unsafe { (*p).write_unlock() };
return 0;
}
1 change: 1 addition & 0 deletions library/std/src/sys/pal/sgx/mod.rs
Expand Up @@ -17,6 +17,7 @@ pub mod fd;
pub mod fs;
#[path = "../unsupported/io.rs"]
pub mod io;
mod libunwind_integration;
pub mod net;
pub mod os;
#[path = "../unsupported/pipe.rs"]
Expand Down
28 changes: 5 additions & 23 deletions library/std/src/sys/pal/sgx/waitqueue/mod.rs
Expand Up @@ -52,10 +52,6 @@ impl<T> WaitVariable<T> {
WaitVariable { queue: WaitQueue::new(), lock: var }
}

pub fn queue_empty(&self) -> bool {
self.queue.is_empty()
}

pub fn lock_var(&self) -> &T {
&self.lock
}
Expand All @@ -68,7 +64,7 @@ impl<T> WaitVariable<T> {
#[derive(Copy, Clone)]
pub enum NotifiedTcs {
Single(Tcs),
All { count: NonZero<usize> },
All { _count: NonZero<usize> },
}

/// An RAII guard that will notify a set of target threads as well as unlock
Expand Down Expand Up @@ -98,19 +94,6 @@ impl Default for WaitQueue {
}
}

impl<'a, T> WaitGuard<'a, T> {
/// Returns which TCSes will be notified when this guard drops.
pub fn notified_tcs(&self) -> NotifiedTcs {
self.notified_tcs
}

/// Drop this `WaitGuard`, after dropping another `guard`.
pub fn drop_after<U>(self, guard: U) {
drop(guard);
drop(self);
}
}

impl<'a, T> Deref for WaitGuard<'a, T> {
type Target = SpinMutexGuard<'a, WaitVariable<T>>;

Expand Down Expand Up @@ -141,10 +124,6 @@ impl WaitQueue {
WaitQueue { inner: UnsafeList::new() }
}

pub fn is_empty(&self) -> bool {
self.inner.is_empty()
}

/// Adds the calling thread to the `WaitVariable`'s wait queue, then wait
/// until a wakeup event.
///
Expand Down Expand Up @@ -253,7 +232,10 @@ impl WaitQueue {
}

if let Some(count) = NonZero::new(count) {
Ok(WaitGuard { mutex_guard: Some(guard), notified_tcs: NotifiedTcs::All { count } })
Ok(WaitGuard {
mutex_guard: Some(guard),
notified_tcs: NotifiedTcs::All { _count: count },
})
} else {
Err(guard)
}
Expand Down
16 changes: 6 additions & 10 deletions library/std/src/sys/sync/rwlock/mod.rs
Expand Up @@ -12,24 +12,20 @@ cfg_if::cfg_if! {
))] {
mod futex;
pub use futex::RwLock;
} else if #[cfg(target_family = "unix")] {
} else if #[cfg(any(
target_family = "unix",
all(target_os = "windows", target_vendor = "win7"),
all(target_vendor = "fortanix", target_env = "sgx"),
target_os = "xous",
))] {
mod queue;
pub use queue::RwLock;
} else if #[cfg(all(target_os = "windows", target_vendor = "win7"))] {
mod windows7;
pub use windows7::RwLock;
} else if #[cfg(all(target_vendor = "fortanix", target_env = "sgx"))] {
mod sgx;
pub use sgx::RwLock;
} else if #[cfg(target_os = "solid_asp3")] {
mod solid;
pub use solid::RwLock;
} else if #[cfg(target_os = "teeos")] {
mod teeos;
pub use teeos::RwLock;
} else if #[cfg(target_os = "xous")] {
mod xous;
pub use xous::RwLock;
} else {
mod no_threads;
pub use no_threads::RwLock;
Expand Down
219 changes: 0 additions & 219 deletions library/std/src/sys/sync/rwlock/sgx.rs

This file was deleted.

21 changes: 0 additions & 21 deletions library/std/src/sys/sync/rwlock/sgx/tests.rs

This file was deleted.

0 comments on commit 1176134

Please sign in to comment.