Skip to content

std: refactor the TLS implementation#126523

Merged
bors merged 6 commits into
rust-lang:masterfrom
joboet:the_great_big_tls_refactor
Jun 24, 2024
Merged

std: refactor the TLS implementation#126523
bors merged 6 commits into
rust-lang:masterfrom
joboet:the_great_big_tls_refactor

Conversation

@joboet

@joboet joboet commented Jun 15, 2024

Copy link
Copy Markdown
Member

As discovered by Mara in #110897, our TLS implementation is a total mess. In the past months, I have simplified the actual macros and their expansions, but the majority of the complexity comes from the platform-specific support code needed to create keys and register destructors. In keeping with #117276, I have therefore moved all of the thread_local_key/thread_local_dtor modules to the thread_local module in sys and merged them into a new structure, so that future porters of std can simply mix-and-match the existing code instead of having to copy the same (bad) implementation everywhere. The new structure should become obvious when looking at sys/thread_local/mod.rs.

Unfortunately, the documentation changes associated with the refactoring have made this PR rather large. That said, this contains no functional changes except for two small ones:

  • the key-based destructor fallback now, by virtue of sharing the implementation used by macOS and others, stores its list in a #[thread_local] static instead of in the key, eliminating one indirection layer and drastically simplifying its code.
  • I've switched over ZKVM (tier 3) to use the same implementation as WebAssembly, as the implementation was just a way worse version of that

Please let me know if I can make this easier to review! I know these large PRs aren't optimal, but I couldn't think of any good intermediate steps.

@rustbot label +A-thread-locals

@rustbot

rustbot commented Jun 15, 2024

Copy link
Copy Markdown
Collaborator

r? @Mark-Simulacrum

rustbot has assigned @Mark-Simulacrum.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

@rustbot rustbot added O-hermit Operating System: Hermit O-itron Operating System: ITRON O-SGX Target: SGX O-solid Operating System: SOLID O-unix Operating system: Unix-like O-wasi Operating system: Wasi, Webassembly System Interface O-wasm Target: WASM (WebAssembly), http://webassembly.org/ O-windows Operating system: Windows 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 Jun 15, 2024
@rustbot

rustbot commented Jun 15, 2024

Copy link
Copy Markdown
Collaborator

The Miri subtree was changed

cc @rust-lang/miri

@joboet joboet added the A-thread-locals Area: Thread local storage (TLS) label Jun 15, 2024
@rust-log-analyzer

This comment has been minimized.

As discovered by Mara in rust-lang#110897, our TLS implementation is a total mess. In the past months, I have simplified the actual macros and their expansions, but the majority of the complexity comes from the platform-specific support code needed to create keys and register destructors. In keeping with rust-lang#117276, I have therefore moved all of the `thread_local_key`/`thread_local_dtor` modules to the `thread_local` module in `sys` and merged them into a new structure, so that future porters of `std` can simply mix-and-match the existing code instead of having to copy the same (bad) implementation everywhere. The new structure should become obvious when looking at `sys/thread_local/mod.rs`.

Unfortunately, the documentation changes associated with the refactoring have made this PR rather large. That said, this contains no functional changes except for two small ones:
* the key-based destructor fallback now, by virtue of sharing the implementation used by macOS and others, stores its list in a `#[thread_local]` static instead of in the key, eliminating one indirection layer and drastically simplifying its code.
* I've switched over ZKVM (tier 3) to use the same implementation as WebAssembly, as the implementation was just a way worse version of that

Please let me know if I can make this easier to review! I know these large PRs aren't optimal, but I couldn't think of any good intermediate steps.

@rustbot label +A-thread-locals
@joboet joboet force-pushed the the_great_big_tls_refactor branch from ff3e202 to f3facf1 Compare June 15, 2024 15:47
@rustbot

rustbot commented Jun 15, 2024

Copy link
Copy Markdown
Collaborator

The Miri subtree was changed

cc @rust-lang/miri

@Mark-Simulacrum Mark-Simulacrum left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I didn't review the implementations in detail (I think they are just moved, not actually changed, right?) -- left some comments inline, but most are non-blocking, just curiosity/slight improvements.

In general I'm happy to r+ with some of the nits fixed/questions answered.

Comment thread library/std/src/sys/thread_local/mod.rs Outdated
pub(super) use linux::register;
pub(super) use list::run;
} else if #[cfg(all(
target_thread_local,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Since this is present in both lists, should we outline it and just #[cfg] the whole destructors module? Or are we glob-importing it or something?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Sure, that makes sense.

