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

Allow compiling the wasm32-wasi std library with atomics #102372

Merged
merged 3 commits into from
Oct 13, 2022

Conversation

abrown
Copy link
Contributor

@abrown abrown commented Sep 27, 2022

The issue #102157 demonstrates how currently the -Z build-std option will fail when re-compiling the standard library with RUSTFLAGS like RUSTFLAGS="-C target-feature=+atomics,+bulk-memory -C link-args=--shared-memory". This change attempts to resolve those build issues by depending on the the WebAssembly futex module and providing an implementation for env_lock. Fixes #102157.

@rust-highfive
Copy link
Collaborator

r? @thomcc

(rust-highfive has picked a reviewer for you, use r? to override)

@rustbot rustbot added the T-libs Relevant to the library team, which will review and decide on the PR/issue. label Sep 27, 2022
@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Sep 27, 2022
@abrown
Copy link
Contributor Author

abrown commented Sep 27, 2022

There are a couple of things I could use help with in this PR:

  1. I assume that env_lock here should actually return one of the lock guards available to WebAssembly but I'm not really sure yet about the details of this — can someone point me to an example of how this should be done from other targets?
  2. I don't have a great way to test this end-to-end by compiling a Rust program with this version of the stdlib: I think I can build the stdlib now without error: RUSTFLAGS="-C target-feature=+atomics,+bulk-memory" ./x.py build library/std --target wasm32-wasi (actually, is this right?). But I'm not sure how to correctly use this new sysroot to compile a Rust program; a command like the following fails — what is the right way to do this?
$ /.../rust/build/x86_64-unknown-linux-gnu/stage1/bin/rustc kernel.rs --target wasm32-wasi --crate-type=cdylib -o kernel.wasm -C link-args="--shared-memory" -C target-feature='+atomics,+atomics' --sysroot /.../rust/build/x86_64-unknown-linux-gnu/stage1

...
error: linker `rust-lld` not found
  |
  = note: No such file or directory (os error 2)

error: aborting due to previous error; 1 warning emitted

@joboet
Copy link
Member

joboet commented Sep 27, 2022

  1. I assume that env_lock here should actually return one of the lock guards available to WebAssembly but I'm not really sure yet about the details of this — can someone point me to an example of how this should be done from other targets?

UNIX uses an RwLock to ensure correct synchronization between setting and getting the environment variables, as setenv is unsynchronized. The libc used on WASI is based on MUSL and is not thread-safe, too, so it's probably best to copy the UNIX implementation.

@alexcrichton
Copy link
Member

But I'm not sure how to correctly use this new sysroot to compile a Rust program; a command like the following fails — what is the right way to do this?

You'll need to set lld = true in config.toml as well to ensure that you're locally compiling wasm-ld. Otherwise though I don't think WASI tests work with the test harness right now and I don't think that compiletest has support for WASI. Notably this has no support for WASI which is used as a node.js-based runner for wasm tests.

I've historically dabbled in getting wasm32-wasi tests up and running using wasmtime-the-CLI but I never ended up finishing the work or proposing it here since it didn't feel like it fit. Overall for testing this I think the best thing to do for now is to compile a toolchain and test it on local programs. Eventually when the whole test suite is up and running more issues can be ironed out.

(FWIW historical test runs turned up no actual failures, just a lot of infrastructural changes to get things working)

@alexcrichton
Copy link
Member

If you're interested this is my historical work to get the test suite running with wasmtime-the-CLI. requiring you to specify:

[target.wasm32-wasi]
runtool = 'wasmtime run --disable-cache --'

in config.toml. This doesn't pass the test suite since lots of // ignore-... needs updates for wasm32-wasi, but you should be able to skim the failures and see if there's anything obvious. I don't think that the src/test/ui test suite will be all that useful for testing this change though.

@thomcc
Copy link
Member

thomcc commented Sep 28, 2022

This is still a draft. Feel free to kick it back to me with at-rustbot ready once it's ready for review.

@rustbot author

@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 Sep 28, 2022
@abrown
Copy link
Contributor Author

abrown commented Sep 29, 2022

As @alexcrichton notes above, the in-tree testing story still has some way to go, so I manually tested that this change works using the following sequence of steps:

  1. First, I built the latest HEAD of wasi-libc with threads enabled:
$ git rev-parse HEAD
05b3b876e63cdc919c79f5127a7ae8dbdb7b095f
$ make THREAD_MODEL=posix
  1. Then, in this repository, I altered my config.toml to use this new sysroot:
// first, enabled building the linker by setting `lld = true` in the [rust] section; then:
$ echo '[target.wasm32-wasi]' >> config.toml
$ echo 'wasi-root = "/.../wasi-libc/sysroot"' >> config.toml
  1. Then, I built the Rust toolchain with all of the changes in this PR along with the flags to activate them:
