Skip to content

AtomicCell: Why do you use SeqCst? #317

Closed
@RalfJung

Description

@RalfJung

This recent great blogpost said that AtomicCell doesn't let the user choose the memory ordering, which is fair, but of course I had to immediately check which one it uses ;) . I was very surprised to see it use SeqCst. I would have expected Acq/Rel/AcqRel. This allows reasoning by ownership transfer, which is strong enough for almost everything.

I wouldn't usually care enough to actually submit an issue about this, but now I found this comment:

So AtomicCell is basically Mutex<Cell>, except faster. That's it.

This is not in the documentation as far as I can see, but I agree it makes sense as a principle. The thing is, from all I know it is perfectly legal to implement locks with release-acquire spinlocks, so by this argument, the accesses in AtomicCell should definitely be release-acquire!

The post claims that

let x = AtomicCell::new(false);
let y = AtomicCell::new(false);
let z = AtomicCell::new(0usize);

scope(|s| {
    s.spawn(|| x.store(true));
    s.spawn(|| y.store(true));

    s.spawn(|| {
        while !x.load() {}
        if y.load() { z.fetch_add(1); }
    });

    s.spawn(|| {
        while !y.load() {}
        if x.load() { z.fetch_add(1); }
    });
}).unwrap();

assert!(z.load() > 0);

will pass when using Mutex<Cell>, but (assuming this was tested) I think that is just an accident of the current implementation. Nothing in the C11 memory model requires this to pass when using locks, and you absolutely shouldn't rely on it.

Cc @jeehoonkang @stjepang

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions