https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109930

--- Comment #5 from Simon Richter <Simon.Richter at hogyros dot de> ---
> Btw if you know the old state then there is presumably no concurrent access 
> here and so you don't need atomic, let alone sequential consistency.

I know it in some, but not all cases.

Basically, what I do is

        auto old_x = x.load();

    retry:
        switch(old_x) {
        case 1:
            if(!x.compare_exchange_weak(old_x, 2))
                 goto retry;
            stop_timer();
            old_x = x.exchange(4);
            assert(old_x == 2);
            break;
        case 2:
            // we must have preempted another instance of this function
            // do nothing
            break;
        case 3:
            // handle timeout
            ...
            break;
        case 4:
            // handle operation complete
            ...
        }

This is in code for timeout handling in a realtime system, the timer interrupt
can preempt this. State 1 is "operation in progress", state 2 is "operation
finished", state 3 is "operation timed out", and state 4 is "operation finished
and timer stopped", and the timer interrupt will try to switch from 1 to 3.

The transient state 2 then solves the race between the timer expiring and
stopping the timer (which is asynchronous because the interrupt controller has
a few cycles delay).

So the switch from state 2 to state 4 has release semantics.

Reply via email to