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

Stabilize atomic_from_ptr #115719

Merged
merged 2 commits into from
Oct 14, 2023
Merged

Stabilize atomic_from_ptr #115719

merged 2 commits into from
Oct 14, 2023

Conversation

tgross35
Copy link
Contributor

@tgross35 tgross35 commented Sep 9, 2023

This stabilizes atomic_from_ptr and moves the const gate to const_atomic_from_ptr. Const stability is blocked on const_mut_refs.

Tracking issue: #108652

Newly stable API:

// core::atomic

impl AtomicBool { pub unsafe fn from_ptr<'a>(ptr: *mut bool) -> &'a AtomicBool; }

impl<T> AtomicPtr<T> { pub unsafe fn from_ptr<'a>(ptr: *mut *mut T) -> &'a AtomicPtr<T>; }

impl AtomicU8    { pub unsafe fn from_ptr<'a>(ptr: *mut u8)    -> &'a AtomicU8;    }
impl AtomicU16   { pub unsafe fn from_ptr<'a>(ptr: *mut u16)   -> &'a AtomicU16;   }
impl AtomicU32   { pub unsafe fn from_ptr<'a>(ptr: *mut u32)   -> &'a AtomicU32;   }
impl AtomicU64   { pub unsafe fn from_ptr<'a>(ptr: *mut u64)   -> &'a AtomicU64;   }
impl AtomicUsize { pub unsafe fn from_ptr<'a>(ptr: *mut usize) -> &'a AtomicUsize; }

impl AtomicI8    { pub unsafe fn from_ptr<'a>(ptr: *mut i8)    -> &'a AtomicI8;    }
impl AtomicI16   { pub unsafe fn from_ptr<'a>(ptr: *mut i16)   -> &'a AtomicI16;   }
impl AtomicI32   { pub unsafe fn from_ptr<'a>(ptr: *mut i32)   -> &'a AtomicI32;   }
impl AtomicI64   { pub unsafe fn from_ptr<'a>(ptr: *mut i64)   -> &'a AtomicI64;   }
impl AtomicIsize { pub unsafe fn from_ptr<'a>(ptr: *mut isize) -> &'a AtomicIsize; }

@rustbot
Copy link
Collaborator

rustbot commented Sep 9, 2023

r? @Mark-Simulacrum

(rustbot has picked a reviewer for you, use r? to override)

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-libs Relevant to the library team, which will review and decide on the PR/issue. labels Sep 9, 2023
@tgross35
Copy link
Contributor Author

tgross35 commented Sep 9, 2023

This seems like a pretty uncontroversial method that mirrors AtomicX::as_ptr. Requres FCP

r? libs-api
@rustbot label +t-libs-api -t-libs

@rustbot rustbot assigned BurntSushi and unassigned Mark-Simulacrum Sep 9, 2023
@rustbot
Copy link
Collaborator

rustbot commented Sep 9, 2023

Error: Label t-libs-api can only be set by Rust team members

Please file an issue on GitHub at triagebot if there's a problem with this bot, or reach out on #t-infra on Zulip.

@WaffleLapkin WaffleLapkin added T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. and removed T-libs Relevant to the library team, which will review and decide on the PR/issue. labels Sep 10, 2023
@dtolnay dtolnay added the needs-fcp This change is insta-stable, so needs a completed FCP to proceed. label Sep 28, 2023
@dtolnay dtolnay assigned dtolnay and unassigned BurntSushi Sep 28, 2023
@dtolnay
Copy link
Member

dtolnay commented Sep 28, 2023

@rust-lang/libs-api:
@rfcbot fcp merge

@rfcbot
Copy link

rfcbot commented Sep 28, 2023

Team member @dtolnay has proposed to merge this. The next step is review by the rest of the tagged team members:

No concerns currently listed.

Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up!

See this document for info about what commands tagged team members can give me.

@rfcbot rfcbot added proposed-final-comment-period Proposed to merge/close by relevant subteam, see T-<team> label. Will enter FCP once signed off. disposition-merge This issue / PR is in PFCP or FCP with a disposition to merge it. labels Sep 28, 2023
@WaffleLapkin
Copy link
Member

Hm, looking at the docs again,

  • The value behind ptr must not be accessed through non-atomic operations for the whole lifetime 'a.

