Skip to content

std: Start implementing wasm32 atomics #54017

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

Merged
merged 1 commit into from
Oct 5, 2018

Conversation

alexcrichton
Copy link
Member

This commit is an initial start at implementing the standard library for
wasm32-unknown-unknown with the experimental atomics feature enabled. None of
these changes will be visible to users of the wasm32-unknown-unknown target
because they all require recompiling the standard library. The hope with this is
that we can get this support into the standard library and start iterating on it
in-tree to enable experimentation.

Currently there's a few components in this PR:

  • Atomic fences are disabled on wasm as there's no corresponding atomic op and
    it's not clear yet what the convention should be, but this will change in the
    future!
  • Implementations of Mutex, Condvar, and RwLock were all added based on
    the atomic intrinsics that wasm has.
  • The ReentrantMutex and thread-local-storage implementations panic currently
    as there's no great way to get a handle on the current thread's "id" yet.

Right now the wasm32 target with atomics is unfortunately pretty unusable,
requiring a lot of manual things here and there to actually get it operational.
This will likely continue to evolve as the story for atomics and wasm unfolds,
but we also need more LLVM support for some operations like custom global
directives for this to work best.

@rust-highfive
Copy link
Contributor

r? @shepmaster

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

@rust-highfive
Copy link
Contributor

⚠️ Warning ⚠️

  • These commits modify submodules.

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Sep 7, 2018
@TimNN
Copy link
Contributor

TimNN commented Sep 11, 2018

Ping from triage @shepmaster: This PR requires your review.

@alexcrichton
Copy link
Member Author

r? @sfackler

@rust-highfive rust-highfive assigned sfackler and unassigned shepmaster Sep 14, 2018
pub fn fence(order: Ordering) {
// On wasm32 it looks like fences aren't implemented in LLVM yet in that
Copy link

Choose a reason for hiding this comment

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

Should we add a FIXME here?

Copy link
Member

Choose a reason for hiding this comment

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

Can we have this panic or fail to compile on wasm rather than being a nop?

Copy link
Member Author

Choose a reason for hiding this comment

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

@sfackler unfortunately this is used by Arc which means that apps quickly stop working if it fails to compile or panics :(

Alternatively we could remove libstd's usage of fences on wasm, but this seemed like a smaller local change for now

@alexcrichton
Copy link
Member Author

ping r? @sfackler

pub fn fence(order: Ordering) {
// On wasm32 it looks like fences aren't implemented in LLVM yet in that
Copy link
Member

Choose a reason for hiding this comment

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

Can we have this panic or fail to compile on wasm rather than being a nop?

#[inline]
fn ptr(&self) -> *mut i32 {
assert_eq!(mem::size_of::<usize>(), mem::size_of::<i32>());
&self.cnt as *const AtomicUsize as *mut usize as *mut i32
Copy link
Member

Choose a reason for hiding this comment

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

It seems like there's one more cast than necessary here, right?

}

fn dec_writers(&mut self) {
let zero = match *self {
Copy link
Member

Choose a reason for hiding this comment

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

zero is () here.

// unlocking the lock will notify *all* waiters rather than just readers or just
// writers. This can cause lots of "thundering stampede" problems. While
// hopefully correct this implementation is very likely to want to be changed in
// the future.
Copy link
Member

Choose a reason for hiding this comment

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

This implementation additionally doesn't provide any fairness guarantees, right?

Copy link
Member Author

Choose a reason for hiding this comment

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

Correct yeah, it's not really that great of an rwlock implementation but I figure it's hopefully at least correct and we can continue to iterate in the future.

let ticket = self.cnt.load(SeqCst) as i32;
mutex.unlock();
let nanos = dur.as_nanos();
assert!(nanos <= i64::max_value() as u128);
Copy link
Member

Choose a reason for hiding this comment

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

We assert here but truncate below in sleep on duration overflow. It seems like truncation is probably more reasonable behavior?

Copy link
Member Author

Choose a reason for hiding this comment

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

Ah right yeah, spurious wakeups!

This commit is an initial start at implementing the standard library for
wasm32-unknown-unknown with the experimental `atomics` feature enabled. None of
these changes will be visible to users of the wasm32-unknown-unknown target
because they all require recompiling the standard library. The hope with this is
that we can get this support into the standard library and start iterating on it
in-tree to enable experimentation.

Currently there's a few components in this PR:

* Atomic fences are disabled on wasm as there's no corresponding atomic op and
  it's not clear yet what the convention should be, but this will change in the
  future!
* Implementations of `Mutex`, `Condvar`, and `RwLock` were all added based on
  the atomic intrinsics that wasm has.
* The `ReentrantMutex` and thread-local-storage implementations panic currently
  as there's no great way to get a handle on the current thread's "id" yet.

Right now the wasm32 target with atomics is unfortunately pretty unusable,
requiring a lot of manual things here and there to actually get it operational.
This will likely continue to evolve as the story for atomics and wasm unfolds,
but we also need more LLVM support for some operations like custom `global`
directives for this to work best.
@alexcrichton
Copy link
Member Author

ping r? @sfackler

@sfackler
Copy link
Member

sfackler commented Oct 5, 2018

@bors r+

@bors
Copy link
Collaborator

bors commented Oct 5, 2018

📌 Commit b4877ed has been approved by sfackler

@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 5, 2018
@bors
Copy link
Collaborator

bors commented Oct 5, 2018

⌛ Testing commit b4877ed with merge b8bea5a...

bors added a commit that referenced this pull request Oct 5, 2018
std: Start implementing wasm32 atomics

This commit is an initial start at implementing the standard library for
wasm32-unknown-unknown with the experimental `atomics` feature enabled. None of
these changes will be visible to users of the wasm32-unknown-unknown target
because they all require recompiling the standard library. The hope with this is
that we can get this support into the standard library and start iterating on it
in-tree to enable experimentation.

Currently there's a few components in this PR:

* Atomic fences are disabled on wasm as there's no corresponding atomic op and
  it's not clear yet what the convention should be, but this will change in the
  future!
* Implementations of `Mutex`, `Condvar`, and `RwLock` were all added based on
  the atomic intrinsics that wasm has.
* The `ReentrantMutex` and thread-local-storage implementations panic currently
  as there's no great way to get a handle on the current thread's "id" yet.

Right now the wasm32 target with atomics is unfortunately pretty unusable,
requiring a lot of manual things here and there to actually get it operational.
This will likely continue to evolve as the story for atomics and wasm unfolds,
but we also need more LLVM support for some operations like custom `global`
directives for this to work best.
@bors
Copy link
Collaborator

bors commented Oct 5, 2018

☀️ Test successful - status-appveyor, status-travis
Approved by: sfackler
Pushing b8bea5a to master...

@bors bors merged commit b4877ed into rust-lang:master Oct 5, 2018
@alexcrichton alexcrichton deleted the wasm-atomics2 branch October 8, 2018 20:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants