Skip to content

Commit 2619acd

Browse files
committed
Auto merge of rust-lang#121914 - Nadrieril:rollup-ol98ncg, r=Nadrieril
Rollup of 5 pull requests Successful merges: - rust-lang#120761 (Add initial support for DataFlowSanitizer) - rust-lang#121622 (Preserve same vtable pointer when cloning raw waker, to fix Waker::will_wake) - rust-lang#121716 (match lowering: Lower bindings in a predictable order) - rust-lang#121731 (Now that inlining, mir validation and const eval all use reveal-all, we won't be constraining hidden types here anymore) - rust-lang#121841 (`f16` and `f128` step 2: intrinsics) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 4a15639 + f080151 commit 2619acd

File tree

3 files changed

+49
-0
lines changed

3 files changed

+49
-0
lines changed

alloc/src/task.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,15 @@ impl<W: Wake + Send + Sync + 'static> From<Arc<W>> for RawWaker {
136136
#[inline(always)]
137137
fn raw_waker<W: Wake + Send + Sync + 'static>(waker: Arc<W>) -> RawWaker {
138138
// Increment the reference count of the arc to clone it.
139+
//
140+
// The #[inline(always)] is to ensure that raw_waker and clone_waker are
141+
// always generated in the same code generation unit as one another, and
142+
// therefore that the structurally identical const-promoted RawWakerVTable
143+
// within both functions is deduplicated at LLVM IR code generation time.
144+
// This allows optimizing Waker::will_wake to a single pointer comparison of
145+
// the vtable pointers, rather than comparing all four function pointers
146+
// within the vtables.
147+
#[inline(always)]
139148
unsafe fn clone_waker<W: Wake + Send + Sync + 'static>(waker: *const ()) -> RawWaker {
140149
unsafe { Arc::increment_strong_count(waker as *const W) };
141150
RawWaker::new(
@@ -304,6 +313,10 @@ impl<W: LocalWake + 'static> From<Rc<W>> for RawWaker {
304313
#[inline(always)]
305314
fn local_raw_waker<W: LocalWake + 'static>(waker: Rc<W>) -> RawWaker {
306315
// Increment the reference count of the Rc to clone it.
316+
//
317+
// Refer to the comment on raw_waker's clone_waker regarding why this is
318+
// always inline.
319+
#[inline(always)]
307320
unsafe fn clone_waker<W: LocalWake + 'static>(waker: *const ()) -> RawWaker {
308321
unsafe { Rc::increment_strong_count(waker as *const W) };
309322
RawWaker::new(

alloc/tests/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
#![feature(thin_box)]
4242
#![feature(strict_provenance)]
4343
#![feature(drain_keep_rest)]
44+
#![feature(local_waker)]
4445
#![allow(internal_features)]
4546
#![deny(fuzzy_provenance_casts)]
4647
#![deny(unsafe_op_in_unsafe_fn)]
@@ -62,6 +63,7 @@ mod rc;
6263
mod slice;
6364
mod str;
6465
mod string;
66+
mod task;
6567
mod thin_box;
6668
mod vec;
6769
mod vec_deque;

alloc/tests/task.rs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
use alloc::rc::Rc;
2+
use alloc::sync::Arc;
3+
use alloc::task::{LocalWake, Wake};
4+
use core::task::{LocalWaker, Waker};
5+
6+
#[test]
7+
fn test_waker_will_wake_clone() {
8+
struct NoopWaker;
9+
10+
impl Wake for NoopWaker {
11+
fn wake(self: Arc<Self>) {}
12+
}
13+
14+
let waker = Waker::from(Arc::new(NoopWaker));
15+
let clone = waker.clone();
16+
17+
assert!(waker.will_wake(&clone));
18+
assert!(clone.will_wake(&waker));
19+
}
20+
21+
#[test]
22+
fn test_local_waker_will_wake_clone() {
23+
struct NoopWaker;
24+
25+
impl LocalWake for NoopWaker {
26+
fn wake(self: Rc<Self>) {}
27+
}
28+
29+
let waker = LocalWaker::from(Rc::new(NoopWaker));
30+
let clone = waker.clone();
31+
32+
assert!(waker.will_wake(&clone));
33+
assert!(clone.will_wake(&waker));
34+
}

0 commit comments

Comments
 (0)