This doesn't seem correct to me (or, rather, this is sufficient, but we could, and probably should, be looser). I think in practice, we only need a guarantee that the periods of using atomic and non-atomic accesses are synchronized. I.e. that for any two atomic and non-atomic accesses, there is a happens before relationship between them. (I could be wrong though, I'm not very knowledgeable here...)

@tgross35
Copy link
Contributor Author

tgross35 commented Sep 28, 2023

Do you think it would be better to say something about needing to use atomic accesses specifically whenever you cross Sync contexts?

I don’t think it is too bad as-is because users of the Atomic will probably assume that you can safely use it everywhere, send it across threads etc. If the caller assumes that there is a time when it doesn’t need to do atomic accesses (one thread, no race conditions) and then something down the line gets refactored to share the Atomic between threads, that could be an easy quiet race condition. Less chance for error if the caller always has to assume that it always has to use atomics.

Maybe changing from must to should would be enough?

@WaffleLapkin
Copy link
Member

Well, I'm just saying that the current documentation doesn't seem to reflect the "actual" safety invariants. I agree that the stuff about atomic/non-atomic accesses being synchronized is tricky to explain and easy to mess up, but if you are using atomics, chances are, you already doing things that are hard to explain and easy to mess up 🙃

Either way, I think that leaving what is currently written as something like "the «actual» conditions are trivially satisfied if ..." may be a good idea. Like we could have both the easy to understand, but a bit too restrictive and the actually correct, but complex rules in the docs.

@rfcbot rfcbot added final-comment-period In the final comment period and will be merged soon unless new substantive objections are raised. and removed proposed-final-comment-period Proposed to merge/close by relevant subteam, see T-<team> label. Will enter FCP once signed off. labels Oct 3, 2023
@rfcbot
Copy link

rfcbot commented Oct 3, 2023

🔔 This is now entering its final comment period, as per the review above. 🔔

@rustbot
Copy link
Collaborator

rustbot commented Oct 3, 2023

Some changes occurred in GUI tests.

cc @GuillaumeGomez

@tgross35
Copy link
Contributor Author

tgross35 commented Oct 3, 2023

@WaffleLapkin I updated the docs to say the following:

+    /// * The value behind `ptr` must not be accessed through non-atomic operations whenever
+    ///   the `AtomicBool` is used in a `Sync` context (e.g. read or modified in a different
+    ///   thread).

does that sound better?

Sorry @GuillaumeGomez I have absolutely no clue how your commit wound up in this PR, it should be gone now

@bors
Copy link
Contributor

bors commented Oct 13, 2023

📌 Commit 227c844 has been approved by dtolnay

It is now in the queue for this repository.

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Oct 13, 2023
@bors
Copy link
Contributor

bors commented Oct 14, 2023

⌛ Testing commit 227c844 with merge 2a7c2df...

@bors
Copy link
Contributor

bors commented Oct 14, 2023

☀️ Test successful - checks-actions
Approved by: dtolnay
Pushing 2a7c2df to master...

@bors bors added the merged-by-bors This PR was explicitly merged by bors. label Oct 14, 2023
@bors bors merged commit 2a7c2df into rust-lang:master Oct 14, 2023
12 checks passed
@rustbot rustbot added this to the 1.75.0 milestone Oct 14, 2023
@rust-timer
Copy link
Collaborator

Finished benchmarking commit (2a7c2df): comparison URL.

Overall result: no relevant changes - no action needed

@rustbot label: -perf-regression

Instruction count

This benchmark run did not return any relevant results for this metric.

Max RSS (memory usage)

This benchmark run did not return any relevant results for this metric.

Cycles

Results

This is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.

mean range count
Regressions ❌
(primary)
- - 0
Regressions ❌
(secondary)
2.1% [2.1%, 2.1%] 1
Improvements ✅
(primary)
- - 0
Improvements ✅
(secondary)
- - 0
All ❌✅ (primary) - - 0

Binary size

This benchmark run did not return any relevant results for this metric.

Bootstrap: 628.136s -> 627.414s (-0.11%)
Artifact size: 271.27 MiB -> 271.28 MiB (0.00%)

@RalfJung
Copy link
Member

I think the docs for these functions should explicitly say that mixed-sized atomic accesses are forbidden.

I don't think this has been done? @tgross35 could you file a follow-up PR fixing the docs? This is important, we don't want people to assume that these are implicitly allowed.

