gecko-dev/third_party/rust/atom
Dzmitry Malyshau 1c5b01ed15 Bug 1575008 - WebGPU implementation basis r=baku,bzbarsky
This change vendors `wgpu` library in-tree and hooks up the initialization bits. It implements adapter and device initialization and adds a simple test.
Complementary ecosystem tracker - https://github.com/gfx-rs/wgpu/issues/374

Current status:
  - [x] General
    - [x] figure out the IPC story
    - [ ] move wgpu crates into a dedicated folder (postponed as https://bugzilla.mozilla.org/show_bug.cgi?id=1594182)
    - [x] neko rebasing disaster
  - [x] Linux
    - [x] avoid depending on spirv_cross
  - [x] macOS
    - [x] due to cross-compiling shaders
    - [x] need the dependency update
    - [x] stop using gcc
    - [x] unexpected SSL header collision - https://phabricator.services.mozilla.com/D51148
    - [x] undefined Metal symbols
    - [x] missing webrtc headers for IPDL magic - https://phabricator.services.mozilla.com/D51558
    - [x] spirv-cross linking failure in ASAN - https://phabricator.services.mozilla.com/D52688
  - [x] Windows
    - [x] due to "ipc-channel" not supporting Windows yet
    - [x] due to some exceptional stuff
    - [x] undefined symbol: `D3D12CreateDevice`
    - [x] d3d12.dll is not found, dxgi1_4 doesn't present
    - [x] d3d11.dll and dxgi.dll need to be explicitly loaded on win32 mingw
    - [x] libbacktrace fails to link on win32 mingw
    - [x] cc mislinking C++ standard library
  - [x] Android
    - [x] spirv-cross fails to build due to exceptions

Update-1:
We decided to go with IPDL mechanism instead of Rust based ipc-channel (or any alternatives), which unblocks Windows build.

Update-2:
It appears that WebGPUThreading isn't needed any more as the child thread (and its event loop) is now managed by IPDL infrastructure. This PR removes it 🎉 .

Update-3:
InstanceProvider is also removed.

Update-4:
All set, the try is green, waiting for dependent changes to go in.

Differential Revision: https://phabricator.services.mozilla.com/D49458

--HG--
rename : dom/webgpu/Adapter.cpp => dom/webgpu/ipc/WebGPUTypes.h
rename : third_party/rust/blake2b_simd/Cargo.toml => third_party/rust/ash/Cargo.toml
rename : third_party/rust/uluru/Cargo.toml => third_party/rust/atom/Cargo.toml
rename : third_party/rust/core-graphics/Cargo.toml => third_party/rust/cocoa/Cargo.toml
rename : third_party/rust/crossbeam-deque/LICENSE-MIT => third_party/rust/cocoa/LICENSE-MIT
rename : third_party/rust/core-graphics/src/lib.rs => third_party/rust/cocoa/src/lib.rs
rename : third_party/rust/uluru/Cargo.toml => third_party/rust/colorful/Cargo.toml
rename : third_party/rust/uluru/Cargo.toml => third_party/rust/copyless/Cargo.toml
rename : third_party/rust/crossbeam-utils/.cargo-checksum.json => third_party/rust/crossbeam-utils-0.6.5/.cargo-checksum.json
rename : third_party/rust/crossbeam-utils/CHANGELOG.md => third_party/rust/crossbeam-utils-0.6.5/CHANGELOG.md
rename : third_party/rust/crossbeam-utils/Cargo.toml => third_party/rust/crossbeam-utils-0.6.5/Cargo.toml
rename : third_party/rust/crossbeam-deque/LICENSE-MIT => third_party/rust/crossbeam-utils-0.6.5/LICENSE-MIT
rename : third_party/rust/crossbeam-utils/README.md => third_party/rust/crossbeam-utils-0.6.5/README.md
rename : third_party/rust/crossbeam-utils/benches/atomic_cell.rs => third_party/rust/crossbeam-utils-0.6.5/benches/atomic_cell.rs
rename : third_party/rust/crossbeam-utils/src/atomic/atomic_cell.rs => third_party/rust/crossbeam-utils-0.6.5/src/atomic/atomic_cell.rs
rename : third_party/rust/crossbeam-utils/src/atomic/mod.rs => third_party/rust/crossbeam-utils-0.6.5/src/atomic/mod.rs
rename : third_party/rust/crossbeam-utils/src/backoff.rs => third_party/rust/crossbeam-utils-0.6.5/src/backoff.rs
rename : third_party/rust/crossbeam-utils/src/cache_padded.rs => third_party/rust/crossbeam-utils-0.6.5/src/cache_padded.rs
rename : third_party/rust/crossbeam-utils/src/lib.rs => third_party/rust/crossbeam-utils-0.6.5/src/lib.rs
rename : third_party/rust/crossbeam-utils/src/thread.rs => third_party/rust/crossbeam-utils-0.6.5/src/thread.rs
rename : third_party/rust/crossbeam-utils/tests/atomic_cell.rs => third_party/rust/crossbeam-utils-0.6.5/tests/atomic_cell.rs
rename : third_party/rust/crossbeam-utils/tests/parker.rs => third_party/rust/crossbeam-utils-0.6.5/tests/parker.rs
rename : third_party/rust/crossbeam-utils/tests/sharded_lock.rs => third_party/rust/crossbeam-utils-0.6.5/tests/sharded_lock.rs
rename : third_party/rust/crossbeam-utils/tests/thread.rs => third_party/rust/crossbeam-utils-0.6.5/tests/thread.rs
rename : third_party/rust/blake2b_simd/Cargo.toml => third_party/rust/gfx-auxil/Cargo.toml
rename : third_party/rust/blake2b_simd/Cargo.toml => third_party/rust/gfx-backend-empty/Cargo.toml
rename : third_party/rust/blake2b_simd/Cargo.toml => third_party/rust/hibitset/Cargo.toml
rename : third_party/rust/crossbeam-deque/LICENSE-MIT => third_party/rust/hibitset/LICENSE-MIT
rename : third_party/rust/crossbeam-deque/LICENSE-MIT => third_party/rust/metal/LICENSE-MIT
rename : third_party/rust/uluru/Cargo.toml => third_party/rust/range-alloc/Cargo.toml
rename : third_party/rust/blake2b_simd/Cargo.toml => third_party/rust/raw-window-handle/Cargo.toml
rename : third_party/rust/blake2b_simd/Cargo.toml => third_party/rust/relevant/Cargo.toml
rename : third_party/rust/crossbeam-deque/LICENSE-MIT => third_party/rust/relevant/LICENSE-MIT
rename : third_party/rust/blake2b_simd/Cargo.toml => third_party/rust/rendy-descriptor/Cargo.toml
rename : third_party/rust/uluru/Cargo.toml => third_party/rust/shared_library/Cargo.toml
rename : third_party/rust/crossbeam-deque/LICENSE-MIT => third_party/rust/shared_library/LICENSE-MIT
rename : third_party/rust/blake2b_simd/Cargo.toml => third_party/rust/storage-map/Cargo.toml
rename : third_party/rust/core-graphics/Cargo.toml => third_party/rust/x11/Cargo.toml
extra : moz-landing-system : lando
2019-11-14 04:59:56 +00:00
..
examples Bug 1575008 - WebGPU implementation basis r=baku,bzbarsky 2019-11-14 04:59:56 +00:00
src Bug 1575008 - WebGPU implementation basis r=baku,bzbarsky 2019-11-14 04:59:56 +00:00
tests Bug 1575008 - WebGPU implementation basis r=baku,bzbarsky 2019-11-14 04:59:56 +00:00
.cargo-checksum.json Bug 1575008 - WebGPU implementation basis r=baku,bzbarsky 2019-11-14 04:59:56 +00:00
Cargo.toml Bug 1575008 - WebGPU implementation basis r=baku,bzbarsky 2019-11-14 04:59:56 +00:00
LICENSE Bug 1575008 - WebGPU implementation basis r=baku,bzbarsky 2019-11-14 04:59:56 +00:00
readme.md Bug 1575008 - WebGPU implementation basis r=baku,bzbarsky 2019-11-14 04:59:56 +00:00

readme.md

Atom

Build Status Atom

Atom is a simple abstraction around Rust's AtomicPtr. It provides a simple, wait-free way to exchange data between threads safely. Atom is built around the principle that an atomic swap can be used to safely emulate Rust's ownership.

store

Using store to set a shared atomic pointer is unsafe in rust (or any language) because the contents of the pointer can be overwritten at any point in time causing the contents of the pointer to be lost. This can cause your system to leak memory, and if you are expecting that memory to do something useful (like wake a sleeping thread), you are in trouble.

load

Similarly, load is unsafe since there is no guarantee that that pointer will live for even a cycle after you have read it. Another thread may modify the pointer, or free it. For load to be safe you need to have some outside contract to preserve the correct ownership semantics.

swap

A swap is special as it allows a reference to be exchanged without the risk of that pointer being freed, or stomped on. When a thread swaps an AtomicPtr the old pointer ownership is moved to the caller, and the AtomicPtr takes ownership of the new pointer.

Using Atom

Add atom your Cargo.toml

[dependencies]
atom="*"

A short example:

extern crate atom;

use std::sync::Arc;
use std::thread;
use atom::*;

fn main() {
    // Create an empty atom
    let shared_atom = Arc::new(Atom::empty());

    // set the value 75 
    shared_atom.swap(Box::new(75));

    // Spawn a bunch of thread that will try and take the value
    let threads: Vec<thread::JoinHandle<()>> = (0..8).map(|_| {
        let shared_atom = shared_atom.clone();
        thread::spawn(move || {
            // Take the contents of the atom, only one will win the race
            if let Some(v) = shared_atom.take() {
                println!("I got it: {:?} :D", v);
            } else {
                println!("I did not get it :(");
            }
        })
    }).collect();

    // join the threads
    for t in threads { t.join().unwrap(); }

The result will look something like this:

I did not get it :(
I got it: 75 :D
I did not get it :(
I did not get it :(
I did not get it :(
I did not get it :(
I did not get it :(
I did not get it :(

Using an Atom has some advantages over using a raw AtomicPtr. First, you don't need any unsafe code in order to convert the Box<T> to and from a Box the library handles that for you. Secondly, Atom implements drop so you won't accidentally leak a pointer when dropping your data structure.

AtomSetOnce

This is an additional bit of abstraction around an Atom. Recall that I said load was unsafe unless you have an additional restrictions. AtomSetOnce as the name indicates may only be set once, and then it may never be unset. We know that if the Atom is set the pointer will be valid for the lifetime of the Atom. This means we can implement Deref in a safe way.

Take a look at the fifo example to see how this can be used to write a lock-free linked list.