Skip to content

Commit 0cc6c95

Browse files
committed
Auto merge of rust-lang#118433 - matthiaskrgr:rollup-fi9lrwg, r=matthiaskrgr
Rollup of 7 pull requests Successful merges: - rust-lang#116839 (Implement thread parking for xous) - rust-lang#118265 (remove the memcpy-on-equal-ptrs assumption) - rust-lang#118269 (Unify `TraitRefs` and `PolyTraitRefs` in `ValuePairs`) - rust-lang#118394 (Remove HIR opkinds) - rust-lang#118398 (Add proper cfgs in std) - rust-lang#118419 (Eagerly return `ExprKind::Err` on `yield`/`await` in wrong coroutine context) - rust-lang#118422 (Fix coroutine validation for mixed panic strategy) r? `@ghost` `@rustbot` modify labels: rollup
2 parents a19e7d2 + 28f7a2f commit 0cc6c95

File tree

9 files changed

+108
-4
lines changed

9 files changed

+108
-4
lines changed

alloc/src/alloc.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -423,12 +423,14 @@ pub mod __alloc_error_handler {
423423
}
424424
}
425425

426+
#[cfg(not(no_global_oom_handling))]
426427
/// Specialize clones into pre-allocated, uninitialized memory.
427428
/// Used by `Box::clone` and `Rc`/`Arc::make_mut`.
428429
pub(crate) trait WriteCloneIntoRaw: Sized {
429430
unsafe fn write_clone_into_raw(&self, target: *mut Self);
430431
}
431432