$ RUSTFLAGS="-C target-feature=+atomics,+bulk-memory" ./x.py build library --target wasm32-wasi
$ rustup toolchain link stage1 build/x86_64-unknown-linux-gnu/stage1
  1. Using the same kernel.rs example from Fail to compile with WebAssembly atomics and shared memory #102157, I was able to successfully compile a Rust program that uses shared memory:
$ rustc +stage1 kernel.rs -o kernel.wasm --target wasm32-wasi --crate-type=cdylib  -C link-args="--shared-memory" -C target-feature='+atomics,+atomics'
$ wasm2wat --enable-threads kernel.wasm | grep '(memory'
  (import "env" "memory" (memory (;0;) 17 16384 shared))

@abrown
Copy link
Contributor Author

abrown commented Sep 29, 2022

I rebased this change on latest master and switched to using RwLock as @joboet pointed out. If someone can point me to the right way to encode a test based on the manual steps I did above, I will add that, but otherwise I think this is ready for review.

@rustbot ready

@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 Sep 29, 2022
@abrown abrown marked this pull request as ready for review September 29, 2022 19:13
@rustbot
Copy link
Collaborator

rustbot commented Sep 29, 2022

Hey! It looks like you've submitted a new PR for the library teams!

If this PR contains changes to any rust-lang/rust public library APIs then please comment with @rustbot label +T-libs-api -T-libs to tag it appropriately. If this PR contains changes to any unstable APIs please edit the PR description to add a link to the relevant API Change Proposal or create one if you haven't already. If you're unsure where your change falls no worries, just leave it as is and the reviewer will take a look and make a decision to forward on if necessary.

Examples of T-libs-api changes:

  • Stabilizing library features
  • Introducing insta-stable changes such as new implementations of existing stable traits on existing stable types
  • Introducing new or changing existing unstable library APIs (excluding permanently unstable features / features without a tracking issue)
  • Changing public documentation in ways that create new stability guarantees
  • Changing observable runtime behavior of library APIs

@abrown
Copy link
Contributor Author

abrown commented Sep 29, 2022

Ok, I guess: @rustbot label +T-libs-api -T-libs

@rustbot rustbot 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 29, 2022
@abrown
Copy link
Contributor Author

abrown commented Sep 29, 2022

Oh, never mind: @rustbot label -T-libs-api +T-libs

@rustbot rustbot added T-libs Relevant to the library team, which will review and decide on the PR/issue. and removed T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. labels Sep 29, 2022
@thomcc
Copy link
Member

thomcc commented Oct 5, 2022

Have you done a check for the places we might cfg(target_arch = "wasm") to see if any of them have similar assumptions? My main hesitation here is I seem to recall that there's a fair bit of code that makes the same assumption (possibly including code std has a dependency on).

@abrown
Copy link
Contributor Author

abrown commented Oct 5, 2022

Have you done a check for the places we might cfg(target_arch = "wasm") to see if any of them have similar assumptions? My main hesitation here is I seem to recall that there's a fair bit of code that makes the same assumption (possibly including code std has a dependency on).

I think you mean target_family = "wasm"? Once I look for that I see that library/std/src/thread/local.rs has quite a few references to that but it seems to me that they are appropriately paired with not(target_feature = "atomics"). Perhaps that was what you were concerned about? The entire repository has 26 results for target_family = "wasm" but the rest do not seem to me to pertain to your question.

I would say that compiling Rust with atomics and shared memory is still a highly risky venture and that this PR only fixes an issue that I am aware of. There will likely be others once people start experimenting with this.

@thomcc
Copy link
Member

thomcc commented Oct 6, 2022

I think you mean target_family = "wasm"

Uh, yeah, and just a grep for cfgs with wasm in them I guess (in case they were on target_arch="wasm32" or something).

I would say that compiling Rust with atomics and shared memory is still a highly risky venture and that this PR only fixes an issue that I am aware of. There will likely be others once people start experimenting with this.