Comment thread library/std/src/sys/thread_local/mod.rs
Comment thread library/std/src/sys/thread_local/mod.rs Outdated
Comment thread library/std/src/sys/pal/windows/c.rs
#[cfi_encoding = "i"]
#[repr(transparent)]
#[allow(non_camel_case_types)]
pub struct c_int(#[allow(dead_code)] pub libc::c_int);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Is there a reason this doesn't use the same c_int? (libc vs core::ffi)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I don't think so.

Comment on lines +2 to +3
//! Instead, we use one TLS key to register a callback which will run
//! iterate through the destructor list.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
//! Instead, we use one TLS key to register a callback which will run
//! iterate through the destructor list.
//! Instead, we use one TLS key to register a callback which will
//! iterate through the destructor list.

static DTORS: StaticKey = StaticKey::new(Some(run));

// Setting the key value to something other than NULL will result in the
// destructor being run at thread exit.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Maybe StaticKey is doing something I don't really understand (yet), but the idea that we don't have a way to register TLS destructors and yet can register a callback on thread exit doesn't really connect for me. Maybe we want to say that we can't register more than one destructor or something? (But then, how does this work when there's non-Rust code in play)

Comment thread library/std/src/sys/thread_local/key/racy.rs
Comment thread library/std/src/sys/thread_local/key/racy.rs
@rustbot rustbot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jun 16, 2024
@joboet

joboet commented Jun 17, 2024

Copy link
Copy Markdown
Member Author

I updated the documentation, it should be a bit clearer now.
@rustbot ready

@rustbot rustbot removed the S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. label Jun 17, 2024
@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Jun 23, 2024
@Mark-Simulacrum

Copy link
Copy Markdown
Member

@bors r+

@bors

bors commented Jun 23, 2024

Copy link
Copy Markdown
Collaborator

📌 Commit a2f078d has been approved by Mark-Simulacrum

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 Jun 23, 2024
@workingjubilee

Copy link
Copy Markdown
Member

@bors rollup=never

Big refactor of TLS, don't want to have to guess when bisecting to this.

@bors

bors commented Jun 24, 2024

Copy link
Copy Markdown
Collaborator

⌛ Testing commit a2f078d with merge 45edc40...

@rust-log-analyzer

This comment has been minimized.

@bors

bors commented Jun 24, 2024

Copy link
Copy Markdown
Collaborator

💔 Test failed - checks-actions

@bors bors added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. labels Jun 24, 2024
@joboet joboet force-pushed the the_great_big_tls_refactor branch from a2f078d to 50a02ed Compare June 24, 2024 14:37
@joboet

joboet commented Jun 24, 2024

Copy link
Copy Markdown
Member Author

I forgot that Emscripten is also in the UNIX family...
@bors r=@Mark-Simulacrum

@bors

bors commented Jun 24, 2024

Copy link
Copy Markdown
Collaborator

📌 Commit 50a02ed has been approved by Mark-Simulacrum

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 Jun 24, 2024
@bors

bors commented Jun 24, 2024

Copy link
Copy Markdown
Collaborator

⌛ Testing commit 50a02ed with merge 5a3e2a4...

@bors

bors commented Jun 24, 2024

Copy link
Copy Markdown
Collaborator

☀️ Test successful - checks-actions
Approved by: Mark-Simulacrum
Pushing 5a3e2a4 to master...

@bors bors added the merged-by-bors This PR was explicitly merged by bors. label Jun 24, 2024
@bors bors merged commit 5a3e2a4 into rust-lang:master Jun 24, 2024
@rustbot rustbot added this to the 1.81.0 milestone Jun 24, 2024
@rust-timer

Copy link
Copy Markdown
Collaborator

Finished benchmarking commit (5a3e2a4): 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

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

Binary size

Results (primary -0.1%, secondary -0.1%)

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)
- - 0
Improvements ✅
(primary)
-0.1% [-0.1%, -0.1%] 4
Improvements ✅
(secondary)
-0.1% [-0.1%, -0.0%] 35
All ❌✅ (primary) -0.1% [-0.1%, -0.1%] 4

Bootstrap: 692.546s -> 692.589s (0.01%)
Artifact size: 326.77 MiB -> 326.77 MiB (-0.00%)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-thread-locals Area: Thread local storage (TLS) merged-by-bors This PR was explicitly merged by bors. O-hermit Operating System: Hermit O-itron Operating System: ITRON O-SGX Target: SGX O-solid Operating System: SOLID O-unix Operating system: Unix-like O-wasi Operating system: Wasi, Webassembly System Interface O-wasm Target: WASM (WebAssembly), http://webassembly.org/ O-windows Operating system: Windows S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-libs Relevant to the library team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

10 participants