/// * This requirement is trivially satisfied if `ptr` is never used non-atomically for the
/// duration of lifetime `'a`. Most use cases should be able to follow this guideline.
/// * This requirement is also trivially satisfied if all accesses (atomic or not) are done
/// from the same thread.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Specifically I was looking for the overlapping atomics part here and I am not seeing it.

/// this guideline.
/// * This requirement is also trivially satisfied if all accesses (atomic or not) are
/// done from the same thread.
/// * This method should not be used to create overlapping or mixed-size atomic
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should say "must not".

Looks like some methods got this note and some didn't; it should be present on all of these methods.

@tgross35
Copy link
Contributor Author

@RalfJung I will follow up in #116762

@tgross35 tgross35 deleted the atomic-from-ptr branch October 16, 2023 00:42
bors-ferrocene bot added a commit to ferrocene/ferrocene that referenced this pull request Oct 17, 2023
54: Pull upstream master 2023 10 17 r=pietroalbini a=Veykril

* rust-lang/rust#116196
* rust-lang/rust#116824
* rust-lang/rust#116822
* rust-lang/rust#116477
* rust-lang/rust#116826
* rust-lang/rust#116820
  * rust-lang/rust#116811
  * rust-lang/rust#116808
  * rust-lang/rust#116805
  * rust-lang/rust#116800
  * rust-lang/rust#116798
  * rust-lang/rust#116754
* rust-lang/rust#114370
* rust-lang/rust#116804
  * rust-lang/rust#116802
  * rust-lang/rust#116790
  * rust-lang/rust#116786
  * rust-lang/rust#116709
  * rust-lang/rust#116430
  * rust-lang/rust#116257
  * rust-lang/rust#114157
* rust-lang/rust#116731
* rust-lang/rust#116550
* rust-lang/rust#114330
* rust-lang/rust#116724
* rust-lang/rust#116782
  * rust-lang/rust#116776
  * rust-lang/rust#115955
  * rust-lang/rust#115196
* rust-lang/rust#116775
* rust-lang/rust#114589
* rust-lang/rust#113747
* rust-lang/rust#116772
  * rust-lang/rust#116771
  * rust-lang/rust#116760
  * rust-lang/rust#116755
  * rust-lang/rust#116732
  * rust-lang/rust#116522
  * rust-lang/rust#116341
  * rust-lang/rust#116172
* rust-lang/rust#110604
* rust-lang/rust#110729
* rust-lang/rust#116527
* rust-lang/rust#116688
* rust-lang/rust#116757
  * rust-lang/rust#116753
  * rust-lang/rust#116748
  * rust-lang/rust#116741
  * rust-lang/rust#116594
* rust-lang/rust#116691
* rust-lang/rust#116643
* rust-lang/rust#116683
* rust-lang/rust#116635
* rust-lang/rust#115515
* rust-lang/rust#116742
  * rust-lang/rust#116661
  * rust-lang/rust#116576
  * rust-lang/rust#116540
* rust-lang/rust#116352
* rust-lang/rust#116737
  * rust-lang/rust#116730
  * rust-lang/rust#116723
  * rust-lang/rust#116715
  * rust-lang/rust#116603
  * rust-lang/rust#116591
  * rust-lang/rust#115439
* rust-lang/rust#116264
* rust-lang/rust#116727
  * rust-lang/rust#116704
  * rust-lang/rust#116696
  * rust-lang/rust#116695
  * rust-lang/rust#116644
  * rust-lang/rust#116630
* rust-lang/rust#116728
  * rust-lang/rust#116689
  * rust-lang/rust#116679
  * rust-lang/rust#116618
  * rust-lang/rust#116577
  * rust-lang/rust#115653
* rust-lang/rust#116702
* rust-lang/rust#116015
* rust-lang/rust#115822
* rust-lang/rust#116407
* rust-lang/rust#115719
* rust-lang/rust#115524
* rust-lang/rust#116705
* rust-lang/rust#116645
* rust-lang/rust#116233
* rust-lang/rust#115108
* rust-lang/rust#116670
* rust-lang/rust#116676
* rust-lang/rust#116666