This is pretty concerning (assuming you mean that there are likely issues in std; I'm aware the ecosystem is... somwhat ill-prepared for this). Is this target_feature stable? If so I think it might be better to get a handle on it before we expose users to a bunch of stdlib code that may have bugs...

@thomcc
Copy link
Member

thomcc commented Oct 6, 2022

Oh, it requires -Zbuild-std? Hm...

@abrown
Copy link
Contributor Author

abrown commented Oct 6, 2022

Yeah, this PR just fixes compilation with features that are already exposed (even if experimentally behind -Z). Is there anything else I should do to get this reviewed and merged?

@bors
Copy link
Contributor

bors commented Oct 11, 2022

📌 Commit 9530ba0 has been approved by thomcc

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 11, 2022
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this pull request Oct 11, 2022
Allow compiling the `wasm32-wasi` std library with atomics

The issue rust-lang#102157 demonstrates how currently the `-Z build-std` option will fail when re-compiling the standard library with `RUSTFLAGS` like `RUSTFLAGS="-C target-feature=+atomics,+bulk-memory -C link-args=--shared-memory"`. This change attempts to resolve those build issues by depending on the the WebAssembly `futex` module and providing an implementation for `env_lock`. Fixes rust-lang#102157.
@JohnTitor
Copy link
Member

Failed on rollup: #102908 (comment)
@bors r-

@bors bors 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-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. labels Oct 11, 2022
@abrown
Copy link
Contributor Author

abrown commented Oct 11, 2022

@thomcc, 95b0b2d should fix the bors failure.

@rustbot label -S-waiting-on-author +S-waiting-on-review

@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 Oct 11, 2022
@thomcc
Copy link
Member

thomcc commented Oct 11, 2022

@bors r+

@bors
Copy link
Contributor

bors commented Oct 11, 2022

📌 Commit 95b0b2d has been approved by thomcc

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 11, 2022
@bors
Copy link
Contributor

bors commented Oct 13, 2022

⌛ Testing commit 95b0b2d with merge 2a92176...

@bors
Copy link
Contributor

bors commented Oct 13, 2022

☀️ Test successful - checks-actions
Approved by: thomcc
Pushing 2a92176 to master...

@bors bors added the merged-by-bors This PR was explicitly merged by bors. label Oct 13, 2022
@bors bors merged commit 2a92176 into rust-lang:master Oct 13, 2022
@rustbot rustbot added this to the 1.66.0 milestone Oct 13, 2022
@rust-timer
Copy link
Collaborator

Finished benchmarking commit (2a92176): comparison URL.

Overall result: ❌ regressions - ACTION NEEDED

Next Steps: If you can justify the regressions found in this perf run, please indicate this with @rustbot label: +perf-regression-triaged along with sufficient written justification. If you cannot justify the regressions please open an issue or create a new PR that fixes the regressions, add a comment linking to the newly created issue or PR, and then add the perf-regression-triaged label to this PR.

@rustbot label: +perf-regression
cc @rust-lang/wg-compiler-performance

Instruction count

This is a highly reliable metric that was used to determine the overall result at the top of this comment.

mean1 range count2
Regressions ❌
(primary)
0.8% [0.7%, 1.0%] 6
Regressions ❌
(secondary)
- - 0
Improvements ✅
(primary)
- - 0
Improvements ✅
(secondary)
- - 0
All ❌✅ (primary) 0.8% [0.7%, 1.0%] 6

Max RSS (memory usage)

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.

mean1 range count2
Regressions ❌
(primary)
2.6% [2.6%, 2.6%] 1
Regressions ❌
(secondary)
- - 0
Improvements ✅
(primary)
- - 0
Improvements ✅
(secondary)
- - 0
All ❌✅ (primary) 2.6% [2.6%, 2.6%] 1

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.

mean1 range count2
Regressions ❌
(primary)
1.9% [1.9%, 1.9%] 1
Regressions ❌
(secondary)
3.5% [3.5%, 3.5%] 1
Improvements ✅
(primary)
- - 0
Improvements ✅
(secondary)
- - 0
All ❌✅ (primary) 1.9% [1.9%, 1.9%] 1

Footnotes

  1. the arithmetic mean of the percent change 2 3

  2. number of relevant changes 2 3

@rustbot rustbot added the perf-regression Performance regression. label Oct 13, 2022
@lqd
Copy link
Member

lqd commented Oct 13, 2022

The regressions are recent diesel noise, and unrelated to this PR and the wasi target.

@rustbot label: +perf-regression-triaged

@rustbot rustbot added the perf-regression-triaged The performance regression has been triaged. label Oct 13, 2022
@abrown abrown deleted the issue-102157 branch October 13, 2022 13:47
Aaron1011 pushed a commit to Aaron1011/rust that referenced this pull request Jan 6, 2023
Allow compiling the `wasm32-wasi` std library with atomics

The issue rust-lang#102157 demonstrates how currently the `-Z build-std` option will fail when re-compiling the standard library with `RUSTFLAGS` like `RUSTFLAGS="-C target-feature=+atomics,+bulk-memory -C link-args=--shared-memory"`. This change attempts to resolve those build issues by depending on the the WebAssembly `futex` module and providing an implementation for `env_lock`. Fixes rust-lang#102157.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
merged-by-bors This PR was explicitly merged by bors. perf-regression Performance regression. perf-regression-triaged The performance regression has been triaged. 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.

Fail to compile with WebAssembly atomics and shared memory
10 participants