-
Notifications
You must be signed in to change notification settings - Fork 13.3k
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
Conversation
r? @shepmaster (rust_highfive has picked a reviewer for you, use r? to override) |
|
9c05f5b
to
c414c5f
Compare
Ping from triage @shepmaster: This PR requires your review. |
r? @sfackler |
pub fn fence(order: Ordering) { | ||
// On wasm32 it looks like fences aren't implemented in LLVM yet in that |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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
ping r? @sfackler |
pub fn fence(order: Ordering) { | ||
// On wasm32 it looks like fences aren't implemented in LLVM yet in that |
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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 { |
There was a problem hiding this comment.
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. |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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); |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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!
c414c5f
to
11b9034
Compare
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.
11b9034
to
b4877ed
Compare
ping r? @sfackler |
@bors r+ |
📌 Commit b4877ed has been approved by |
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.
☀️ Test successful - status-appveyor, status-travis |
This commit is an initial start at implementing the standard library for
wasm32-unknown-unknown with the experimental
atomics
feature enabled. None ofthese 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:
it's not clear yet what the convention should be, but this will change in the
future!
Mutex
,Condvar
, andRwLock
were all added based onthe atomic intrinsics that wasm has.
ReentrantMutex
and thread-local-storage implementations panic currentlyas 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.