Co-authored-by: Benoît du Garreau <bdgdlm@outlook.com>
Co-authored-by: Colin Finck <colin@reactos.org>
Co-authored-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
Co-authored-by: Joshua Liebow-Feeser <joshlf@users.noreply.github.com>
Co-authored-by: León Orell Valerian Liehr <me@fmease.dev>
Co-authored-by: Trevor Gross <tmgross@umich.edu>
Co-authored-by: Evan Merlock <evan@merlock.dev>
Co-authored-by: joboet <jonasboettiger@icloud.com>
Co-authored-by: Ralf Jung <post@ralfj.de>
Co-authored-by: DaniPopes <57450786+DaniPopes@users.noreply.github.com>
Co-authored-by: Mark Rousskov <mark.simulacrum@gmail.com>
Co-authored-by: onur-ozkan <work@onurozkan.dev>
Co-authored-by: Nicholas Nethercote <n.nethercote@gmail.com>
Co-authored-by: The 8472 <git@infinite-source.de>
Co-authored-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
Co-authored-by: reez12g <reez12g@gmail.com>
Co-authored-by: Jakub Beránek <berykubik@gmail.com>
@apiraino apiraino removed the to-announce Announce this issue on triage meeting label Oct 19, 2023
@RalfJung
Copy link
Member

@taiki-e points out an interaction between the caveats we are adding here to stay within the bounds of the C++ model, and this comment by @dtolnay:

As I understand it, the new guarantee introduced here would make the following sound: we want a value that can be atomically loaded but the backing data might either be the read-write memory where interior mutable values ordinarily go, or could be readonly memory on certain architectures that have this new guarantee.

Under the constraints imposed by this PR, I think that code would not be sound. And indeed there is no way to write such code soundly in C++, so we should be extremely careful with allowing it in Rust.

TaKO8Ki added a commit to TaKO8Ki/rust that referenced this pull request Nov 9, 2023
…=RalfJung

Fixup `Atomic*::from_ptr` safety docs

See rust-lang#115719 (comment)
cc `@RalfJung`
TaKO8Ki added a commit to TaKO8Ki/rust that referenced this pull request Nov 9, 2023
…=RalfJung

Fixup `Atomic*::from_ptr` safety docs

See rust-lang#115719 (comment)
cc ``@RalfJung``
rust-timer added a commit to rust-lang-ci/rust that referenced this pull request Nov 9, 2023
Rollup merge of rust-lang#116762 - WaffleLapkin:fixup_fromptr_docs, r=RalfJung

Fixup `Atomic*::from_ptr` safety docs

See rust-lang#115719 (comment)
cc ``@RalfJung``
tgross35 added a commit to tgross35/rust that referenced this pull request Oct 14, 2024
The API is already stable since [1], but const stability was blocked on
`const_mut_refs`. Since that was recently stabilized, const stabilize
the following:

    // core::atomic

    impl AtomicBool { pub const unsafe fn from_ptr<'a>(ptr: *mut bool) -> &'a AtomicBool; }

    impl<T> AtomicPtr<T> { pub const unsafe fn from_ptr<'a>(ptr: *mut *mut T) -> &'a AtomicPtr<T>; }

    impl AtomicU8    { pub const unsafe fn from_ptr<'a>(ptr: *mut u8)    -> &'a AtomicU8;    }
    impl AtomicU16   { pub const unsafe fn from_ptr<'a>(ptr: *mut u16)   -> &'a AtomicU16;   }
    impl AtomicU32   { pub const unsafe fn from_ptr<'a>(ptr: *mut u32)   -> &'a AtomicU32;   }
    impl AtomicU64   { pub const unsafe fn from_ptr<'a>(ptr: *mut u64)   -> &'a AtomicU64;   }
    impl AtomicUsize { pub const unsafe fn from_ptr<'a>(ptr: *mut usize) -> &'a AtomicUsize; }

    impl AtomicI8    { pub const unsafe fn from_ptr<'a>(ptr: *mut i8)    -> &'a AtomicI8;    }
    impl AtomicI16   { pub const unsafe fn from_ptr<'a>(ptr: *mut i16)   -> &'a AtomicI16;   }
    impl AtomicI32   { pub const unsafe fn from_ptr<'a>(ptr: *mut i32)   -> &'a AtomicI32;   }
    impl AtomicI64   { pub const unsafe fn from_ptr<'a>(ptr: *mut i64)   -> &'a AtomicI64;   }
    impl AtomicIsize { pub const unsafe fn from_ptr<'a>(ptr: *mut isize) -> &'a AtomicIsize; }

