rlsf::GlobalTlsf (std::alloc::GlobalAlloc implementation) requires target-specific code to synchronize concurrent function calls. The code for cfg(target_arch = "wasm32", target_feature = "atomic") was left out as its support (rust-lang/rust#77839) in Rust was still in infancy.
|
#[cfg(not(target_feature = "atomics"))] |
|
impl Mutex { |
|
// Single-threaded WebAssembly environment |
|
#[inline] |
|
pub fn lock(&self) {} |
|
|
|
#[inline] |
|
pub fn unlock(&self) {} |
|
} |
Now that WASM atomic intrinsics have been introduced to core (still unstable though), it's possible to implement this now, but we must decide which mutex implementation to use:
-
std::sync::Mutex
- Pro: Already stable
- Con: Runtime and code-size overhead due to poisoning mechanism
- Con: The current implementation does not provide fairness guarantees, meaning acquiring a lock might not complete in a finite time
- ...which might be not that bad, considering that the rest of an application is probably gonna use it anyway.
-
Flag + memory_atomic_{wait32,notify}
- Pro: Minimum code-size overhead
- Pro: Minimum runtime overhead in uncontended cases
- Con: Does not provide fairness guarantees, meaning acquiring a lock might not complete in a finite time
-
Ticket lock + memory_atomic_{wait32,notify}
- Pro: Provides fairness guarantees
- Con: Thundering herd problem, which increases runtime overhead in contended cases
-
Queue-based lock (e.g., MCS, CLH) + memory_atomic_{wait32,notify}
- Pro: Provides fairness guarantees
- Pro: Lowest worst-case runtime overhead
- Con: High best-case runtime overhead
- Con: More complicated to implement than other options
- Scott, Michael L., and William N. Scherer. "Scalable queue-based spin locks with timeout." ACM SIGPLAN Notices 36.7 (2001): 44-52.
-
Flag + busy loop (spinlock)
- Pro: Minimum code-size overhead
- Pro: Minimum runtime overhead in uncontended cases
- Con: Does not provide fairness guarantees, meaning acquiring a lock might not complete in a finite time
- Con: Catastrophic runtime overhead in contended cases
-
Ticket lock + busy loop
- Pro: Provides fairness guarantees (assuming the scheduler is fair)
- Con: Catastrophic runtime overhead in contended cases
rlsf::GlobalTlsf(std::alloc::GlobalAllocimplementation) requires target-specific code to synchronize concurrent function calls. The code forcfg(target_arch = "wasm32", target_feature = "atomic")was left out as its support (rust-lang/rust#77839) in Rust was still in infancy.rlsf/crates/rlsf/src/global/wasm32.rs
Lines 12 to 20 in e315d64
Now that WASM atomic intrinsics have been introduced to
core(still unstable though), it's possible to implement this now, but we must decide which mutex implementation to use:std::sync::MutexFlag +
memory_atomic_{wait32,notify}Ticket lock +
memory_atomic_{wait32,notify}Queue-based lock (e.g., MCS, CLH) +
memory_atomic_{wait32,notify}Flag + busy loop (spinlock)
Ticket lock + busy loop