433+
#[cfg(not(no_global_oom_handling))]
432434
impl<T: Clone> WriteCloneIntoRaw for T {
433435
#[inline]
434436
default unsafe fn write_clone_into_raw(&self, target: *mut Self) {
@@ -438,6 +440,7 @@ impl<T: Clone> WriteCloneIntoRaw for T {
438440
}
439441
}
440442

443+
#[cfg(not(no_global_oom_handling))]
441444
impl<T: Copy> WriteCloneIntoRaw for T {
442445
#[inline]
443446
unsafe fn write_clone_into_raw(&self, target: *mut Self) {

alloc/src/collections/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@ impl Display for TryReserveError {
148148

149149
/// An intermediate trait for specialization of `Extend`.
150150
#[doc(hidden)]
151+
#[cfg(not(no_global_oom_handling))]
151152
trait SpecExtend<I: IntoIterator> {
152153
/// Extends `self` with the contents of the given iterator.
153154
fn spec_extend(&mut self, iter: I);

alloc/src/rc.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2023,6 +2023,7 @@ impl<T, A: Allocator> Rc<[T], A> {
20232023
}
20242024
}
20252025

2026+
#[cfg(not(no_global_oom_handling))]
20262027
/// Specialization trait used for `From<&[T]>`.
20272028
trait RcFromSlice<T> {
20282029
fn from_slice(slice: &[T]) -> Self;

alloc/src/sync.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3503,6 +3503,7 @@ impl<T> FromIterator<T> for Arc<[T]> {
35033503
}
35043504
}
35053505

3506+
#[cfg(not(no_global_oom_handling))]
35063507
/// Specialization trait used for collecting into `Arc<[T]>`.
35073508
trait ToArcSlice<T>: Iterator<Item = T> + Sized {
35083509
fn to_arc_slice(self) -> Arc<[T]>;

alloc/src/vec/mod.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ use core::cmp;
5858
use core::cmp::Ordering;
5959
use core::fmt;
6060
use core::hash::{Hash, Hasher};
61+
#[cfg(not(no_global_oom_handling))]
6162
use core::iter;
6263
use core::marker::PhantomData;
6364
use core::mem::{self, ManuallyDrop, MaybeUninit, SizedTypeProperties};
@@ -101,6 +102,7 @@ mod into_iter;
101102
#[cfg(not(no_global_oom_handling))]
102103
use self::is_zero::IsZero;
103104

105+
#[cfg(not(no_global_oom_handling))]
104106
mod is_zero;
105107

106108
#[cfg(not(no_global_oom_handling))]
@@ -2599,6 +2601,7 @@ pub fn from_elem_in<T: Clone, A: Allocator>(elem: T, n: usize, alloc: A) -> Vec<
25992601
<T as SpecFromElem>::from_elem(elem, n, alloc)
26002602
}
26012603

2604+
#[cfg(not(no_global_oom_handling))]
26022605
trait ExtendFromWithinSpec {
26032606
/// # Safety
26042607
///
@@ -2607,6 +2610,7 @@ trait ExtendFromWithinSpec {
26072610
unsafe fn spec_extend_from_within(&mut self, src: Range<usize>);
26082611
}
26092612

2613+
#[cfg(not(no_global_oom_handling))]
26102614
impl<T: Clone, A: Allocator> ExtendFromWithinSpec for Vec<T, A> {
26112615
default unsafe fn spec_extend_from_within(&mut self, src: Range<usize>) {
26122616
// SAFETY:
@@ -2626,6 +2630,7 @@ impl<T: Clone, A: Allocator> ExtendFromWithinSpec for Vec<T, A> {
26262630
}
26272631
}
26282632

2633+
#[cfg(not(no_global_oom_handling))]
26292634
impl<T: Copy, A: Allocator> ExtendFromWithinSpec for Vec<T, A> {
26302635
unsafe fn spec_extend_from_within(&mut self, src: Range<usize>) {
26312636
let count = src.len();

core/src/lib.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,8 @@
2424
//! which are generated by Rust codegen backends. Additionally, this library can make explicit
2525
//! calls to `strlen`. Their signatures are the same as found in C, but there are extra
2626
//! assumptions about their semantics: For `memcpy`, `memmove`, `memset`, `memcmp`, and `bcmp`, if
27-
//! the `n` parameter is 0, the function is assumed to not be UB. Furthermore, for `memcpy`, if
28-
//! source and target pointer are equal, the function is assumed to not be UB.
29-
//! (Note that these are standard assumptions among compilers:
27+
//! the `n` parameter is 0, the function is assumed to not be UB, even if the pointers are NULL or
28+
//! dangling. (Note that making extra assumptions about these functions is common among compilers:
3029
//! [clang](https://reviews.llvm.org/D86993) and [GCC](https://gcc.gnu.org/onlinedocs/gcc/Standards.html#C-Language) do the same.)
3130
//! These functions are often provided by the system libc, but can also be provided by the
3231
//! [compiler-builtins crate](https://crates.io/crates/compiler_builtins).

std/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,7 @@
336336
#![feature(portable_simd)]
337337
#![feature(prelude_2024)]
338338
#![feature(ptr_as_uninit)]
339+
#![feature(ptr_from_ref)]
339340
#![feature(raw_os_nonzero)]
340341
#![feature(round_ties_even)]
341342
#![feature(slice_internals)]

std/src/sys/xous/mod.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ pub mod process;
2828
pub mod stdio;
2929
pub mod thread;
3030
pub mod thread_local_key;
31-
#[path = "../unsupported/thread_parking.rs"]
3231
pub mod thread_parking;
3332
pub mod time;
3433

std/src/sys/xous/thread_parking.rs

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
use crate::os::xous::ffi::{blocking_scalar, scalar};
2+
use crate::os::xous::services::{ticktimer_server, TicktimerScalar};
3+
use crate::pin::Pin;
4+
use crate::ptr;
5+
use crate::sync::atomic::{
6+
AtomicI8,
7+
Ordering::{Acquire, Release},
8+
};
9+
use crate::time::Duration;
10+
11+
const NOTIFIED: i8 = 1;
12+
const EMPTY: i8 = 0;
13+
const PARKED: i8 = -1;
14+
15+
pub struct Parker {
16+
state: AtomicI8,
17+
}
18+
19+
impl Parker {
20+
pub unsafe fn new_in_place(parker: *mut Parker) {
21+
unsafe { parker.write(Parker { state: AtomicI8::new(EMPTY) }) }
22+
}
23+
24+
fn index(&self) -> usize {
25+
ptr::from_ref(self).addr()
26+
}
27+
28+
pub unsafe fn park(self: Pin<&Self>) {
29+
// Change NOTIFIED to EMPTY and EMPTY to PARKED.
30+
let state = self.state.fetch_sub(1, Acquire);
31+
if state == NOTIFIED {
32+
return;
33+
}
34+
35+
// The state was set to PARKED. Wait until the `unpark` wakes us up.
36+
blocking_scalar(
37+
ticktimer_server(),
38+
TicktimerScalar::WaitForCondition(self.index(), 0).into(),
39+
)
40+
.expect("failed to send WaitForCondition command");
41+
42+
self.state.swap(EMPTY, Acquire);
43+
}
44+
45+
pub unsafe fn park_timeout(self: Pin<&Self>, timeout: Duration) {
46+
// Change NOTIFIED to EMPTY and EMPTY to PARKED.
47+
let state = self.state.fetch_sub(1, Acquire);
48+
if state == NOTIFIED {
49+
return;
50+
}
51+
52+
// A value of zero indicates an indefinite wait. Clamp the number of
53+
// milliseconds to the allowed range.
54+
let millis = usize::max(timeout.as_millis().try_into().unwrap_or(usize::MAX), 1);
55+
56+
let was_timeout = blocking_scalar(
57+
ticktimer_server(),
58+
TicktimerScalar::WaitForCondition(self.index(), millis).into(),
59+
)
60+
.expect("failed to send WaitForCondition command")[0]
61+
!= 0;
62+
63+
let state = self.state.swap(EMPTY, Acquire);
64+
if was_timeout && state == NOTIFIED {
65+
// The state was set to NOTIFIED after we returned from the wait
66+
// but before we reset the state. Therefore, a wakeup is on its
67+
// way, which we need to consume here.
68+
// NOTICE: this is a priority hole.
69+
blocking_scalar(
70+
ticktimer_server(),
71+
TicktimerScalar::WaitForCondition(self.index(), 0).into(),
72+
)
73+
.expect("failed to send WaitForCondition command");
74+
}
75+
}
76+
77+
pub fn unpark(self: Pin<&Self>) {
78+
let state = self.state.swap(NOTIFIED, Release);
79+
if state == PARKED {
80+
// The thread is parked, wake it up.
81+
blocking_scalar(
82+
ticktimer_server(),
83+
TicktimerScalar::NotifyCondition(self.index(), 1).into(),
84+
)
85+
.expect("failed to send NotifyCondition command");
86+
}
87+
}
88+
}
89+
90+
impl Drop for Parker {
91+
fn drop(&mut self) {
92+
scalar(ticktimer_server(), TicktimerScalar::FreeCondition(self.index()).into()).ok();
93+
}
94+
}

0 commit comments

Comments
 (0)