Closes: <rust-lang#108652>
[1]: <rust-lang#115719>
tgross35 added a commit to tgross35/rust that referenced this pull request Oct 14, 2024
The API is already stable since [1], but const stability was blocked on
`const_mut_refs`. Since that was recently stabilized, const stabilize
the following:

    // core::atomic

    impl AtomicBool { pub const unsafe fn from_ptr<'a>(ptr: *mut bool) -> &'a AtomicBool; }

    impl<T> AtomicPtr<T> { pub const unsafe fn from_ptr<'a>(ptr: *mut *mut T) -> &'a AtomicPtr<T>; }

    impl AtomicU8    { pub const unsafe fn from_ptr<'a>(ptr: *mut u8)    -> &'a AtomicU8;    }
    impl AtomicU16   { pub const unsafe fn from_ptr<'a>(ptr: *mut u16)   -> &'a AtomicU16;   }
    impl AtomicU32   { pub const unsafe fn from_ptr<'a>(ptr: *mut u32)   -> &'a AtomicU32;   }
    impl AtomicU64   { pub const unsafe fn from_ptr<'a>(ptr: *mut u64)   -> &'a AtomicU64;   }
    impl AtomicUsize { pub const unsafe fn from_ptr<'a>(ptr: *mut usize) -> &'a AtomicUsize; }

    impl AtomicI8    { pub const unsafe fn from_ptr<'a>(ptr: *mut i8)    -> &'a AtomicI8;    }
    impl AtomicI16   { pub const unsafe fn from_ptr<'a>(ptr: *mut i16)   -> &'a AtomicI16;   }
    impl AtomicI32   { pub const unsafe fn from_ptr<'a>(ptr: *mut i32)   -> &'a AtomicI32;   }
    impl AtomicI64   { pub const unsafe fn from_ptr<'a>(ptr: *mut i64)   -> &'a AtomicI64;   }
    impl AtomicIsize { pub const unsafe fn from_ptr<'a>(ptr: *mut isize) -> &'a AtomicIsize; }

Closes: <rust-lang#108652>
[1]: <rust-lang#115719>
tgross35 added a commit to tgross35/rust that referenced this pull request Oct 29, 2024
The API is already stable since [1], but const stability was blocked on
`const_mut_refs`. Since that was recently stabilized, const stabilize
the following:

    // core::atomic

    impl AtomicBool { pub const unsafe fn from_ptr<'a>(ptr: *mut bool) -> &'a AtomicBool; }

    impl<T> AtomicPtr<T> { pub const unsafe fn from_ptr<'a>(ptr: *mut *mut T) -> &'a AtomicPtr<T>; }

    impl AtomicU8    { pub const unsafe fn from_ptr<'a>(ptr: *mut u8)    -> &'a AtomicU8;    }
    impl AtomicU16   { pub const unsafe fn from_ptr<'a>(ptr: *mut u16)   -> &'a AtomicU16;   }
    impl AtomicU32   { pub const unsafe fn from_ptr<'a>(ptr: *mut u32)   -> &'a AtomicU32;   }
    impl AtomicU64   { pub const unsafe fn from_ptr<'a>(ptr: *mut u64)   -> &'a AtomicU64;   }
    impl AtomicUsize { pub const unsafe fn from_ptr<'a>(ptr: *mut usize) -> &'a AtomicUsize; }

    impl AtomicI8    { pub const unsafe fn from_ptr<'a>(ptr: *mut i8)    -> &'a AtomicI8;    }
    impl AtomicI16   { pub const unsafe fn from_ptr<'a>(ptr: *mut i16)   -> &'a AtomicI16;   }
    impl AtomicI32   { pub const unsafe fn from_ptr<'a>(ptr: *mut i32)   -> &'a AtomicI32;   }
    impl AtomicI64   { pub const unsafe fn from_ptr<'a>(ptr: *mut i64)   -> &'a AtomicI64;   }
    impl AtomicIsize { pub const unsafe fn from_ptr<'a>(ptr: *mut isize) -> &'a AtomicIsize; }

Closes: <rust-lang#108652>
[1]: <rust-lang#115719>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
disposition-merge This issue / PR is in PFCP or FCP with a disposition to merge it. finished-final-comment-period The final comment period is finished for this PR / Issue. merged-by-bors This PR was explicitly merged by bors. needs-fcp This change is insta-stable, so needs a completed FCP to proceed. S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.